"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { Plus, Trash2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input, Textarea, Label, Select } from "@/components/ui/input";
import { Card, CardBody, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { cn } from "@/lib/utils";

type Any = any;

export function BroadcastsClient({
  broadcasts,
  templates,
  tags = [],
}: {
  broadcasts: Any[];
  templates: Any[];
  tags?: Any[];
}) {
  const router = useRouter();
  const [showNew, setShowNew] = useState(false);
  const [creating, setCreating] = useState(false);
  const [selectedTemplateId, setSelectedTemplateId] = useState("");
  const [selectedTags, setSelectedTags] = useState<string[]>([]);
  const selectedTemplate = templates.find((t) => t.id === selectedTemplateId);
  const requiresMedia = selectedTemplate && ["IMAGE", "VIDEO", "DOCUMENT"].includes(selectedTemplate.headerType);

  async function create(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setCreating(true);
    const data = Object.fromEntries(new FormData(e.currentTarget).entries());
    const payload: any = { name: data.name };
    if (data.useTemplate === "1" && data.templateId) {
      payload.templateId = data.templateId;
      if (data.mediaUrl) payload.mediaUrl = data.mediaUrl;
    } else {
      payload.messageText = data.messageText;
    }
    if (selectedTags.length > 0) {
      payload.audience = { tagIds: selectedTags };
    }
    const res = await fetch("/api/broadcasts", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });
    const json = await res.json().catch(() => ({}));
    setCreating(false);
    if (!res.ok) return toast.error(json.error ?? "Failed to create.");
    toast.success("Broadcast created. Configure the audience then launch it.");
    setShowNew(false);
    router.push(`/broadcasts/${json.broadcast.id}`);
    router.refresh();
  }

  return (
    <div className="space-y-5">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold text-foreground">Broadcasts</h1>
          <p className="text-sm text-muted-foreground">Send template messages to your contacts at scale.</p>
        </div>
        <Button onClick={() => setShowNew(true)} disabled={templates.length === 0}>
          <Plus className="h-4 w-4" /> New broadcast
        </Button>
      </div>

      {templates.length === 0 && (
        <div className="rounded-xl border border-amber-200 bg-amber-50 p-4 text-sm text-amber-800">
          You need at least one <strong>approved</strong> message template to send broadcasts. Create one in{" "}
          <button className="font-medium underline" onClick={() => router.push("/settings/templates")}>
            Settings → Message templates
          </button>
          .
        </div>
      )}

      <div className="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-3">
        {broadcasts.map((b) => {
          const on = b.status === "DONE" || b.status === "SENDING";
          return (
            <Card key={b.id} className="flex flex-col">
              <CardHeader className="flex flex-row items-center justify-between">
                <CardTitle className="truncate">{b.name}</CardTitle>
                <Badge
                  tone={
                    b.status === "DONE" ? "green" : b.status === "FAILED" ? "red" : b.status === "SENDING" ? "blue" : b.status === "SCHEDULED" ? "amber" : "gray"
                  }
                >
                  {b.status}
                </Badge>
              </CardHeader>
              <CardBody className="flex flex-1 flex-col gap-3">
                <p className="text-xs text-muted-foreground">
                  {b.template ? `Template: ${b.template.name}` : b.messageText?.slice(0, 80) ?? "—"}
                </p>
                <div className="flex flex-wrap gap-3 text-xs text-muted-foreground">
                  <span>{b._count.recipients} recipients</span>
                  <span className="text-emerald-600">{b.sentCount} sent</span>
                  <span className="text-blue-600">{b.deliveredCount} delivered</span>
                  <span className="text-violet-600">{b.readCount} read</span>
                  <span className="text-red-600">{b.failedCount} failed</span>
                </div>
                <div className="mt-auto flex items-center gap-2">
                  <Button
                    variant="outline"
                    size="sm"
                    className="flex-1"
                    onClick={() => router.push(`/broadcasts/${b.id}`)}
                  >
                    View
                  </Button>
                  {!on && (
                    <LaunchButton id={b.id} onDone={() => router.refresh()} />
                  )}
                  {!on && (
                    <Button
                      variant="ghost"
                      size="icon"
                      className="text-muted-foreground hover:text-red-600"
                      onClick={async () => {
                        if (!confirm("Delete this broadcast?")) return;
                        const res = await fetch(`/api/broadcasts/${b.id}`, { method: "DELETE" });
                        if (!res.ok) return toast.error("Delete failed.");
                        router.refresh();
                      }}
                    >
                      <Trash2 className="h-4 w-4" />
                    </Button>
                  )}
                </div>
              </CardBody>
            </Card>
          );
        })}
        {broadcasts.length === 0 && (
          <p className="text-sm text-muted-foreground">No broadcasts yet.</p>
        )}
      </div>

      {showNew && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-zinc-900/40 p-4">
          <div className="w-full max-w-lg rounded-2xl bg-card p-6 shadow-xl">
            <h2 className="text-lg font-semibold text-foreground">New broadcast</h2>
            <form onSubmit={create} className="mt-4 space-y-4">
              <div>
                <Label>Campaign name</Label>
                <Input name="name" required placeholder="e.g. Spring launch" />
              </div>
              <div>
                <Label>Target audience (Tags)</Label>
                <div className="mt-1 flex flex-wrap gap-2">
                  {tags.map((t) => (
                    <button
                      key={t.id}
                      type="button"
                      onClick={() => {
                        if (selectedTags.includes(t.id)) {
                          setSelectedTags(selectedTags.filter((id) => id !== t.id));
                        } else {
                          setSelectedTags([...selectedTags, t.id]);
                        }
                      }}
                      className={cn(
                        "rounded-full border px-3 py-1 text-xs font-medium transition-colors",
                        selectedTags.includes(t.id) 
                          ? "border-indigo-200 bg-indigo-100 text-indigo-700 dark:border-indigo-800 dark:bg-indigo-900/50 dark:text-indigo-300" 
                          : "border-border bg-card text-muted-foreground hover:bg-muted hover:text-foreground"
                      )}
                    >
                      {t.name}
                    </button>
                  ))}
                  {tags.length === 0 && <span className="text-xs text-muted-foreground">No tags available.</span>}
                </div>
                <p className="mt-1.5 text-xs text-muted-foreground">Select tags to limit recipients. Leave empty to send to all contacts.</p>
              </div>
              <div>
                <Label>Message type</Label>
                <Select name="useTemplate" defaultValue="1">
                  <option value="1">Approved template</option>
                  <option value="0">Plain text</option>
                </Select>
              </div>
              <div>
                <Label>Template</Label>
                <Select
                  name="templateId"
                  value={selectedTemplateId}
                  onChange={(e) => setSelectedTemplateId(e.target.value)}
                >
                  <option value="">Select a template...</option>
                  {templates.map((t) => (
                    <option key={t.id} value={t.id}>
                      {t.name}
                    </option>
                  ))}
                </Select>
              </div>
              {requiresMedia && (
                <div>
                  <Label>Media URL ({selectedTemplate?.headerType})</Label>
                  <Input name="mediaUrl" type="url" placeholder="https://example.com/image.jpg" required />
                  <p className="mt-1 text-xs text-muted-foreground">Provide a direct link to the media file required by this template.</p>
                </div>
              )}
              <div>
                <Label>Message text (when not using a template)</Label>
                <Textarea name="messageText" rows={3} placeholder="Only the first message in a 24h window is free…" />
              </div>
              <div className="flex justify-end gap-2">
                <Button type="button" variant="ghost" onClick={() => setShowNew(false)}>
                  Cancel
                </Button>
                <Button type="submit" loading={creating}>
                  Create
                </Button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  );
}

function LaunchButton({ id, onDone }: { id: string; onDone: () => void }) {
  const [loading, setLoading] = useState(false);
  async function launch() {
    if (!confirm("Launch this broadcast now?")) return;
    setLoading(true);
    const res = await fetch(`/api/broadcasts/${id}`, { method: "POST" });
    const json = await res.json().catch(() => ({}));
    setLoading(false);
    if (!res.ok) return toast.error(json.error ?? "Launch failed.");
    toast.success(`Launched: ${json.sent} sent, ${json.failed} failed.`);
    onDone();
  }
  return (
    <Button variant="outline" size="sm" loading={loading} onClick={launch}>
      Launch
    </Button>
  );
}
