'use client';

import { useMutation, useQueryClient } from '@tanstack/react-query';

import type { DetailTab } from '@/components/shared/detail-layout';
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 { RemindersInline } from '@/components/reminders/reminders-inline';
import { primaryTimezoneFor } from '@/lib/i18n/timezones';
import { InlineTagEditor } from '@/components/shared/inline-tag-editor';
import { NotesList } from '@/components/shared/notes-list';
import type { CountryCode } from '@/lib/i18n/countries';
import { ClientInterestsTab } from '@/components/clients/client-interests-tab';
import { ClientPipelineSummary } from '@/components/clients/client-pipeline-summary';
import { ClientYachtsTab } from '@/components/clients/client-yachts-tab';
import { ClientCompaniesTab } from '@/components/clients/client-companies-tab';
import { ClientReservationsTab } from '@/components/clients/client-reservations-tab';
import { ClientFilesTab } from '@/components/clients/client-files-tab';
import { ContactsEditor } from '@/components/clients/contacts-editor';
import { AddressesEditor, type Address } from '@/components/shared/addresses-editor';
import { EntityActivityFeed } from '@/components/shared/entity-activity-feed';
import { apiFetch } from '@/lib/api/client';
import { SOURCES } from '@/lib/constants';

type ClientPatchField =
  | 'fullName'
  | 'nationality'
  | 'nationalityIso'
  | 'preferredContactMethod'
  | 'preferredLanguage'
  | 'timezone'
  | 'source'
  | 'sourceDetails';

const SOURCE_OPTIONS = SOURCES.map((s) => ({ value: s.value, label: s.label }));

const CONTACT_METHOD_OPTIONS = [
  { value: 'email', label: 'Email' },
  { value: 'phone', label: 'Phone' },
  { value: 'whatsapp', label: 'WhatsApp' },
];

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

function EditableRow({ 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-40 shrink-0 text-sm text-muted-foreground">{label}</dt>
      <dd className="flex-1 min-w-0">{children}</dd>
    </div>
  );
}

interface ClientTabsOptions {
  clientId: string;
  currentUserId?: string;
  client: {
    fullName: string;
    nationality?: string | null;
    nationalityIso?: string | null;
    preferredContactMethod?: string | null;
    preferredLanguage?: string | null;
    timezone?: string | null;
    source?: string | null;
    sourceDetails?: string | null;
    contacts?: Array<{
      id: string;
      channel: string;
      value: string;
      valueE164?: string | null;
      valueCountry?: string | null;
      label?: string | null;
      isPrimary: boolean;
    }>;
    addresses?: Address[];
    yachts: Array<{
      id: string;
      name: string;
      hullNumber: string | null;
      registration: string | null;
      lengthFt: string | null;
      widthFt: string | null;
      status: string;
    }>;
    companies: Array<{
      membershipId: string;
      role: string;
      isPrimary: boolean;
      startDate: string | Date;
      company: {
        id: string;
        name: string;
        legalName: string | null;
        status: string;
      };
    }>;
    activeReservations: Array<{
      id: string;
      berthId: string;
      yachtId: string;
      startDate: string | Date;
      tenureType: string;
      status: string;
    }>;
    interestCount?: number;
    noteCount?: number;
    tags?: Array<{ id: string; name: string; color: string }>;
  };
}

