'use client';

import { useState } from 'react';
import Link from 'next/link';
import { useParams } 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';

interface ResidentialClientRow {
  id: string;
  fullName: string;
  email: string | null;
  phone: string | null;
  placeOfResidence: string | null;
  status: string;
  source: string | null;
  updatedAt: string;
}

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 [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']],
  });

  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" />
            New
          </Button>
        }
      />

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

      {/* Desktop: table layout. Hidden below lg because the 6 columns clip
          off the viewport at phone widths. */}
      <div className="hidden lg:block rounded-lg border bg-card overflow-hidden">
        <table className="w-full text-sm">
          <thead className="bg-muted/40 text-xs text-muted-foreground">
            <tr>
              <th className="text-left font-medium px-3 py-2">Name</th>
              <th className="text-left font-medium px-3 py-2">Email</th>
              <th className="text-left font-medium px-3 py-2">Phone</th>
              <th className="text-left font-medium px-3 py-2">Residence</th>
              <th className="text-left font-medium px-3 py-2">Status</th>
              <th className="text-left font-medium px-3 py-2">Source</th>
            </tr>
          </thead>
          <tbody>
            {isLoading && (
              <tr>
                <td colSpan={6} className="px-3 py-8 text-center text-muted-foreground">
                  Loading…
                </td>
              </tr>
            )}
            {!isLoading && data?.data.length === 0 && (
              <tr>
                <td colSpan={6} className="px-3 py-8 text-center text-muted-foreground">
                  No residential clients yet.
                </td>
              </tr>
            )}
            {data?.data.map((c) => (
              <tr
                key={c.id}
                className="border-t hover:bg-muted/30 transition-colors cursor-pointer"
              >
                <td className="px-3 py-2">
                  <Link
                    /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
                    href={`/${portSlug}/residential/clients/${c.id}` as any}
                    className="font-medium hover:underline"
                  >
                    {c.fullName}
                  </Link>
                </td>
                <td className="px-3 py-2 text-muted-foreground">{c.email ?? '-'}</td>
                <td className="px-3 py-2 text-muted-foreground">{c.phone ?? '-'}</td>
                <td className="px-3 py-2 text-muted-foreground">{c.placeOfResidence ?? '-'}</td>
                <td className="px-3 py-2">{STATUS_LABELS[c.status] ?? c.status}</td>
                <td className="px-3 py-2 capitalize text-muted-foreground">{c.source ?? '-'}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      {/* Mobile: card list. Each card mirrors the table row data with
          name + status pill on top, then meta line(s) below. */}
      <div className="lg:hidden space-y-2">
        {isLoading && (
          <div className="rounded-lg border bg-card px-3 py-8 text-center text-sm text-muted-foreground">
            Loading…
          </div>
        )}
        {!isLoading && data?.data.length === 0 && (
          <div className="rounded-lg border bg-card px-3 py-8 text-center text-sm text-muted-foreground">
            No residential clients yet.
          </div>
        )}
        {data?.data.map((c) => (
          <Link
            key={c.id}
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            href={`/${portSlug}/residential/clients/${c.id}` as any}
            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="font-medium text-sm truncate">{c.fullName}</p>
              <span
                className={cn(
                  'shrink-0 inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide',
                  c.status === 'active'
                    ? 'bg-emerald-100 text-emerald-800'
                    : c.status === 'inactive'
                      ? 'bg-muted text-muted-foreground'
                      : 'bg-blue-100 text-blue-800',
                )}
              >
                {STATUS_LABELS[c.status] ?? c.status}
              </span>
            </div>
            <div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-xs text-muted-foreground">
              {c.email ? <span className="truncate">{c.email}</span> : null}
              {c.phone ? <span>{c.phone}</span> : null}
              {c.placeOfResidence ? <span>{c.placeOfResidence}</span> : null}
              {c.source ? <span className="capitalize">· {c.source}</span> : null}
            </div>
          </Link>
        ))}
      </div>

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

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>
  );
}
