'use client';

import { useMemo, useState } from 'react';
import Link from 'next/link';
import type { Route } from 'next';
import { useParams, useRouter } from 'next/navigation';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { ArrowLeft, Copy, CopyCheck, Trash2, UserCog, Users } from 'lucide-react';
import { toast } from 'sonner';

import { PageHeader } from '@/components/shared/page-header';
import { PermissionGate } from '@/components/shared/permission-gate';
import { EmptyState } from '@/components/shared/empty-state';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Checkbox } from '@/components/ui/checkbox';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';

interface GroupMember {
  clientId: string;
  fullName: string;
  email: string | null;
}
interface ClientOption {
  id: string;
  fullName: string;
  primaryEmail: string | null;
}

async function copyToClipboard(text: string, successMsg: string) {
  try {
    await navigator.clipboard.writeText(text);
    toast.success(successMsg);
  } catch {
    toast.error('Copy failed — clipboard unavailable');
  }
}

export function ClientGroupDetail({ groupId }: { groupId: string }) {
  const params = useParams<{ portSlug: string }>();
  const portSlug = params?.portSlug ?? '';
  const router = useRouter();
  const qc = useQueryClient();
  const [manageOpen, setManageOpen] = useState(false);

  const { data: groupResp } = useQuery<{ data: { id: string; name: string; color: string } }>({
    queryKey: ['client-group', groupId],
    queryFn: () => apiFetch(`/api/v1/client-groups/${groupId}`),
  });
  const { data: membersResp, isLoading } = useQuery<{ data: GroupMember[] }>({
    queryKey: ['client-group', groupId, 'members'],
    queryFn: () => apiFetch(`/api/v1/client-groups/${groupId}/members`),
  });

  const group = groupResp?.data;
  const members = useMemo(() => membersResp?.data ?? [], [membersResp]);
  const emails = members.map((m) => m.email).filter((e): e is string => !!e);

  const archive = useMutation({
    mutationFn: () => apiFetch(`/api/v1/client-groups/${groupId}`, { method: 'DELETE' }),
    onSuccess: () => {
      toast.success('Group archived');
      qc.invalidateQueries({ queryKey: ['client-groups'] });
      router.push(`/${portSlug}/client-groups` as Route);
    },
    onError: (err) => toastError(err),
  });

  return (
    <div className="space-y-6">
      <Link
        href={`/${portSlug}/client-groups` as Route}
        className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
      >
        <ArrowLeft className="h-3.5 w-3.5" aria-hidden />
        All groups
      </Link>

      <PageHeader
        title={group?.name ?? 'Group'}
        eyebrow="Mailing group"
        kpiLine={
          <span className="inline-flex items-center gap-1.5">
            <Users className="h-3.5 w-3.5" aria-hidden />
            {members.length} {members.length === 1 ? 'member' : 'members'}
            {emails.length < members.length ? (
              <span className="text-amber-700">
                · {members.length - emails.length} without email
              </span>
            ) : null}
          </span>
        }
        variant="gradient"
        actions={
          <>
            <Button
              variant="outline"
              disabled={emails.length === 0}
              onClick={() =>
                copyToClipboard(emails.join(', '), `Copied ${emails.length} email addresses`)
              }
            >
              <CopyCheck className="me-1.5 h-4 w-4" aria-hidden />
              Copy all emails
            </Button>
            <PermissionGate resource="client_groups" action="manage">
              <Button variant="outline" onClick={() => setManageOpen(true)}>
                <UserCog className="me-1.5 h-4 w-4" aria-hidden />
                Manage members
              </Button>
            </PermissionGate>
            <PermissionGate resource="client_groups" action="manage">
              <Button
                variant="ghost"
                className="text-destructive"
                onClick={() => {
                  if (confirm('Archive this group? Members are kept; the group is hidden.')) {
                    archive.mutate();
                  }
                }}
              >
                <Trash2 className="me-1.5 h-4 w-4" aria-hidden />
                Archive
              </Button>
            </PermissionGate>
          </>
        }
      />

      {isLoading ? (
        <p className="text-sm text-muted-foreground">Loading members…</p>
      ) : members.length === 0 ? (
        <EmptyState
          icon={Users}
          title="No members yet"
          description="Use “Manage members” to add clients to this group."
        />
      ) : (
        <div className="overflow-hidden rounded-xl border border-border">
          <table className="w-full text-sm">
            <thead className="bg-muted/50 text-left text-xs uppercase tracking-wide text-muted-foreground">
              <tr>
                <th className="px-4 py-2 font-medium">Client</th>
                <th className="px-4 py-2 font-medium">Email</th>
                <th className="px-4 py-2" />
              </tr>
            </thead>
            <tbody className="divide-y divide-border">
              {members.map((m) => (
                <tr key={m.clientId} className="hover:bg-muted/30">
                  <td className="px-4 py-2">
                    <Link
                      href={`/${portSlug}/clients/${m.clientId}` as Route}
                      className="text-foreground hover:underline"
                    >
                      {m.fullName}
                    </Link>
                  </td>
                  <td className="px-4 py-2 text-muted-foreground">{m.email ?? '—'}</td>
                  <td className="px-4 py-2 text-end">
                    {m.email ? (
                      <button
                        type="button"
                        onClick={() => copyToClipboard(m.email!, 'Email copied')}
                        aria-label={`Copy ${m.email}`}
                        title="Copy email"
                        className="rounded-md p-1.5 text-muted-foreground/70 transition-colors hover:bg-foreground/5 hover:text-foreground"
                      >
                        <Copy className="h-4 w-4" aria-hidden />
                      </button>
                    ) : null}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {manageOpen ? (
        <ManageMembersDialog
          groupId={groupId}
          open={manageOpen}
          onOpenChange={setManageOpen}
          currentIds={members.map((m) => m.clientId)}
          onSaved={() => {
            qc.invalidateQueries({ queryKey: ['client-group', groupId, 'members'] });
            qc.invalidateQueries({ queryKey: ['client-groups'] });
          }}
        />
      ) : null}
    </div>
  );
}

function ManageMembersDialog({
  groupId,
  open,
  onOpenChange,
  currentIds,
  onSaved,
}: {
  groupId: string;
  open: boolean;
  onOpenChange: (v: boolean) => void;
  currentIds: string[];
  onSaved: () => void;
}) {
  const [search, setSearch] = useState('');
  const [selected, setSelected] = useState<Set<string>>(new Set(currentIds));

  const { data, isLoading } = useQuery<{ data: ClientOption[] }>({
    queryKey: ['clients', 'group-picker'],
    queryFn: () => apiFetch('/api/v1/clients?limit=1000'),
    enabled: open,
  });

  const clients = data?.data ?? [];
  const filtered = clients.filter((c) =>
    `${c.fullName} ${c.primaryEmail ?? ''}`.toLowerCase().includes(search.trim().toLowerCase()),
  );

  const save = useMutation({
    mutationFn: () =>
      apiFetch(`/api/v1/client-groups/${groupId}/members`, {
        method: 'PUT',
        body: { clientIds: Array.from(selected) },
      }),
    onSuccess: () => {
      toast.success('Members updated');
      onSaved();
      onOpenChange(false);
    },
    onError: (err) => toastError(err),
  });

  function toggle(id: string) {
    setSelected((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-lg">
        <DialogHeader>
          <DialogTitle>Manage members</DialogTitle>
          <DialogDescription>
            Tick the clients who belong in this group. {selected.size} selected.
          </DialogDescription>
        </DialogHeader>
        <Input
          placeholder="Search clients…"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
        />
        <div className="max-h-80 space-y-1 overflow-y-auto rounded-lg border border-border p-2">
          {isLoading ? (
            <p className="p-2 text-sm text-muted-foreground">Loading clients…</p>
          ) : filtered.length === 0 ? (
            <p className="p-2 text-sm text-muted-foreground">No matching clients.</p>
          ) : (
            filtered.map((c) => (
              <label
                key={c.id}
                className="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 hover:bg-muted/50"
              >
                <Checkbox checked={selected.has(c.id)} onCheckedChange={() => toggle(c.id)} />
                <span className="min-w-0 flex-1">
                  <span className="block truncate text-sm text-foreground">{c.fullName}</span>
                  {c.primaryEmail ? (
                    <span className="block truncate text-xs text-muted-foreground">
                      {c.primaryEmail}
                    </span>
                  ) : null}
                </span>
              </label>
            ))
          )}
        </div>
        <DialogFooter>
          <Button variant="ghost" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button onClick={() => save.mutate()} disabled={save.isPending}>
            Save members
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