function OverviewTab({
  clientId,
  client,
}: {
  clientId: string;
  client: ClientTabsOptions['client'];
}) {
  const mutation = useClientPatch(clientId);
  const save = (field: ClientPatchField) => async (next: string | null) => {
    await mutation.mutateAsync({ [field]: next });
  };

  return (
    <div className="space-y-6">
      <div className="rounded-xl border border-border bg-card p-4 shadow-sm">
        <ClientPipelineSummary clientId={clientId} variant="panel" />
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
        {/* Personal Info */}
        <div className="space-y-1">
          <h3 className="text-sm font-medium mb-2">Personal Information</h3>
          <dl>
            <EditableRow label="Full Name">
              <InlineEditableField value={client.fullName} onSave={save('fullName')} />
            </EditableRow>
            <EditableRow label="Country">
              <InlineCountryField
                value={client.nationalityIso ?? null}
                onSave={async (iso) => {
                  // Auto-default the timezone to the country's primary
                  // zone when none is set yet — saves the rep a click
                  // and matches what a marina actually wants for first
                  // contact (London for GB, NYC for US, etc.). Only
                  // fires when timezone is empty so we never clobber a
                  // value the rep deliberately picked.
                  const patch: { nationalityIso: string | null; timezone?: string | null } = {
                    nationalityIso: iso,
                  };
                  if (iso && !client.timezone) {
                    const defaultTz = primaryTimezoneFor(iso as CountryCode);
                    if (defaultTz) patch.timezone = defaultTz;
                  }
                  await mutation.mutateAsync(patch);
                }}
                data-testid="client-country-inline"
              />
            </EditableRow>
            <EditableRow label="Timezone">
              <InlineTimezoneField
                value={
                  client.timezone ??
                  (client.nationalityIso
                    ? primaryTimezoneFor(client.nationalityIso as CountryCode)
                    : null)
                }
                countryHint={(client.nationalityIso as CountryCode | null) ?? null}
                onSave={async (tz) => {
                  await mutation.mutateAsync({ timezone: tz });
                }}
                data-testid="client-timezone-inline"
              />
            </EditableRow>
            <EditableRow label="Preferred Contact">
              <InlineEditableField
                variant="select"
                options={CONTACT_METHOD_OPTIONS}
                value={client.preferredContactMethod}
                onSave={save('preferredContactMethod')}
              />
            </EditableRow>
          </dl>
        </div>

        {/* Contacts */}
        <div className="space-y-1">
          <h3 className="text-sm font-medium mb-2">Contact Details</h3>
          <ContactsEditor clientId={clientId} contacts={client.contacts ?? []} />
        </div>

        {/* Source */}
        <div className="space-y-1">
          <h3 className="text-sm font-medium mb-2">Source</h3>
          <dl>
            <EditableRow label="Source">
              <InlineEditableField
                variant="select"
                options={SOURCE_OPTIONS}
                value={client.source}
                onSave={save('source')}
              />
            </EditableRow>
            <EditableRow label="Source Details">
              <InlineEditableField value={client.sourceDetails} onSave={save('sourceDetails')} />
            </EditableRow>
          </dl>
        </div>

        <InlineTagEditor
          heading="Tags"
          endpoint={`/api/v1/clients/${clientId}/tags`}
          currentTags={client.tags ?? []}
          invalidateKey={['clients', clientId]}
        />

        <RemindersInline clientId={clientId} />
      </div>
    </div>
  );
}

export function getClientTabs({ clientId, currentUserId, client }: ClientTabsOptions): DetailTab[] {
  return [
    {
      id: 'overview',
      label: 'Overview',
      content: <OverviewTab clientId={clientId} client={client} />,
    },
    {
      id: 'interests',
      label: 'Interests',
      badge: client.interestCount,
      content: <ClientInterestsTab clientId={clientId} />,
    },
    {
      id: 'yachts',
      label: 'Yachts',
      badge: client.yachts.length,
      content: <ClientYachtsTab clientId={clientId} yachts={client.yachts} />,
    },
    {
      id: 'companies',
      label: 'Companies',
      badge: client.companies.length,
      content: <ClientCompaniesTab clientId={clientId} companies={client.companies} />,
    },
    {
      id: 'reservations',
      label: 'Reservations',
      badge: client.activeReservations.length,
      content: (
        <ClientReservationsTab clientId={clientId} activeReservations={client.activeReservations} />
      ),
    },
    {
      id: 'addresses',
      label: 'Addresses',
      badge: client.addresses?.length ?? 0,
      content: (
        <AddressesEditor
          endpoint={`/api/v1/clients/${clientId}/addresses`}
          invalidateKey={['clients', clientId]}
          addresses={client.addresses ?? []}
        />
      ),
    },
    {
      id: 'notes',
      label: 'Notes',
      badge: client.noteCount,
      content: (
        <NotesList
          aggregate
          entityType="clients"
          entityId={clientId}
          currentUserId={currentUserId}
        />
      ),
    },
    {
      id: 'files',
      label: 'Files',
      content: <ClientFilesTab clientId={clientId} />,
    },
    {
      id: 'activity',
      label: 'Activity',
      content: (
        <EntityActivityFeed
          endpoint={`/api/v1/clients/${clientId}/activity`}
          emptyText="No activity recorded for this client yet."
        />
      ),
    },
  ];
}
