'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 { FieldHistoryProvider, FieldHistoryIcon } from '@/components/shared/field-history';
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 { ProxyCard } from '@/components/shared/proxy-card';
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 { ClientTenanciesTab } from '@/components/clients/client-tenancies-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,
  historyPath,
}: {
  label: string;
  children: React.ReactNode;
  /** When set, renders a clock icon (if any override rows exist) that
   *  opens the field-history popover. The icon component renders nothing
   *  when the field has no history, so it's safe to pass on every row. */
  historyPath?: string;
}) {
  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 flex items-center gap-1">
        <div className="flex-1 min-w-0">{children}</div>
        {historyPath ? <FieldHistoryIcon fieldPath={historyPath} /> : null}
      </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;
      };
    }>;
    activeTenancies: 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 (
    <FieldHistoryProvider scope={{ type: 'client', id: clientId }}>
      <div className="space-y-6">
        <div className="rounded-xl border border-border bg-card p-4 shadow-sm">
          <ClientPipelineSummary clientId={clientId} variant="panel" />
        </div>

        {/* CM-9: point-of-contact (default level for the client). */}
        <ProxyCard entityType="client" entityId={clientId} />

        <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" historyPath="client.fullName">
                <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>
    </FieldHistoryProvider>
  );
}

export function getClientTabs({
  clientId,
  currentUserId,
  client,
  tenanciesModuleEnabled = false,
}: ClientTabsOptions & { tenanciesModuleEnabled?: boolean }): DetailTab[] {
  const tabs: DetailTab[] = [
    {
      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: '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}
          parentInvalidateKey={['clients', clientId]}
        />
      ),
    },
    {
      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."
        />
      ),
    },
  ];
  if (tenanciesModuleEnabled) {
    // Insert the Tenancies tab after Companies (index 4) so the entity
    // ordering reads: Overview → Interests → Yachts → Companies → Tenancies.
    tabs.splice(4, 0, {
      id: 'tenancies',
      label: 'Tenancies',
      badge: client.activeTenancies.length,
      content: <ClientTenanciesTab clientId={clientId} activeTenancies={client.activeTenancies} />,
    });
  }
  return tabs;
}
