'use client';

import Link from 'next/link';
import { useParams } from 'next/navigation';
import { format, formatDistanceToNowStrict } from 'date-fns';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { CheckCircle2, Circle, FileSignature, Plus, Send, Wallet } from 'lucide-react';

import type { DetailTab } from '@/components/shared/detail-layout';
import { Button } from '@/components/ui/button';
import { NotesList } from '@/components/shared/notes-list';
import { InlineEditableField } from '@/components/shared/inline-editable-field';
import { InlineTagEditor } from '@/components/shared/inline-tag-editor';
import { RecommendationList } from '@/components/interests/recommendation-list';
import { InterestTimeline } from '@/components/interests/interest-timeline';
import { InterestDocumentsTab } from '@/components/interests/interest-documents-tab';
import { InterestFilesTab } from '@/components/interests/interest-files-tab';
import { LEAD_CATEGORIES } from '@/lib/constants';
import { apiFetch } from '@/lib/api/client';
import { cn } from '@/lib/utils';

type InterestPatchField = 'leadCategory' | 'source' | 'notes';

const LEAD_CATEGORY_OPTIONS = LEAD_CATEGORIES.map((c) => ({
  value: c,
  label: c.replace(/_/g, ' ').replace(/\b\w/g, (m) => m.toUpperCase()),
}));

interface InterestTabsOptions {
  interestId: string;
  currentUserId?: string;
  interest: {
    leadCategory: string | null;
    source: string | null;
    eoiStatus: string | null;
    contractStatus: string | null;
    depositStatus: string | null;
    reservationStatus: string | null;
    dateFirstContact: string | null;
    dateLastContact: string | null;
    dateEoiSent: string | null;
    dateEoiSigned: string | null;
    dateContractSent: string | null;
    dateContractSigned: string | null;
    dateDepositReceived: string | null;
    reminderEnabled: boolean;
    reminderDays: number | null;
    reminderLastFired: string | null;
    notes: string | null;
    tags?: Array<{ id: string; name: string; color: string }>;
  };
}

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

function useStageMutation(interestId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: async ({ stage, reason }: { stage: string; reason?: string }) =>
      apiFetch(`/api/v1/interests/${interestId}/stage`, {
        method: 'PATCH',
        body: { pipelineStage: stage, reason },
      }),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['interests', interestId] });
      qc.invalidateQueries({ queryKey: ['interests'] });
    },
  });
}

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

function InfoRow({ label, value }: { label: string; value?: string | null }) {
  if (!value) return null;
  return (
    <div className="flex gap-2 py-1.5 border-b last:border-0">
      <dt className="w-44 shrink-0 text-sm text-muted-foreground">{label}</dt>
      <dd className="text-sm">{value}</dd>
    </div>
  );
}

function formatDate(date: string | null) {
  if (!date) return null;
  return format(new Date(date), 'MMM d, yyyy');
}

function relativeDate(date: string | null) {
  if (!date) return null;
  return `${formatDistanceToNowStrict(new Date(date))} ago`;
}

interface MilestoneSectionProps {
  title: string;
  icon: React.ComponentType<{ className?: string }>;
  /** Lifecycle for this milestone, in chronological order. */
  steps: Array<{
    label: string;
    date: string | null;
    /** Stage to advance to when the user clicks the action button for this step. */
    advanceStage?: string;
    /** Optional override for the action label. */
    actionLabel?: string;
  }>;
  status: string | null;
  onAdvance: (stage: string) => void;
  isPending: boolean;
  /** Extra nodes (e.g. "Create deposit invoice" link) rendered below the steps. */
  footer?: React.ReactNode;
}

/**
 * One milestone section (EOI / Deposit / Contract) — shows a vertical lifecycle
 * with completed steps checked, the next step exposing a quick "mark as…"
 * button that bumps the pipeline stage. Each stage flip auto-stamps its date
 * via the service layer (interests.service.ts). When external systems wire in
 * (Documenso webhook, paid invoice → deposit, etc.), they patch the same
 * stage endpoint and these checkmarks light up automatically.
 */
