'use client';

import { useState } from 'react';
import Link from 'next/link';
import type { Route } from 'next';
import { useParams, useRouter } from 'next/navigation';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Plus } 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 { Sheet, SheetContent, SheetFooter, SheetHeader, SheetTitle } from '@/components/ui/sheet';
import { PageHeader } from '@/components/shared/page-header';
import { CountryCombobox } from '@/components/shared/country-combobox';
import { TimezoneCombobox } from '@/components/shared/timezone-combobox';
import { SubdivisionCombobox } from '@/components/shared/subdivision-combobox';
import { PhoneInput, type PhoneInputValue } from '@/components/shared/phone-input';
import { useRealtimeInvalidation } from '@/hooks/use-realtime-invalidation';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';
import { cn } from '@/lib/utils';
import type { CountryCode } from '@/lib/i18n/countries';
import { DataTable } from '@/components/shared/data-table';
import { ColumnPicker } from '@/components/shared/column-picker';
import { useTablePreferences } from '@/hooks/use-table-preferences';
import {
  getResidentialClientColumns,
  RESIDENTIAL_CLIENT_COLUMN_OPTIONS,
  RESIDENTIAL_CLIENT_DEFAULT_HIDDEN,
  type ResidentialClientRow,
} from '@/components/residential/residential-client-columns';

interface ListResponse {
  data: ResidentialClientRow[];
  pagination: { total: number; page: number; pageSize: number };
}

const STATUS_LABELS: Record<string, string> = {
  prospect: 'Prospect',
  active: 'Active',
  inactive: 'Inactive',
};

export function ResidentialClientsList() {
  const params = useParams<{ portSlug: string }>();
  const portSlug = params?.portSlug ?? '';
  const router = useRouter();
  const [createOpen, setCreateOpen] = useState(false);
  const [search, setSearch] = useState('');

  const { data, isLoading } = useQuery<ListResponse>({
    queryKey: ['residential-clients', { search }],
    queryFn: () => {
      const qs = new URLSearchParams({ search, limit: '50' });
      return apiFetch(`/api/v1/residential/clients?${qs.toString()}`);
    },
  });

  useRealtimeInvalidation({
    'residential_client:created': [['residential-clients']],
    'residential_client:updated': [['residential-clients']],
    'residential_client:archived': [['residential-clients']],
    'residential_client:restored': [['residential-clients']],
  });

  const columns = getResidentialClientColumns({ portSlug });
  // Per-user column visibility, persisted via /api/v1/me — same hook + UX as
  // the marina clients/interests lists. "Residence" is hidden by default
  // (it's empty for nearly every residential client); "Date added" is shown.
  const { hidden, setHidden } = useTablePreferences(
    'residential-clients',
    RESIDENTIAL_CLIENT_DEFAULT_HIDDEN,
  );
  const columnVisibility = Object.fromEntries(hidden.map((id) => [id, false]));
  const rows = data?.data ?? [];

  return (
    <div className="space-y-4">
      <PageHeader
        title="Residential Clients"
        description="Inquiries and clients for the residential side"
        actions={
          <Button size="sm" onClick={() => setCreateOpen(true)}>
            <Plus className="mr-1.5 h-3.5 w-3.5" aria-hidden />
            New
          </Button>
        }
      />

      <div className="flex flex-wrap items-center gap-2">
        <Input
          placeholder="Search by name, email, phone, residence…"
          value={search}
          onChange={(e) => setSearch(e.target.value)}
          className="max-w-sm"
        />
        <ColumnPicker
          columns={RESIDENTIAL_CLIENT_COLUMN_OPTIONS}
          hidden={hidden}
          onChange={setHidden}
        />
      </div>

      <DataTable
        columns={columns}
        columnVisibility={columnVisibility}
        data={rows}
        isLoading={isLoading}
        getRowId={(r) => r.id}
        onRowClick={(r) => router.push(`/${portSlug}/residential/clients/${r.id}` as Route)}
        emptyState={
          <div className="px-3 py-8 text-center text-sm text-muted-foreground">
            No residential clients yet.
          </div>
        }
        cardRender={(row) => <ResidentialClientCard portSlug={portSlug} client={row.original} />}
      />

      <NewResidentialClientSheet open={createOpen} onOpenChange={setCreateOpen} />
    </div>
  );
}

/**
 * Mobile card for a residential client — DataTable swaps to this below the
 * md breakpoint. Self-navigating `<Link>` (DataTable's onRowClick only wires
 * the desktop table rows). Mirrors the marina-side card density.
 */
function ResidentialClientCard({
  portSlug,
  client,
}: {
  portSlug: string;
  client: ResidentialClientRow;
}) {
  return (
    <Link
      href={`/${portSlug}/residential/clients/${client.id}` as Route}
      className="block rounded-lg border bg-card p-3 transition-colors hover:bg-muted/30"
    >
      <div className="flex items-start justify-between gap-2">
        <p className="truncate text-sm font-medium">{client.fullName}</p>
        <span
          className={cn(
            'inline-flex shrink-0 items-center rounded-full px-2 py-0.5 text-xs font-medium uppercase tracking-wide',
            client.status === 'active'
              ? 'bg-emerald-100 text-emerald-800'
              : client.status === 'inactive'
                ? 'bg-muted text-muted-foreground'
                : 'bg-blue-100 text-blue-800',
          )}
        >
          {STATUS_LABELS[client.status] ?? client.status}
        </span>
      </div>
      <div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-muted-foreground">
        {client.email ? <span className="truncate">{client.email}</span> : null}
        {client.phone ? <span>{client.phone}</span> : null}
        {client.placeOfResidence ? <span>{client.placeOfResidence}</span> : null}
        {client.source ? <span className="capitalize">· {client.source}</span> : null}
      </div>
    </Link>
  );
}

