'use client';

import Link from 'next/link';
import { useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { Plus } from 'lucide-react';

import type { DetailTab } from '@/components/shared/detail-layout';
import { Button } from '@/components/ui/button';
import { InlineEditableField } from '@/components/shared/inline-editable-field';
import { InlineCountryField } from '@/components/shared/inline-country-field';
import { InlineTimezoneField } from '@/components/shared/inline-timezone-field';
import { InlinePhoneField } from '@/components/shared/inline-phone-field';
import { SubdivisionCombobox } from '@/components/shared/subdivision-combobox';
import { NotesList } from '@/components/shared/notes-list';
import { EntityActivityFeed } from '@/components/shared/entity-activity-feed';
import { apiFetch } from '@/lib/api/client';
import { SOURCES } from '@/lib/constants';
import type { CountryCode } from '@/lib/i18n/countries';

interface ResidentialInterestSummary {
  id: string;
  pipelineStage: string;
  source: string | null;
  notes: string | null;
  preferences: string | null;
  updatedAt: string;
}

interface ResidentialClient {
  id: string;
  fullName: string;
  email: string | null;
  phone: string | null;
  phoneE164: string | null;
  phoneCountry: string | null;
  nationalityIso: string | null;
  timezone: string | null;
  placeOfResidence: string | null;
  placeOfResidenceCountryIso: string | null;
  subdivisionIso: string | null;
  preferredContactMethod: string | null;
  status: string;
  source: string | null;
  notes: string | null;
  interests: ResidentialInterestSummary[];
}

interface Args {
  clientId: string;
  client: ResidentialClient;
  portSlug: string;
  currentUserId?: string;
  stageLabels: Record<string, string>;
}

const STATUS_OPTIONS = [
  { value: 'prospect', label: 'Prospect' },
  { value: 'active', label: 'Active' },
  { value: 'inactive', label: 'Inactive' },
];
const CONTACT_OPTIONS = [
  { value: 'email', label: 'Email' },
  { value: 'phone', label: 'Phone' },
];
const SOURCE_OPTIONS = SOURCES.map((s) => ({ value: s.value, label: s.label }));

function Row({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div className="flex gap-2 py-1.5 border-b last:border-0 items-center">
      <dt className="w-44 shrink-0 text-sm text-muted-foreground">{label}</dt>
      <dd className="flex-1 min-w-0">{children}</dd>
    </div>
  );
}

export function getResidentialClientTabs({
  clientId,
  client,
  portSlug,
  currentUserId,
  stageLabels,
}: Args): DetailTab[] {
  return [
    {
      id: 'overview',
      label: 'Overview',
      content: (
        <OverviewTab
          clientId={clientId}
          client={client}
          portSlug={portSlug}
          stageLabels={stageLabels}
        />
      ),
    },
    {
      id: 'interests',
      label: 'Interests',
      badge: client.interests.length || undefined,
      content: (
        <InterestsTab
          clientId={clientId}
          client={client}
          portSlug={portSlug}
          stageLabels={stageLabels}
        />
      ),
    },
    {
      id: 'notes',
      label: 'Notes',
      content: (
        <NotesList
          aggregate
          entityType="residential_clients"
          entityId={clientId}
          currentUserId={currentUserId}
          parentInvalidateKey={['residential-client', clientId]}
        />
      ),
    },
    {
      id: 'activity',
      label: 'Activity',
      content: (
        <EntityActivityFeed
          endpoint={`/api/v1/residential/clients/${clientId}/activity`}
          emptyText="No activity recorded for this residential client yet."
        />
      ),
    },
  ];
}

function useClientPatch(clientId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: (patch: Record<string, unknown>) =>
      apiFetch(`/api/v1/residential/clients/${clientId}`, { method: 'PATCH', body: patch }),
    onSuccess: () => qc.invalidateQueries({ queryKey: ['residential-client', clientId] }),
  });
}

