'use client';

import { useState } from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Mail, Phone, UserCheck, UserPlus } from 'lucide-react';
import { toast } from 'sonner';

import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { usePermissions } from '@/hooks/use-permissions';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';

type ProxyEntityType = 'client' | 'interest' | 'yacht';

interface Proxy {
  id: string;
  name: string;
  email: string | null;
  phone: string | null;
  relationship: string | null;
  notes: string | null;
}

const RESOURCE: Record<ProxyEntityType, 'clients' | 'interests' | 'yachts'> = {
  client: 'clients',
  interest: 'interests',
  yacht: 'yachts',
};

/**
 * CM-9: point-of-contact ("proxy") panel for a client / interest / yacht detail
 * page. Reads + edits the per-entity proxy via the entity's sub-resource route.
 */
export function ProxyCard({
  entityType,
  entityId,
}: {
  entityType: ProxyEntityType;
  entityId: string;
}) {
  const { can } = usePermissions();
  const canManage = can(RESOURCE[entityType], 'edit');
  const qc = useQueryClient();
  const base = `/api/v1/${RESOURCE[entityType]}/${entityId}/proxy`;
  const queryKey = ['proxy', entityType, entityId];

  const { data } = useQuery<{ data: Proxy | null }>({
    queryKey,
    queryFn: () => apiFetch(base),
  });
  const proxy = data?.data ?? null;

  const [open, setOpen] = useState(false);

  const remove = useMutation({
    mutationFn: () => apiFetch(base, { method: 'DELETE' }),
    onSuccess: () => {
      toast.success('Point of contact removed');
      qc.invalidateQueries({ queryKey });
    },
    onError: (err) => toastError(err),
  });

  return (
    <div className="rounded-xl border border-border bg-card p-4">
      <div className="mb-2 flex items-center justify-between">
        <h3 className="inline-flex items-center gap-1.5 text-sm font-semibold text-foreground">
          <UserCheck className="h-4 w-4 text-muted-foreground" aria-hidden />
          Point of contact
        </h3>
        {canManage ? (
          <Button variant="ghost" size="sm" className="h-7" onClick={() => setOpen(true)}>
            {proxy ? (
              'Edit'
            ) : (
              <>
                <UserPlus className="me-1 h-3.5 w-3.5" aria-hidden />
                Add
              </>
            )}
          </Button>
        ) : null}
      </div>

      {proxy ? (
        <div className="space-y-1 text-sm">
          <p className="font-medium text-foreground">
            {proxy.name}
            {proxy.relationship ? (
              <span className="ms-2 text-xs font-normal text-muted-foreground">
                {proxy.relationship}
              </span>
            ) : null}
          </p>
          {proxy.email ? (
            <a
              href={`mailto:${proxy.email}`}
              className="inline-flex items-center gap-1.5 text-muted-foreground hover:text-foreground"
            >
              <Mail className="h-3.5 w-3.5" aria-hidden />
              {proxy.email}
            </a>
          ) : null}
          {proxy.phone ? (
            <p className="inline-flex items-center gap-1.5 text-muted-foreground">
              <Phone className="h-3.5 w-3.5" aria-hidden />
              {proxy.phone}
            </p>
          ) : null}
          {proxy.notes ? <p className="text-xs text-muted-foreground">{proxy.notes}</p> : null}
          {canManage ? (
            <button
              type="button"
              onClick={() => remove.mutate()}
              disabled={remove.isPending}
              className="pt-1 text-xs text-destructive hover:underline disabled:opacity-50"
            >
              Remove
            </button>
          ) : null}
        </div>
      ) : (
        <p className="text-sm text-muted-foreground">
          No proxy set — comms go to the {entityType} directly.
        </p>
      )}

      {open ? (
        <ProxyDialog
          open={open}
          onOpenChange={setOpen}
          base={base}
          existing={proxy}
          entityType={entityType}
          onSaved={() => qc.invalidateQueries({ queryKey })}
        />
      ) : null}
    </div>
  );
}

function ProxyDialog({
  open,
  onOpenChange,
  base,
  existing,
  entityType,
  onSaved,
}: {
  open: boolean;
  onOpenChange: (v: boolean) => void;
  base: string;
  existing: Proxy | null;
  entityType: ProxyEntityType;
  onSaved: () => void;
}) {
  const [name, setName] = useState(existing?.name ?? '');
  const [email, setEmail] = useState(existing?.email ?? '');
  const [phone, setPhone] = useState(existing?.phone ?? '');
  const [relationship, setRelationship] = useState(existing?.relationship ?? '');
  const [notes, setNotes] = useState(existing?.notes ?? '');
  // State seeds from `existing` at mount; the dialog is remounted on each open
  // (the parent renders it conditionally), so no reseed effect is needed.

  const save = useMutation({
    mutationFn: () =>
      apiFetch(base, {
        method: 'PUT',
        body: { name: name.trim(), email, phone, relationship, notes },
      }),
    onSuccess: () => {
      toast.success('Point of contact saved');
      onSaved();
      onOpenChange(false);
    },
    onError: (err) => toastError(err),
  });

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Point of contact</DialogTitle>
          <DialogDescription>
            A person who acts as the point of contact for this {entityType}. Used to address
            outbound comms.
          </DialogDescription>
        </DialogHeader>
        <div className="space-y-3">
          <div className="space-y-1.5">
            <Label htmlFor="proxy-name">Name</Label>
            <Input
              id="proxy-name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              autoFocus
            />
          </div>
          <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
            <div className="space-y-1.5">
              <Label htmlFor="proxy-email">Email</Label>
              <Input
                id="proxy-email"
                type="email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="proxy-phone">Phone</Label>
              <Input id="proxy-phone" value={phone} onChange={(e) => setPhone(e.target.value)} />
            </div>
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="proxy-rel">Relationship (optional)</Label>
            <Input
              id="proxy-rel"
              placeholder="e.g. broker, spouse, assistant, legal"
              value={relationship}
              onChange={(e) => setRelationship(e.target.value)}
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="proxy-notes">Notes (optional)</Label>
            <Input id="proxy-notes" value={notes} onChange={(e) => setNotes(e.target.value)} />
          </div>
        </div>
        <DialogFooter>
          <Button variant="ghost" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button onClick={() => save.mutate()} disabled={!name.trim() || save.isPending}>
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