function MilestoneSection({
  title,
  icon: Icon,
  steps,
  status,
  onAdvance,
  isPending,
  footer,
}: MilestoneSectionProps) {
  const firstUnsetIdx = steps.findIndex((s) => !s.date);

  return (
    <section className="rounded-xl border border-border bg-card p-4 shadow-sm">
      <header className="mb-3 flex items-center justify-between gap-2">
        <div className="flex items-center gap-2">
          <Icon className="size-4 text-muted-foreground" />
          <h3 className="text-sm font-semibold tracking-tight text-foreground">{title}</h3>
        </div>
        {status ? (
          <span className="rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground">
            {status.replace(/_/g, ' ')}
          </span>
        ) : null}
      </header>

      <ol className="space-y-2">
        {steps.map((step, i) => {
          const done = !!step.date;
          const isNext = !done && i === firstUnsetIdx;
          return (
            <li key={step.label} className="flex items-start gap-2 text-sm">
              {done ? (
                <CheckCircle2 className="mt-0.5 size-4 shrink-0 text-emerald-600" />
              ) : (
                <Circle
                  className={cn(
                    'mt-0.5 size-4 shrink-0',
                    isNext ? 'text-foreground/60' : 'text-muted-foreground/40',
                  )}
                />
              )}
              <div className="min-w-0 flex-1">
                <div className="flex flex-wrap items-center gap-x-2 gap-y-0.5">
                  <span
                    className={cn(
                      'truncate',
                      done
                        ? 'text-foreground'
                        : isNext
                          ? 'text-foreground'
                          : 'text-muted-foreground',
                    )}
                  >
                    {step.label}
                  </span>
                  {step.date ? (
                    <span className="text-xs text-muted-foreground">
                      {formatDate(step.date)} · {relativeDate(step.date)}
                    </span>
                  ) : null}
                </div>
                {isNext && step.advanceStage ? (
                  <Button
                    type="button"
                    variant="outline"
                    size="sm"
                    disabled={isPending}
                    onClick={() => onAdvance(step.advanceStage!)}
                    className="mt-2 h-7 px-2.5 text-xs"
                  >
                    {step.actionLabel ?? `Mark as ${step.label.toLowerCase()}`}
                  </Button>
                ) : null}
              </div>
            </li>
          );
        })}
      </ol>
      {footer ? <div className="mt-3 border-t pt-3 text-xs">{footer}</div> : null}
    </section>
  );
}