function OverviewTab({
  clientId,
  client,
}: {
  clientId: string;
  client: ResidentialClient;
  portSlug: string;
  stageLabels: Record<string, string>;
}) {
  const update = useClientPatch(clientId);
  const save = (field: string) => async (next: string | null) => {
    await update.mutateAsync({ [field]: next });
  };

  return (
    <div className="rounded-lg border bg-card p-6 space-y-6">
      <div className="grid grid-cols-1 lg:grid-cols-[2fr_1fr] gap-6">
        <div className="space-y-1">
          <h3 className="text-sm font-medium mb-2">Contact</h3>
          <Row label="Email">
            <InlineEditableField value={client.email} onSave={save('email')} />
          </Row>
          <Row label="Phone">
            <InlinePhoneField
              e164={client.phoneE164}
              country={client.phoneCountry}
              onSave={async ({ e164, country }) => {
                await update.mutateAsync({ phone: e164, phoneE164: e164, phoneCountry: country });
              }}
            />
          </Row>
          <Row label="Preferred contact">
            <InlineEditableField
              variant="select"
              options={CONTACT_OPTIONS}
              value={client.preferredContactMethod}
              onSave={save('preferredContactMethod')}
            />
          </Row>
          <Row label="Country">
            <InlineCountryField
              value={client.nationalityIso}
              onSave={async (iso) => {
                await update.mutateAsync({ nationalityIso: iso });
              }}
            />
          </Row>
          <Row label="Timezone">
            <InlineTimezoneField
              value={client.timezone}
              countryHint={(client.nationalityIso as CountryCode | null) ?? null}
              onSave={async (tz) => {
                await update.mutateAsync({ timezone: tz });
              }}
            />
          </Row>
          <Row label="Place of residence">
            <InlineEditableField
              value={client.placeOfResidence}
              onSave={save('placeOfResidence')}
            />
          </Row>
          <Row label="Country of residence">
            <InlineCountryField
              value={client.placeOfResidenceCountryIso}
              onSave={async (iso) => {
                await update.mutateAsync({ placeOfResidenceCountryIso: iso, subdivisionIso: null });
              }}
            />
          </Row>
          <Row label="Region">
            <SubdivisionCombobox
              value={client.subdivisionIso}
              onChange={(code) => {
                void update.mutateAsync({ subdivisionIso: code });
              }}
              country={(client.placeOfResidenceCountryIso as CountryCode | null) ?? null}
            />
          </Row>
        </div>

        <div className="space-y-1">
          <h3 className="text-sm font-medium mb-2">Status</h3>
          <Row label="Status">
            <InlineEditableField
              variant="select"
              options={STATUS_OPTIONS}
              value={client.status}
              onSave={save('status')}
            />
          </Row>
          <Row label="Source">
            <InlineEditableField
              variant="select"
              options={SOURCE_OPTIONS}
              value={client.source}
              onSave={save('source')}
            />
          </Row>
        </div>
      </div>
    </div>
  );
}

function InterestsTab({
  clientId,
  client,
  portSlug,
  stageLabels,
}: {
  clientId: string;
  client: ResidentialClient;
  portSlug: string;
  stageLabels: Record<string, string>;
}) {
  const [open, setOpen] = useState(false);
  return (
    <div className="rounded-lg border bg-card p-6">
      <div className="flex items-center justify-between mb-4">
        <h2 className="text-lg font-semibold">Interests</h2>
        <Button size="sm" onClick={() => setOpen(true)}>
          <Plus className="h-3.5 w-3.5 mr-1.5" aria-hidden />
          New interest
        </Button>
      </div>
      {client.interests.length === 0 ? (
        <p className="text-sm text-muted-foreground">No interests yet.</p>
      ) : (
        <ul className="space-y-2">
          {client.interests.map((i) => (
            <li key={i.id}>
              <Link
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                href={`/${portSlug}/residential/interests/${i.id}` as any}
                className="flex items-center gap-3 p-3 rounded-md border bg-muted/30 hover:bg-muted/50 hover:border-primary/40 transition-colors"
              >
                <span className="text-xs font-medium uppercase text-muted-foreground w-32 shrink-0">
                  {stageLabels[i.pipelineStage] ?? i.pipelineStage}
                </span>
                <span className="flex-1 truncate text-sm">{i.preferences || i.notes || '-'}</span>
              </Link>
            </li>
          ))}
        </ul>
      )}
      {open && <NewInterestDialog clientId={clientId} open={open} onOpenChange={setOpen} />}
    </div>
  );
}

function NewInterestDialog({
  clientId,
  open,
  onOpenChange,
}: {
  clientId: string;
  open: boolean;
  onOpenChange: (v: boolean) => void;
}) {
  const qc = useQueryClient();
  const [preferences, setPreferences] = useState('');
  const [notes, setNotes] = useState('');
  const create = useMutation({
    mutationFn: () =>
      apiFetch('/api/v1/residential/interests', {
        method: 'POST',
        body: {
          residentialClientId: clientId,
          preferences: preferences || undefined,
          notes: notes || undefined,
          source: 'manual',
        },
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['residential-client', clientId] });
      onOpenChange(false);
      setPreferences('');
      setNotes('');
    },
  });

  if (!open) return null;
  return (
    <div className="fixed inset-0 z-50 grid place-items-center bg-black/40 p-4">
      <div className="w-full max-w-md rounded-lg border bg-card p-6 shadow-lg space-y-3">
        <h3 className="text-sm font-medium">New residential interest</h3>
        <textarea
          className="w-full rounded-md border px-3 py-2 text-sm"
          rows={3}
          placeholder="Preferences (unit type / size / budget / floor)"
          value={preferences}
          onChange={(e) => setPreferences(e.target.value)}
        />
        <textarea
          className="w-full rounded-md border px-3 py-2 text-sm"
          rows={3}
          placeholder="Initial notes"
          value={notes}
          onChange={(e) => setNotes(e.target.value)}
        />
        <div className="flex justify-end gap-2">
          <Button variant="outline" size="sm" onClick={() => onOpenChange(false)}>
            Cancel
          </Button>
          <Button size="sm" onClick={() => create.mutate()} disabled={create.isPending}>
            {create.isPending ? 'Creating…' : 'Create'}
          </Button>
        </div>
      </div>
    </div>
  );
}
