"use client";

import { useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { Plus, GripVertical } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input, Label, Select } from "@/components/ui/input";
import { formatMoney, initials } from "@/lib/utils";
import { cn } from "@/lib/utils";

type Stage = { id: string; name: string; color: string; position: number };
type Deal = {
  id: string;
  title: string;
  value: number;
  status: string;
  stageId: string;
  contact: { id: string; name: string; phone: string } | null;
};
type Pipeline = { id: string; name: string; isDefault: boolean; stages: Stage[]; deals: Deal[] };
type Any = any;

export function PipelinesClient({
  pipelines,
  contacts,
  members,
  currency,
}: {
  pipelines: Pipeline[];
  contacts: Any[];
  members: Any[];
  currency: string;
}) {
  const router = useRouter();
  const [activeId, setActiveId] = useState(pipelines[0]?.id ?? "");
  const [showNewDeal, setShowNewDeal] = useState(false);
  const [newDealStage, setNewDealStage] = useState("");
  const [dragging, setDragging] = useState<string | null>(null);

  const pipeline = pipelines.find((p) => p.id === activeId) ?? pipelines[0];
  const byStage = useMemo(() => {
    const map: Record<string, Deal[]> = {};
    for (const s of pipeline?.stages ?? []) map[s.id] = [];
    for (const d of pipeline?.deals ?? []) {
      if (map[d.stageId]) map[d.stageId].push(d);
    }
    return map;
  }, [pipeline]);

  async function createDeal(data: Any) {
    const res = await fetch("/api/deals", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(data),
    });
    const json = await res.json().catch(() => ({}));
    if (!res.ok) return toast.error(json.error ?? "Failed to create deal.");
    toast.success("Deal created.");
    setShowNewDeal(false);
    router.refresh();
  }

  async function moveDeal(dealId: string, stageId: string) {
    const res = await fetch(`/api/deals/${dealId}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ stageId }),
    });
    if (!res.ok) return toast.error("Failed to move deal.");
    router.refresh();
  }

  async function dropDeal(e: React.DragEvent, stageId: string) {
    e.preventDefault();
    if (dragging) {
      await moveDeal(dragging, stageId);
      setDragging(null);
    }
  }

  async function closeDeal(dealId: string, status: "WON" | "LOST") {
    const res = await fetch(`/api/deals/${dealId}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ status }),
    });
    if (!res.ok) return toast.error("Failed to update deal.");
    toast.success(status === "WON" ? "Deal won 🎉" : "Deal marked lost.");
    router.refresh();
  }

  async function deleteDeal(dealId: string) {
    if (!confirm("Delete this deal?")) return;
    const res = await fetch(`/api/deals/${dealId}`, { method: "DELETE" });
    if (!res.ok) return toast.error("Failed to delete deal.");
    router.refresh();
  }

  return (
    <div className="space-y-5">
      <div className="flex flex-wrap items-center gap-2">
        <h1 className="mr-2 text-2xl font-bold text-foreground">Pipelines</h1>
        {pipelines.map((p) => (
          <button
            key={p.id}
            onClick={() => setActiveId(p.id)}
            className={cn(
              "rounded-full px-3 py-1.5 text-sm font-medium",
              activeId === p.id ? "bg-indigo-600 text-white" : "bg-card text-muted-foreground border border-border hover:bg-muted"
            )}
          >
            {p.name}
          </button>
        ))}
        <div className="ml-auto">
          <Button onClick={() => setNewDealStage(pipeline?.stages[0]?.id ?? "")} disabled={!pipeline}>
            <Plus className="h-4 w-4" /> Add deal
          </Button>
        </div>
      </div>

      <div className="flex gap-4 overflow-x-auto pb-4">
        {pipeline?.stages.map((stage) => {
          const deals = byStage[stage.id] ?? [];
          const total = deals.reduce((s, d) => s + d.value, 0);
          return (
            <div
              key={stage.id}
              className="flex w-72 shrink-0 flex-col rounded-xl bg-muted/80"
              onDragOver={(e) => e.preventDefault()}
              onDrop={(e) => dropDeal(e, stage.id)}
            >
              <div className="flex items-center gap-2 px-4 py-3">
                <span className="h-2.5 w-2.5 rounded-full" style={{ backgroundColor: stage.color }} />
                <span className="text-sm font-semibold text-muted-foreground">{stage.name}</span>
                <span className="ml-auto rounded-full bg-card px-2 py-0.5 text-xs font-medium text-muted-foreground">
                  {deals.length}
                </span>
              </div>
              <div className="flex-1 space-y-2 px-3 pb-3">
                {deals.length === 0 && (
                  <p className="rounded-lg border border-dashed border-zinc-300 p-3 text-center text-xs text-muted-foreground">
                    Drop deals here
                  </p>
                )}
                {deals.map((deal) => (
                  <div
                    key={deal.id}
                    draggable
                    onDragStart={() => setDragging(deal.id)}
                    onDragEnd={() => setDragging(null)}
                    className="group cursor-grab rounded-lg border border-border bg-card p-3 shadow-sm transition-shadow hover:shadow"
                  >
                    <div className="flex items-start gap-1">
                      <GripVertical className="mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" />
                      <div className="min-w-0 flex-1">
                        <p className="truncate text-sm font-medium text-foreground">{deal.title}</p>
                        <p className="mt-0.5 flex items-center gap-1.5 text-xs text-muted-foreground">
                          {deal.contact && (
                            <span className="flex items-center gap-1">
                              <span className="flex h-4 w-4 items-center justify-center rounded-full bg-muted text-[9px] font-semibold text-muted-foreground">
                                {initials(deal.contact.name)}
                              </span>
                              {deal.contact.name}
                            </span>
                          )}
                        </p>
                        <p className="mt-1.5 text-sm font-semibold text-foreground">
                          {formatMoney(deal.value, currency)}
                        </p>
                        <div className="mt-2 flex gap-1.5 opacity-0 transition-opacity group-hover:opacity-100">
                          {deal.status === "OPEN" && (
                            <>
                              <button
                                onClick={() => closeDeal(deal.id, "WON")}
                                className="rounded bg-emerald-50 px-2 py-0.5 text-xs font-medium text-emerald-700 hover:bg-emerald-100"
                              >
                                Won
                              </button>
                              <button
                                onClick={() => closeDeal(deal.id, "LOST")}
                                className="rounded bg-red-50 px-2 py-0.5 text-xs font-medium text-red-700 hover:bg-red-100"
                              >
                                Lost
                              </button>
                            </>
                          )}
                          {deal.status !== "OPEN" && (
                            <span
                              className={cn(
                                "rounded px-2 py-0.5 text-xs font-medium",
                                deal.status === "WON" ? "bg-emerald-50 text-emerald-700" : "bg-red-50 text-red-700"
                              )}
                            >
                              {deal.status}
                            </span>
                          )}
                          <button
                            onClick={() => deleteDeal(deal.id)}
                            className="ml-auto rounded px-2 py-0.5 text-xs text-muted-foreground hover:text-red-600"
                          >
                            Delete
                          </button>
                        </div>
                      </div>
                    </div>
                  </div>
                ))}
              </div>
              <div className="border-t border-border px-4 py-2 text-xs font-medium text-muted-foreground">
                {formatMoney(total, currency)}
              </div>
            </div>
          );
        })}
      </div>

      {showNewDeal && pipeline && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-zinc-900/40 p-4">
          <div className="w-full max-w-md rounded-2xl bg-card p-6 shadow-xl">
            <h2 className="text-lg font-semibold text-foreground">Add deal</h2>
            <form
              className="mt-4 space-y-4"
              onSubmit={(e) => {
                e.preventDefault();
                const data = Object.fromEntries(new FormData(e.currentTarget).entries());
                createDeal({
                  pipelineId: pipeline.id,
                  title: data.title,
                  value: Number(data.value ?? 0),
                  contactId: data.contactId,
                  expectedClose: data.expectedClose || undefined,
                });
              }}
            >
              <div>
                <Label>Title</Label>
                <Input name="title" required placeholder="e.g. Annual contract" />
              </div>
              <div>
                <Label>Contact</Label>
                <Select name="contactId" required>
                  <option value="">Select contact…</option>
                  {contacts.map((c) => (
                    <option key={c.id} value={c.id}>
                      {c.name} ({c.phone})
                    </option>
                  ))}
                </Select>
              </div>
              <div className="grid grid-cols-2 gap-3">
                <div>
                  <Label>Value</Label>
                  <Input name="value" type="number" step="0.01" min="0" defaultValue="0" />
                </div>
                <div>
                  <Label>Expected close</Label>
                  <Input name="expectedClose" type="date" />
                </div>
              </div>
              <div className="flex justify-end gap-2">
                <Button type="button" variant="ghost" onClick={() => setShowNewDeal(false)}>
                  Cancel
                </Button>
                <Button type="submit">Create deal</Button>
              </div>
            </form>
          </div>
        </div>
      )}
    </div>
  );
}
