import { useState } from "react";
import { useParams } from "react-router";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { client } from "@/client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Trash2, Plus, Webhook, Pencil, History, X } from "lucide-react";

const EVENT_OPTIONS = [
  "push", "pull_request", "issues", "issue_comment", "pull_request_comment",
  "create", "delete", "release", "fork", "star", "watch",
];

function formatDate(date: string) {
  return new Date(date).toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
}

export default function WebhooksTab() {
  const { projectName = "", repoName = "" } = useParams();
  const qc = useQueryClient();
  const [showForm, setShowForm] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [url, setUrl] = useState("");
  const [secret, setSecret] = useState("");
  const [events, setEvents] = useState<string[]>(["push"]);
  const [active, setActive] = useState(true);
  const [error, setError] = useState("");
  const [showDeliveries, setShowDeliveries] = useState<string | null>(null);

  const { data: webhooks = [], isLoading } = useQuery({
    queryKey: ["repo", projectName, repoName, "webhooks"],
    queryFn: async () => {
      const res = await client.gitListWebhooks(projectName, repoName);
      return res.data;
    },
    enabled: Boolean(projectName) && Boolean(repoName), retry: false,
  });

  const { data: deliveries = [] } = useQuery({
    queryKey: ["repo", projectName, repoName, "webhooks", "deliveries", showDeliveries],
    queryFn: async () => {
      const res = await client.gitListDeliveries(projectName, repoName, showDeliveries!);
      return res.data;
    },
    enabled: Boolean(showDeliveries), retry: false,
  });

  const createWebhook = useMutation({
    mutationFn: async () => { await client.gitCreateWebhook(projectName, repoName, { url, secret: secret || null, events, active }); },
    onSuccess: () => { resetForm(); qc.invalidateQueries({ queryKey: ["repo", projectName, repoName, "webhooks"] }); },
    onError: (err: Error) => setError(err.message),
  });

  const updateWebhook = useMutation({
    mutationFn: async (id: string) => { await client.gitUpdateWebhook!(projectName, repoName, id, { url, secret: secret || null, events, active }); },
    onSuccess: () => { resetForm(); qc.invalidateQueries({ queryKey: ["repo", projectName, repoName, "webhooks"] }); },
    onError: (err: Error) => setError(err.message),
  });

  const deleteWebhook = useMutation({
    mutationFn: async (id: string) => { await client.gitDeleteWebhook(projectName, repoName, id); },
    onSuccess: () => qc.invalidateQueries({ queryKey: ["repo", projectName, repoName, "webhooks"] }),
  });

  const resetForm = () => { setShowForm(false); setEditingId(null); setUrl(""); setSecret(""); setEvents(["push"]); setActive(true); setError(""); };

  const startEdit = (wh: any) => { setEditingId(wh.id); setUrl(wh.url); setSecret(""); setEvents(wh.events); setActive(wh.active); setShowForm(true); };

  const toggleEvent = (event: string) => { setEvents((prev) => prev.includes(event) ? prev.filter((e) => e !== event) : [...prev, event]); };

  return (
    <div className="space-y-5">
      <div className="flex items-center justify-between">
        <p className="font-mono text-[11px] text-muted-foreground">{webhooks.length} webhook{webhooks.length !== 1 ? "s" : ""}</p>
        <Button className="h-8 px-3 text-[12px]" onClick={() => { resetForm(); setShowForm(!showForm); }}>
          <Plus className="size-3.5 mr-1" /> Add webhook
        </Button>
      </div>

      {showForm && (
        <div className="space-y-4 rounded-xl border border-border bg-card p-4 shadow-sm">
          <div className="flex items-center justify-between">
            <span className="font-heading text-[13px] font-semibold text-foreground">{editingId ? "Edit webhook" : "New webhook"}</span>
            <Button aria-label="Close webhook form" className="size-8 text-muted-foreground" onClick={resetForm} size="icon" variant="ghost"><X className="size-3" /></Button>
          </div>
          <div>
            <label className="text-[13px] font-medium text-foreground">Payload URL</label>
            <Input className="mt-1 h-9 text-[13px]" placeholder="https://example.com/webhook" value={url} onChange={(e) => setUrl(e.target.value)} />
          </div>
          <div>
            <label className="text-[13px] font-medium text-foreground">Secret <span className="text-muted-foreground">(optional)</span></label>
            <Input className="mt-1 h-9 text-[13px]" placeholder="A secret to sign the payload" value={secret} onChange={(e) => setSecret(e.target.value)} />
          </div>
          <div>
            <label className="text-[13px] font-medium text-foreground">Events</label>
            <div className="mt-1.5 flex flex-wrap gap-1.5">
              {EVENT_OPTIONS.map((event) => (
                <button className={`rounded-lg border px-2 py-1 text-[11px] font-medium transition-colors ${events.includes(event) ? "border-primary/30 bg-primary/10 text-primary" : "border-border text-muted-foreground hover:bg-muted/40 hover:text-foreground"}`} key={event} onClick={() => toggleEvent(event)} type="button">
                  {event}
                </button>
              ))}
            </div>
          </div>
          <label className="flex items-center gap-2 cursor-pointer">
            <input checked={active} className="size-3.5 rounded border-border accent-primary" onChange={(e) => setActive(e.target.checked)} type="checkbox" />
            <span className="text-[13px] text-foreground">Active</span>
          </label>
          {error && <p className="text-[12px] text-destructive">{error}</p>}
          <div className="flex items-center gap-2">
            <Button className="h-8 px-3 text-[12px]" disabled={!url.trim() || (editingId ? updateWebhook.isPending : createWebhook.isPending)} onClick={() => { if (editingId) updateWebhook.mutate(editingId); else createWebhook.mutate(); }}>
              {editingId ? "Update" : "Create"} webhook
            </Button>
            <Button className="h-8 px-3 text-[12px]" onClick={resetForm} variant="outline">Cancel</Button>
          </div>
        </div>
      )}

      <div className="overflow-hidden rounded-xl border border-border bg-card shadow-sm">
        {isLoading ? (
          <div className="px-4 py-2">{Array.from({ length: 2 }).map((_, i) => <div className="h-6 animate-pulse rounded bg-muted/50 my-1.5" key={i} />)}</div>
        ) : webhooks.length > 0 ? (
          webhooks.map((wh) => (
            <div key={wh.id}>
              <div className="flex items-center gap-3 border-b border-border px-4 py-3">
                <Webhook className="size-4 text-muted-foreground shrink-0" />
                <div className="min-w-0 flex-1">
                  <span className="font-heading text-[13px] font-semibold text-foreground truncate block">{wh.url}</span>
                  <div className="flex items-center gap-2 mt-0.5">
                    <span className={`inline-block size-1.5 rounded-full ${wh.active ? "bg-success" : "bg-muted-foreground"}`} />
                    <span className="font-mono text-[10px] text-muted-foreground">{wh.events.join(", ")}</span>
                    <span className="font-mono text-[10px] text-muted-foreground">· {formatDate(wh.created_at)}</span>
                  </div>
                </div>
                <Button aria-label="Edit webhook" className="size-8 text-muted-foreground hover:text-foreground" onClick={() => startEdit(wh)} size="icon" variant="ghost"><Pencil className="size-3" /></Button>
                <Button aria-label="Toggle delivery history" className="size-8 text-muted-foreground hover:text-foreground" onClick={() => setShowDeliveries(showDeliveries === wh.id ? null : wh.id)} size="icon" variant="ghost"><History className="size-3" /></Button>
                <Button aria-label="Delete webhook" className="size-8 text-destructive hover:text-destructive" onClick={() => deleteWebhook.mutate(wh.id)} size="icon" variant="ghost"><Trash2 className="size-3.5" /></Button>
              </div>
              {showDeliveries === wh.id && (
                <div className="border-b border-border bg-muted/20 px-6 py-3">
                  <p className="font-mono text-[10px] uppercase tracking-wider text-muted-foreground mb-2">Delivery history</p>
                  {deliveries.length > 0 ? (
                    <div className="space-y-1">{deliveries.slice(0, 10).map((d: any, i: number) => (
                      <div className="flex items-center gap-2 text-[11px] font-mono text-muted-foreground" key={i}>
                        <span className={`inline-block size-1.5 rounded-full ${d.status === "success" ? "bg-success" : "bg-destructive"}`} />
                        <span>{d.status ?? d.response_status ?? "?"}</span>
                        {d.timestamp && <span>{formatDate(d.timestamp)}</span>}
                        {d.http_status && <span>HTTP {d.http_status}</span>}
                      </div>
                    ))}</div>
                  ) : <p className="text-[11px] text-muted-foreground">No deliveries yet</p>}
                </div>
              )}
            </div>
          ))
        ) : (
          <div className="py-8 text-center">
            <Webhook className="mx-auto size-5 text-muted-foreground/20" />
            <p className="mt-2 text-[13px] text-muted-foreground">No webhooks configured</p>
          </div>
        )}
      </div>
    </div>
  );
}