function OverviewTab({
  interestId,
  interest,
}: {
  interestId: string;
  interest: InterestTabsOptions['interest'];
}) {
  const params = useParams<{ portSlug: string }>();
  const portSlug = params?.portSlug ?? '';
  const mutation = useInterestPatch(interestId);
  const stageMutation = useStageMutation(interestId);
  const save = (field: InterestPatchField) => async (next: string | null) => {
    await mutation.mutateAsync({ [field]: next });
  };
  const advance = (stage: string) =>
    stageMutation.mutate({ stage, reason: 'Marked from overview' });

  return (
    <div className="space-y-6">
      {/* Sales-process milestones — the heart of the system. Each section is a
          mini lifecycle that auto-completes as actions happen on the platform
          (Documenso webhook, paid deposit invoice, signed contract). Until the
          automation lands, salespeople nudge stages forward via the inline
          buttons here, which auto-stamp the milestone date server-side. */}
      <div className="grid grid-cols-1 gap-4 lg:grid-cols-3">
        <MilestoneSection
          title="EOI"
          icon={Send}
          status={interest.eoiStatus}
          isPending={stageMutation.isPending}
          onAdvance={advance}
          steps={[
            {
              label: 'EOI sent',
              date: interest.dateEoiSent,
              advanceStage: 'eoi_sent',
              actionLabel: 'Mark EOI as sent',
            },
            {
              label: 'EOI signed',
              date: interest.dateEoiSigned,
              advanceStage: 'eoi_signed',
              actionLabel: 'Mark EOI as signed',
            },
          ]}
        />
        <MilestoneSection
          title="Deposit"
          icon={Wallet}
          status={interest.depositStatus}
          isPending={stageMutation.isPending}
          onAdvance={advance}
          steps={[
            {
              label: 'Deposit received',
              date: interest.dateDepositReceived,
              advanceStage: 'deposit_10pct',
              actionLabel: 'Mark deposit received',
            },
          ]}
          footer={
            !interest.dateDepositReceived ? (
              <Link
                href={`/${portSlug}/invoices/new?interestId=${interestId}&kind=deposit`}
                className="inline-flex items-center gap-1.5 text-foreground/80 hover:text-foreground"
              >
                <Plus className="size-3.5" />
                Create deposit invoice
              </Link>
            ) : null
          }
        />
        <MilestoneSection
          title="Contract"
          icon={FileSignature}
          status={interest.contractStatus}
          isPending={stageMutation.isPending}
          onAdvance={advance}
          steps={[
            {
              label: 'Contract sent',
              date: interest.dateContractSent,
              advanceStage: 'contract_sent',
              actionLabel: 'Mark contract as sent',
            },
            {
              label: 'Contract signed',
              date: interest.dateContractSigned,
              advanceStage: 'contract_signed',
              actionLabel: 'Mark contract as signed',
            },
          ]}
        />
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
        {/* Lead & Source (editable) */}
        <div className="space-y-1">
          <h3 className="text-sm font-medium mb-2">Lead</h3>
          <dl>
            <EditableRow label="Lead Category">
              <InlineEditableField
                variant="select"
                options={LEAD_CATEGORY_OPTIONS}
                value={interest.leadCategory}
                onSave={save('leadCategory')}
              />
            </EditableRow>
            <EditableRow label="Source">
              <InlineEditableField value={interest.source} onSave={save('source')} />
            </EditableRow>
          </dl>
        </div>

        {/* Contact dates (read-only — kept compact next to Lead) */}
        <div className="space-y-1">
          <h3 className="text-sm font-medium mb-2">Contact</h3>
          <dl>
            <InfoRow label="First Contact" value={formatDate(interest.dateFirstContact)} />
            <InfoRow label="Last Contact" value={formatDate(interest.dateLastContact)} />
            {interest.reservationStatus ? (
              <InfoRow label="Reservation" value={interest.reservationStatus} />
            ) : null}
          </dl>
        </div>

        {/* Reminder */}
        {interest.reminderEnabled && (
          <div className="space-y-1">
            <h3 className="text-sm font-medium mb-2">Reminder</h3>
            <dl>
              <InfoRow
                label="Reminder Days"
                value={interest.reminderDays ? `${interest.reminderDays} days` : null}
              />
              <InfoRow label="Last Fired" value={formatDate(interest.reminderLastFired)} />
            </dl>
          </div>
        )}

        {/* Notes (editable, multiline) */}
        <div className="space-y-1 md:col-span-2">
          <h3 className="text-sm font-medium mb-2">Notes</h3>
          <InlineEditableField
            variant="textarea"
            value={interest.notes}
            onSave={save('notes')}
            emptyText="No notes — click to add"
          />
        </div>

        {/* Tags */}
        <div className="space-y-1 md:col-span-2">
          <h3 className="text-sm font-medium mb-2">Tags</h3>
          <InlineTagEditor
            endpoint={`/api/v1/interests/${interestId}/tags`}
            currentTags={interest.tags ?? []}
            invalidateKey={['interests', interestId]}
          />
        </div>
      </div>
    </div>
  );
}

export function getInterestTabs({
  interestId,
  currentUserId,
  interest,
}: InterestTabsOptions): DetailTab[] {
  return [
    {
      id: 'overview',
      label: 'Overview',
      content: <OverviewTab interestId={interestId} interest={interest} />,
    },
    {
      id: 'notes',
      label: 'Notes',
      content: (
        <NotesList entityType="interests" entityId={interestId} currentUserId={currentUserId} />
      ),
    },
    {
      id: 'documents',
      label: 'Documents',
      content: <InterestDocumentsTab interestId={interestId} />,
    },
    {
      id: 'files',
      label: 'Files',
      content: <InterestFilesTab interestId={interestId} />,
    },
    {
      id: 'recommendations',
      label: 'Recommendations',
      content: <RecommendationList interestId={interestId} />,
    },
    {
      id: 'activity',
      label: 'Activity',
      content: <InterestTimeline interestId={interestId} />,
    },
  ];
}
