'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 { SubdivisionCombobox } from '@/components/shared/subdivision-combobox';
import { InlineTagEditor } from '@/components/shared/inline-tag-editor';
import { NotesList } from '@/components/shared/notes-list';
import { EntityActivityFeed } from '@/components/shared/entity-activity-feed';
import { CompanyMembersTab } from '@/components/companies/company-members-tab';
import { CompanyOwnedYachtsTab } from '@/components/companies/company-owned-yachts-tab';
import { CompanyFilesTab } from '@/components/companies/company-files-tab';
import { AddressesEditor, type Address } from '@/components/shared/addresses-editor';
import { apiFetch } from '@/lib/api/client';
import type { CountryCode } from '@/lib/i18n/countries';

type CompanyPatchField =
  | 'name'
  | 'legalName'
  | 'taxId'
  | 'registrationNumber'
  | 'incorporationCountry'
  | 'incorporationCountryIso'
  | 'incorporationSubdivisionIso'
  | 'incorporationDate'
  | 'status'
  | 'billingEmail'
  | 'notes';

const STATUS_OPTIONS = [
  { value: 'active', label: 'Active' },
  { value: 'dissolved', label: 'Dissolved' },
];

interface CompanyTabsCompany {
  id: string;
  name: string;
  legalName: string | null;
  taxId: string | null;
  registrationNumber: string | null;
  incorporationCountryIso: string | null;
  incorporationSubdivisionIso: string | null;
  incorporationDate: string | null;
  status: string;
  billingEmail: string | null;
  notes: string | null;
  tags?: Array<{ id: string; name: string; color: string }>;
  addresses?: Address[];
  noteCount?: number;
}

interface CompanyTabsOptions {
  companyId: string;
  portSlug: string;
  currentUserId?: string;
  company: CompanyTabsCompany;
}

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

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

function OverviewTab({ companyId, company }: { companyId: string; company: CompanyTabsCompany }) {
  const mutation = useCompanyPatch(companyId);
  const save = (field: CompanyPatchField) => async (next: string | null) => {
    await mutation.mutateAsync({ [field]: next });
  };

  return (
    <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
      {/* Identity */}
      <div className="space-y-1">
        <h3 className="text-sm font-medium mb-2">Identity</h3>
        <dl>
          <EditableRow label="Name">
            <InlineEditableField value={company.name} onSave={save('name')} />
          </EditableRow>
          <EditableRow label="Legal Name">
            <InlineEditableField value={company.legalName} onSave={save('legalName')} />
          </EditableRow>
          <EditableRow label="Status">
            <InlineEditableField
              variant="select"
              options={STATUS_OPTIONS}
              value={company.status}
              onSave={save('status')}
            />
          </EditableRow>
        </dl>
      </div>

      {/* Registration */}
      <div className="space-y-1">
        <h3 className="text-sm font-medium mb-2">Registration</h3>
        <dl>
          <EditableRow label="Tax ID">
            <InlineEditableField value={company.taxId} onSave={save('taxId')} />
          </EditableRow>
          <EditableRow label="Registration Number">
            <InlineEditableField
              value={company.registrationNumber}
              onSave={save('registrationNumber')}
            />
          </EditableRow>
          <EditableRow label="Incorporation Country">
            <InlineCountryField
              value={company.incorporationCountryIso}
              onSave={async (iso) => {
                // Wipe subdivision when country flips - codes are country-scoped.
                await mutation.mutateAsync({
                  incorporationCountryIso: iso,
                  incorporationSubdivisionIso: null,
                });
              }}
              data-testid="company-incorp-country-inline"
            />
          </EditableRow>
          <EditableRow label="Incorporation Region">
            <SubdivisionCombobox
              value={company.incorporationSubdivisionIso}
              onChange={(code) => {
                void mutation.mutateAsync({ incorporationSubdivisionIso: code });
              }}
              country={(company.incorporationCountryIso as CountryCode | null) ?? null}
              data-testid="company-incorp-subdivision-inline"
            />
          </EditableRow>
          <EditableRow label="Incorporation Date">
            <InlineEditableField
              variant="date"
              // The API returns this as an ISO timestamp ("2019-03-14T00:00:00.000Z")
              // because Postgres `date` columns are serialized through JSON. Strip
              // the time portion so the read-only state shows just YYYY-MM-DD,
              // which is also the format the date input expects.
              value={company.incorporationDate ? company.incorporationDate.slice(0, 10) : null}
              max={new Date().toISOString().slice(0, 10)}
              onSave={save('incorporationDate')}
            />
          </EditableRow>
        </dl>
      </div>

      {/* Contact */}
      <div className="space-y-1">
        <h3 className="text-sm font-medium mb-2">Contact</h3>
        <dl>
          <EditableRow label="Billing Email">
            <InlineEditableField value={company.billingEmail} onSave={save('billingEmail')} />
          </EditableRow>
        </dl>
      </div>

      <InlineTagEditor
        heading="Tags"
        wrapperClassName="md:col-span-2"
        endpoint={`/api/v1/companies/${companyId}/tags`}
        currentTags={company.tags ?? []}
        invalidateKey={['companies', companyId]}
      />
    </div>
  );
}

export function getCompanyTabs({
  companyId,
  portSlug,
  currentUserId,
  company,
}: CompanyTabsOptions): DetailTab[] {
  return [
    {
      id: 'overview',
      label: 'Overview',
      content: <OverviewTab companyId={companyId} company={company} />,
    },
    {
      id: 'members',
      label: 'Contacts',
      content: <CompanyMembersTab companyId={companyId} portSlug={portSlug} />,
    },
    {
      id: 'owned-yachts',
      label: 'Owned Yachts',
      content: <CompanyOwnedYachtsTab companyId={companyId} portSlug={portSlug} />,
    },
    {
      id: 'addresses',
      label: 'Addresses',
      badge: company.addresses?.length ?? 0,
      content: (
        <AddressesEditor
          endpoint={`/api/v1/companies/${companyId}/addresses`}
          invalidateKey={['companies', companyId]}
          addresses={company.addresses ?? []}
        />
      ),
    },
    {
      id: 'documents',
      label: 'Documents',
      content: <CompanyFilesTab companyId={companyId} />,
    },
    {
      id: 'notes',
      label: 'Notes',
      badge: company.noteCount,
      content: (
        <NotesList
          aggregate
          entityType="companies"
          entityId={companyId}
          currentUserId={currentUserId}
          parentInvalidateKey={['companies', companyId]}
        />
      ),
    },
    {
      id: 'activity',
      label: 'Activity',
      content: (
        <EntityActivityFeed
          endpoint={`/api/v1/companies/${companyId}/activity`}
          emptyText="No activity recorded for this company yet."
        />
      ),
    },
  ];
}
