"use client";

import Link from "next/link";
import { useState } from "react";
import { ChevronRight, Plus, Webhook } from "lucide-react";
import { Badge, Button, Dialog, EmptyState, PageHeader, Panel, Skeleton } from "@/components/ui/kit";
import { useToast } from "@/components/ui/toast";
import { useSession } from "@/components/session";
import { CopyField, DevTabs } from "@/components/developers/common";
import { EndpointForm, type Endpoint, type EventType } from "@/components/developers/endpoint-form";
import { api, ApiError } from "@/lib/api";
import { formatDateTime } from "@/lib/format";
import { useApi } from "@/lib/use-api";

export default function WebhooksPage() {
  const { can } = useSession();
  const toast = useToast();
  const manage = can("developers.manage");
  const { data, reload } = useApi<{ data: Endpoint[] }>("/developers/webhooks");
  const types = useApi<{ data: EventType[] }>("/developers/webhooks/event-types");
  const [creating, setCreating] = useState(false);
  const [busy, setBusy] = useState(false);
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [secret, setSecret] = useState<string | null>(null);

  async function create(body: Record<string, unknown>) {
    setBusy(true);
    setErrors({});
    try {
      const r = await api.post<{ data: Endpoint; secret: string }>("/developers/webhooks", body);
      setCreating(false);
      setSecret(r.secret);
      reload();
    } catch (e) {
      if (e instanceof ApiError && Object.keys(e.fields).length) setErrors(e.fields);
      else toast("error", (e as Error).message);
    } finally {
      setBusy(false);
    }
  }

  return (
    <>
      <PageHeader
        title="Developers"
        description="Connect your own systems to Devwebs with the REST API and signed webhooks."
        actions={
          manage && (
            <Button variant="primary" icon={<Plus className="size-4" />} onClick={() => (setErrors({}), setCreating(true))}>
              Add endpoint
            </Button>
          )
        }
      />
      <DevTabs />
      <p className="mb-4 max-w-3xl text-sm text-muted">
        Devwebs sends an HTTPS POST to your endpoint when something happens, signed with the endpoint&apos;s secret (Standard Webhooks). Failed deliveries are retried for about two days, and every attempt is logged.
      </p>
      <Panel>
        {!data ? (
          <Skeleton className="m-5 h-32" />
        ) : data.data.length === 0 ? (
          <EmptyState icon={<Webhook />} title="No endpoints yet" body="Add the URL of your server to receive messages, delivery updates, contact changes and more as they happen." action={manage ? <Button variant="primary" onClick={() => setCreating(true)}>Add endpoint</Button> : undefined} />
        ) : (
          <ul className="divide-y divide-line">
            {data.data.map((e) => (
              <li key={e.id}>
                <Link href={`/developers/webhooks/${e.id}`} className="flex items-center gap-4 px-5 py-4 hover:bg-paper">
                  <div className="min-w-0 flex-1">
                    <p className="flex flex-wrap items-center gap-2">
                      <span className="truncate font-mono text-[13px]">{e.url}</span>
                      <Badge tone={e.is_active ? (e.consecutive_failures ? "amber" : "teal") : "brick"}>{e.is_active ? (e.consecutive_failures ? "Failing" : "Active") : "Switched off"}</Badge>
                    </p>
                    <p className="mt-1 text-[13px] text-muted">
                      {e.description ? `${e.description}, ` : ""}
                      {e.events.includes("*") ? "all events" : `${e.events.length} event${e.events.length === 1 ? "" : "s"}`}
                      {e.stats ? `; last 24 h: ${e.stats.succeeded_24h} delivered, ${e.stats.failed_24h} failed, ${e.stats.pending} waiting` : ""}
                      {e.last_success_at ? `; last success ${formatDateTime(e.last_success_at)}` : ""}
                    </p>
                    {!e.is_active && e.disabled_reason && <p className="mt-1 text-[13px] text-brick">{e.disabled_reason}</p>}
                  </div>
                  <ChevronRight className="size-4 text-muted" />
                </Link>
              </li>
            ))}
          </ul>
        )}
      </Panel>
      {creating && types.data && (
        <Dialog open onClose={() => setCreating(false)} title="Add endpoint" size="md" footer={<><Button onClick={() => setCreating(false)}>Cancel</Button><Button variant="primary" type="submit" form="ep-form" loading={busy}>Add endpoint</Button></>}>
          <EndpointForm id="ep-form" types={types.data.data} errors={errors} busy={busy} onSubmit={create} />
        </Dialog>
      )}
      {secret && (
        <Dialog open onClose={() => setSecret(null)} title="Endpoint added" description="Use this signing secret to verify that requests come from Devwebs. You can view it again on the endpoint's page." footer={<Button variant="primary" onClick={() => setSecret(null)}>Done</Button>}>
          <CopyField value={secret} label="Signing secret" />
        </Dialog>
      )}
    </>
  );
}
