"use client";

import Link from "next/link";
import { useCallback, useEffect, useState, type FormEvent } from "react";
import { Plus, Shapes } from "lucide-react";
import { Button, ConfirmDialog, Dialog, EmptyState, Field, Input, PageHeader, Panel, Skeleton } from "@/components/ui/kit";
import { useToast } from "@/components/ui/toast";
import { useSession } from "@/components/session";
import { api, ApiError } from "@/lib/api";
import type { Group } from "@/lib/types";

export default function GroupsPage() {
  const { can } = useSession();
  const toast = useToast();
  const [groups, setGroups] = useState<Group[] | null>(null);
  const [editing, setEditing] = useState<Group | "new" | null>(null);
  const [toDelete, setToDelete] = useState<Group | null>(null);
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [saving, setSaving] = useState(false);

  const load = useCallback(() => api.get<{ data: Group[] }>("/groups").then((r) => setGroups(r.data)), []);
  useEffect(() => {
    load().catch((e) => toast("error", e.message));
  }, [load, toast]);

  async function save(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const body = Object.fromEntries(new FormData(e.currentTarget));
    setSaving(true);
    setErrors({});
    try {
      if (editing === "new") await api.post("/groups", body);
      else if (editing) await api.patch(`/groups/${editing.id}`, body);
      toast("success", editing === "new" ? "Group created" : "Group saved");
      setEditing(null);
      load();
    } catch (err) {
      if (err instanceof ApiError && Object.keys(err.fields).length) setErrors(err.fields);
      else toast("error", (err as Error).message);
    } finally {
      setSaving(false);
    }
  }

  async function remove() {
    if (!toDelete) return;
    setSaving(true);
    try {
      await api.delete(`/groups/${toDelete.id}`);
      toast("success", "Group deleted");
      setToDelete(null);
      load();
    } catch (e) {
      toast("error", (e as Error).message);
    } finally {
      setSaving(false);
    }
  }

  const current = editing && editing !== "new" ? editing : null;

  return (
    <>
      <PageHeader
        title="Groups"
        description="Groups are the audiences you pick when sending a campaign. A contact can be in several groups."
        actions={
          can("groups.manage") && (
            <Button
              variant="primary"
              icon={<Plus className="size-4" />}
              onClick={() => {
                setErrors({});
                setEditing("new");
              }}
            >
              New group
            </Button>
          )
        }
      />
      <Panel>
        {!groups ? (
          <div className="space-y-3 p-4">
            {Array.from({ length: 4 }).map((_, i) => (
              <Skeleton key={i} className="h-6 w-full" />
            ))}
          </div>
        ) : groups.length === 0 ? (
          <EmptyState
            icon={<Shapes className="size-5" />}
            title="No groups yet"
            body="Create groups like VIP customers or Newsletter, then add contacts to them from the contact form or with bulk actions."
            action={can("groups.manage") && <Button variant="primary" onClick={() => setEditing("new")}>New group</Button>}
          />
        ) : (
          <div className="relative overflow-x-auto">
          <table className="w-full min-w-[560px] text-sm">
            <thead>
              <tr className="border-b border-line text-left text-[13px] text-muted">
                <th className="px-4 py-2.5 font-medium">Name</th>
                <th className="px-4 py-2.5 font-medium">Description</th>
                <th className="px-4 py-2.5 text-right font-medium">Contacts</th>
                <th className="px-4 py-2.5">
                  <span className="sr-only">Actions</span>
                </th>
              </tr>
            </thead>
            <tbody>
              {groups.map((g) => (
                <tr key={g.id} className="border-b border-line last:border-0 hover:bg-paper/70">
                  <td className="px-4 py-3 font-medium text-ink">{g.name}</td>
                  <td className="px-4 py-3 text-muted">{g.description ?? "—"}</td>
                  <td className="tabular px-4 py-3 text-right">
                    <Link href="/contacts" className="hover:text-teal hover:underline">
                      {g.contacts_count}
                    </Link>
                  </td>
                  <td className="whitespace-nowrap px-4 py-3 text-right">
                    {can("groups.manage") && (
                      <>
                        <Button size="sm" variant="ghost" onClick={() => { setErrors({}); setEditing(g); }}>
                          Edit
                        </Button>
                        <Button size="sm" variant="ghost" className="hover:bg-brick-soft hover:text-brick" onClick={() => setToDelete(g)}>
                          Delete
                        </Button>
                      </>
                    )}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          </div>
        )}
      </Panel>

      <Dialog
        open={editing !== null}
        onClose={() => setEditing(null)}
        title={current ? "Edit group" : "New group"}
        size="sm"
        footer={
          <>
            <Button onClick={() => setEditing(null)}>Cancel</Button>
            <Button variant="primary" type="submit" form="group-form" loading={saving}>
              {current ? "Save group" : "Create group"}
            </Button>
          </>
        }
      >
        <form id="group-form" onSubmit={save} className="space-y-4" noValidate>
          <Field label="Name" htmlFor="g-name" error={errors.name}>
            <Input id="g-name" name="name" defaultValue={current?.name ?? ""} invalid={!!errors.name} autoFocus />
          </Field>
          <Field label="Description" htmlFor="g-desc" optional error={errors.description}>
            <Input id="g-desc" name="description" defaultValue={current?.description ?? ""} />
          </Field>
        </form>
      </Dialog>

      <ConfirmDialog
        open={!!toDelete}
        title={`Delete "${toDelete?.name}"?`}
        message={`The ${toDelete?.contacts_count ?? 0} contacts in this group stay in your contact list. Only the group is removed.`}
        confirmLabel="Delete group"
        loading={saving}
        onConfirm={remove}
        onClose={() => setToDelete(null)}
      />
    </>
  );
}