function NewResidentialClientSheet({
  open,
  onOpenChange,
}: {
  open: boolean;
  onOpenChange: (v: boolean) => void;
}) {
  const qc = useQueryClient();
  const [fullName, setFullName] = useState('');
  const [email, setEmail] = useState('');
  const [phone, setPhone] = useState<PhoneInputValue | null>(null);
  const [nationalityIso, setNationalityIso] = useState<CountryCode | null>(null);
  const [timezone, setTimezone] = useState<string | null>(null);
  const [placeOfResidence, setPlaceOfResidence] = useState('');
  const [residenceCountry, setResidenceCountry] = useState<CountryCode | null>(null);
  const [residenceSubdivision, setResidenceSubdivision] = useState<string | null>(null);
  const [notes, setNotes] = useState('');

  function reset() {
    setFullName('');
    setEmail('');
    setPhone(null);
    setNationalityIso(null);
    setTimezone(null);
    setPlaceOfResidence('');
    setResidenceCountry(null);
    setResidenceSubdivision(null);
    setNotes('');
  }

  const create = useMutation({
    mutationFn: () =>
      apiFetch('/api/v1/residential/clients', {
        method: 'POST',
        body: {
          fullName,
          email: email || undefined,
          phone: phone?.e164 ?? undefined,
          phoneE164: phone?.e164 ?? undefined,
          phoneCountry: phone?.country ?? undefined,
          nationalityIso: nationalityIso ?? undefined,
          timezone: timezone ?? undefined,
          placeOfResidence: placeOfResidence || undefined,
          placeOfResidenceCountryIso: residenceCountry ?? undefined,
          subdivisionIso: residenceSubdivision ?? undefined,
          notes: notes || undefined,
          source: 'manual',
        },
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['residential-clients'] });
      onOpenChange(false);
      reset();
      toast.success('Residential client added');
    },
    onError: (err) => {
      toastError(err);
    },
  });

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent>
        <SheetHeader>
          <SheetTitle>New residential client</SheetTitle>
        </SheetHeader>
        <form
          className="mt-6 space-y-4"
          onSubmit={(e) => {
            e.preventDefault();
            create.mutate();
          }}
        >
          <div className="space-y-1.5">
            <Label htmlFor="rc-name">Full name *</Label>
            <Input
              id="rc-name"
              value={fullName}
              onChange={(e) => setFullName(e.target.value)}
              required
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="rc-email">Email</Label>
            <Input
              id="rc-email"
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="rc-phone">Phone</Label>
            <PhoneInput id="rc-phone" value={phone} onChange={setPhone} data-testid="rc-phone" />
          </div>
          <div className="grid grid-cols-2 gap-3">
            <div className="space-y-1.5">
              <Label htmlFor="rc-nationality">Nationality</Label>
              <CountryCombobox
                id="rc-nationality"
                value={nationalityIso}
                onChange={setNationalityIso}
                data-testid="rc-nationality"
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="rc-timezone">Timezone</Label>
              <TimezoneCombobox
                id="rc-timezone"
                value={timezone}
                onChange={setTimezone}
                countryHint={nationalityIso ?? undefined}
                data-testid="rc-timezone"
              />
            </div>
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="rc-residence">Place of residence</Label>
            <Input
              id="rc-residence"
              value={placeOfResidence}
              onChange={(e) => setPlaceOfResidence(e.target.value)}
              placeholder="City or area"
            />
          </div>
          <div className="grid grid-cols-2 gap-3">
            <div className="space-y-1.5">
              <Label htmlFor="rc-residence-country">Country</Label>
              <CountryCombobox
                id="rc-residence-country"
                value={residenceCountry}
                onChange={(iso) => {
                  setResidenceCountry(iso);
                  // Wipe subdivision when country flips - codes are scoped per country.
                  setResidenceSubdivision(null);
                }}
                data-testid="rc-residence-country"
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="rc-residence-subdivision">Region</Label>
              <SubdivisionCombobox
                id="rc-residence-subdivision"
                value={residenceSubdivision}
                onChange={setResidenceSubdivision}
                country={residenceCountry}
                data-testid="rc-residence-subdivision"
              />
            </div>
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="rc-notes">Notes</Label>
            <Input id="rc-notes" value={notes} onChange={(e) => setNotes(e.target.value)} />
          </div>
          <SheetFooter>
            <Button
              type="button"
              variant="outline"
              onClick={() => onOpenChange(false)}
              disabled={create.isPending}
            >
              Cancel
            </Button>
            <Button type="submit" disabled={!fullName.trim() || create.isPending}>
              {create.isPending ? 'Saving…' : 'Create'}
            </Button>
          </SheetFooter>
        </form>
      </SheetContent>
    </Sheet>
  );
}
