'use client';

import { useState } from 'react';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { ArrowLeft, Plus, Trash2 } from 'lucide-react';
import { toast } from 'sonner';

import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { PageHeader } from '@/components/shared/page-header';
import { ClientPicker } from '@/components/shared/client-picker';
import { CompanyPicker } from '@/components/companies/company-picker';
import { YachtPicker } from '@/components/yachts/yacht-picker';
import { InterestPicker } from '@/components/interests/interest-picker';
import { DocumentTemplatePicker } from '@/components/documents/document-template-picker';
import { FileUploadZone } from '@/components/files/file-upload-zone';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';
import { DOCUMENT_TYPES } from '@/lib/constants';

// Display labels for SIGNER_ROLES — internal values stay lowercase, UI shows
// capitalized. Falls back to capitalize-first-letter for any value not in the
// explicit map.
const SIGNER_ROLE_LABELS: Record<string, string> = {
  client: 'Client',
  sales: 'Sales',
  approver: 'Approver',
  developer: 'Developer',
  other: 'Other',
};
function formatSignerRole(r: string): string {
  return SIGNER_ROLE_LABELS[r] ?? r.charAt(0).toUpperCase() + r.slice(1);
}

const SIGNER_ROLES = ['client', 'sales', 'approver', 'developer', 'other'] as const;

const SUBJECT_TYPES = [
  { key: 'interest', label: 'Interest', field: 'interestId' as const },
  { key: 'reservation', label: 'Reservation', field: 'reservationId' as const },
  { key: 'client', label: 'Client', field: 'clientId' as const },
  { key: 'company', label: 'Company', field: 'companyId' as const },
  { key: 'yacht', label: 'Yacht', field: 'yachtId' as const },
] as const;

interface SignerRow {
  signerName: string;
  signerEmail: string;
  signerRole: (typeof SIGNER_ROLES)[number];
  signingOrder: number;
}

interface CreateDocumentWizardProps {
  portSlug: string;
}

export function CreateDocumentWizard({ portSlug }: CreateDocumentWizardProps) {
  const router = useRouter();

  const [source, setSource] = useState<'template' | 'upload'>('template');
  const [pathway, setPathway] = useState<'documenso-template' | 'inapp' | 'upload'>(
    'documenso-template',
  );
  const [templateId, setTemplateId] = useState('');
  const [uploadedFileId, setUploadedFileId] = useState('');
  const [documentType, setDocumentType] = useState<(typeof DOCUMENT_TYPES)[number]>('eoi');
  const [title, setTitle] = useState('');
  const [notes, setNotes] = useState('');

  const [subjectType, setSubjectType] = useState<(typeof SUBJECT_TYPES)[number]['key']>('interest');
  const [subjectId, setSubjectId] = useState('');

  const [signers, setSigners] = useState<SignerRow[]>([
    { signerName: '', signerEmail: '', signerRole: 'client', signingOrder: 1 },
  ]);
  const [signingMode, setSigningMode] = useState<'sequential' | 'parallel'>('sequential');

  const [reminderMode, setReminderMode] = useState<'default' | 'override' | 'disabled'>('default');
  const [reminderDays, setReminderDays] = useState(7);

  const [submitting, setSubmitting] = useState(false);

  const subjectField = SUBJECT_TYPES.find((s) => s.key === subjectType)!.field;

  const setSourceAndPathway = (next: 'template' | 'upload'): void => {
    setSource(next);
    if (next === 'upload') {
      setPathway('upload');
    } else if (pathway === 'upload') {
      setPathway('documenso-template');
    }
  };

  const updateSigner = (idx: number, patch: Partial<SignerRow>): void => {
    setSigners((current) => current.map((s, i) => (i === idx ? { ...s, ...patch } : s)));
  };

  const addSigner = (): void => {
    setSigners((current) => [
      ...current,
      {
        signerName: '',
        signerEmail: '',
        signerRole: 'other',
        signingOrder: current.length + 1,
      },
    ]);
  };

  const removeSigner = (idx: number): void => {
    setSigners((current) =>
      current.filter((_, i) => i !== idx).map((s, i) => ({ ...s, signingOrder: i + 1 })),
    );
  };

  const handleSubmit = async (): Promise<void> => {
    if (!title.trim()) {
      toast.error('Title is required');
      return;
    }
    if (!subjectId.trim()) {
      toast.error(`Provide a ${subjectType} id`);
      return;
    }
    if (source === 'template' && !templateId.trim()) {
      toast.error('Pick a template');
      return;
    }
    if (source === 'upload' && !uploadedFileId.trim()) {
      toast.error('Provide an uploaded file id');
      return;
    }
    const cleanSigners = signers.filter((s) => s.signerEmail.trim() && s.signerName.trim());
    if (source === 'upload' && cleanSigners.length === 0) {
      toast.error('Upload path requires at least one signer');
      return;
    }

    setSubmitting(true);
    try {
      const body: Record<string, unknown> = {
        source,
        pathway,
        documentType,
        title: title.trim(),
        notes: notes.trim() || undefined,
        [subjectField]: subjectId.trim(),
        signingMode,
        watchers: [],
        autoPlaceFields: true,
        sendImmediately: false,
        remindersDisabled: reminderMode === 'disabled',
      };

      if (source === 'template') body.templateId = templateId.trim();
      if (source === 'upload') {
        body.uploadedFileId = uploadedFileId.trim();
        body.signers = cleanSigners;
      } else if (cleanSigners.length > 0) {
        body.signers = cleanSigners;
      }

      if (reminderMode === 'override') {
        body.reminderCadenceOverride = reminderDays;
      }

      const res = await apiFetch<{ data: { id: string } }>('/api/v1/documents/wizard', {
        method: 'POST',
        body,
      });
      toast.success('Document created');
      router.push(`/${portSlug}/documents/${res.data.id}`);
    } catch (err) {
      toastError(err);
      setSubmitting(false);
    }
  };

  return (
    <div className="flex flex-col gap-4">
      <PageHeader
        title="New document"
        description="Generate, attach, and send a document for signing."
        actions={
          <Button asChild variant="outline">
            <Link href={`/${portSlug}/documents`}>
              <ArrowLeft className="mr-1.5 h-4 w-4" /> Back
            </Link>
          </Button>
        }
      />

      <div className="grid gap-4 lg:grid-cols-2">
        <section className="rounded-md border bg-white p-4">
          <h2 className="mb-3 text-sm font-semibold uppercase tracking-wide text-muted-foreground">
            Source
          </h2>
          <div className="flex flex-col gap-3 text-sm">
            <label className="flex items-center gap-2">
              <input
                type="radio"
                checked={source === 'template'}
                onChange={() => setSourceAndPathway('template')}
              />
              <span>Generate from a template</span>
            </label>
            <label className="flex items-center gap-2">
              <input
                type="radio"
                checked={source === 'upload'}
                onChange={() => setSourceAndPathway('upload')}
              />
              <span>Upload a finished PDF</span>
            </label>

            {source === 'template' ? (
              <>
                <div className="mt-2 flex flex-col gap-2">
                  <Label className="text-xs">Pathway</Label>
                  <Select value={pathway} onValueChange={(v) => setPathway(v as typeof pathway)}>
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="documenso-template">
                        Generated EOI — rendered + signed externally
                      </SelectItem>
                      <SelectItem value="inapp">
                        Manual EOI — rendered in CRM, sent for e-signature
                      </SelectItem>
                    </SelectContent>
                  </Select>
                </div>
                <div className="flex flex-col gap-2">
                  <Label className="text-xs">Template</Label>
                  <DocumentTemplatePicker
                    value={templateId || null}
                    onChange={(id) => setTemplateId(id ?? '')}
                  />
                </div>
              </>
            ) : (
              <div className="flex flex-col gap-2">
                <Label className="text-xs">Upload PDF</Label>
                {uploadedFileId ? (
                  <div className="flex items-center justify-between rounded-md border bg-muted/30 px-3 py-2 text-xs">
                    <span className="truncate">File ready (id: {uploadedFileId.slice(0, 8)}…)</span>
                    <button
                      type="button"
                      onClick={() => setUploadedFileId('')}
                      className="text-muted-foreground hover:text-destructive"
                    >
                      Clear
                    </button>
                  </div>
                ) : (
                  <FileUploadZone
                    onUploadComplete={(file) => {
                      if (file?.id) setUploadedFileId(file.id);
                    }}
                  />
                )}
                <p className="text-xs text-muted-foreground">
                  Drop a PDF or click to browse. The file is stored, then the wizard wires it as the
                  source for signing.
                </p>
              </div>
            )}
          </div>
        </section>

        <section className="rounded-md border bg-white p-4">
          <h2 className="mb-3 text-sm font-semibold uppercase tracking-wide text-muted-foreground">
            Document
          </h2>
          <div className="flex flex-col gap-3 text-sm">
            <div className="flex flex-col gap-2">
              <Label className="text-xs">Type</Label>
              <Select
                value={documentType}
                onValueChange={(v) => setDocumentType(v as typeof documentType)}
              >
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {DOCUMENT_TYPES.map((t) => (
                    <SelectItem key={t} value={t}>
                      {t.replace(/_/g, ' ')}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="flex flex-col gap-2">
              <Label className="text-xs">Title</Label>
              <Input value={title} onChange={(e) => setTitle(e.target.value)} />
            </div>
            <div className="flex flex-col gap-2">
              <Label className="text-xs">Internal notes</Label>
              <Input value={notes} onChange={(e) => setNotes(e.target.value)} />
            </div>
            <div className="grid grid-cols-[max-content_1fr] gap-2">
              <Select
                value={subjectType}
                onValueChange={(v) => {
                  setSubjectType(v as typeof subjectType);
                  // Reset subject id when the type changes — pickers are
                  // type-specific and old ids belong to the wrong table.
                  setSubjectId('');
                }}
              >
                <SelectTrigger className="h-9 w-32">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {SUBJECT_TYPES.map((s) => (
                    <SelectItem key={s.key} value={s.key}>
                      {s.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              {subjectType === 'client' ? (
                <ClientPicker value={subjectId || null} onChange={(id) => setSubjectId(id ?? '')} />
              ) : subjectType === 'company' ? (
                <CompanyPicker
                  value={subjectId || null}
                  onChange={(id) => setSubjectId(id ?? '')}
                />
              ) : subjectType === 'yacht' ? (
                <YachtPicker value={subjectId || null} onChange={(id) => setSubjectId(id ?? '')} />
              ) : subjectType === 'interest' ? (
                <InterestPicker
                  value={subjectId || null}
                  onChange={(id) => setSubjectId(id ?? '')}
                />
              ) : (
                <Input
                  value={subjectId}
                  onChange={(e) => setSubjectId(e.target.value)}
                  placeholder="Reservation id"
                />
              )}
            </div>
          </div>
        </section>

        <section className="rounded-md border bg-white p-4 lg:col-span-2">
          <div className="mb-3 flex items-center justify-between">
            <h2 className="text-sm font-semibold uppercase tracking-wide text-muted-foreground">
              Signers
            </h2>
            <Button size="sm" variant="outline" onClick={addSigner}>
              <Plus className="mr-1.5 h-3.5 w-3.5" /> Add signer
            </Button>
          </div>
          <ul className="space-y-2">
            {signers.map((s, idx) => (
              <li
                key={idx}
                className="grid grid-cols-[2.5rem_1fr_1fr_8rem_2rem] items-center gap-2 text-sm"
              >
                <span className="text-xs tabular-nums text-muted-foreground">
                  #{s.signingOrder}
                </span>
                <Input
                  value={s.signerName}
                  onChange={(e) => updateSigner(idx, { signerName: e.target.value })}
                  placeholder="Name"
                />
                <Input
                  value={s.signerEmail}
                  onChange={(e) => updateSigner(idx, { signerEmail: e.target.value })}
                  placeholder="Email"
                />
                <Select
                  value={s.signerRole}
                  onValueChange={(v) =>
                    updateSigner(idx, { signerRole: v as SignerRow['signerRole'] })
                  }
                >
                  <SelectTrigger className="h-9">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {SIGNER_ROLES.map((r) => (
                      <SelectItem key={r} value={r}>
                        {formatSignerRole(r)}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <button
                  type="button"
                  aria-label="Remove signer"
                  onClick={() => removeSigner(idx)}
                  className="text-muted-foreground hover:text-destructive"
                >
                  <Trash2 className="h-3.5 w-3.5" />
                </button>
              </li>
            ))}
          </ul>
          <div className="mt-3 flex items-center gap-3 text-xs text-muted-foreground">
            <Label className="text-xs">Signing mode</Label>
            <Select
              value={signingMode}
              onValueChange={(v) => setSigningMode(v as typeof signingMode)}
            >
              <SelectTrigger className="w-40">
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="sequential">Sequential</SelectItem>
                <SelectItem value="parallel">Parallel</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </section>

        <section className="rounded-md border bg-white p-4 lg:col-span-2">
          <h2 className="mb-3 text-sm font-semibold uppercase tracking-wide text-muted-foreground">
            Reminders
          </h2>
          <div className="flex flex-col gap-2 text-sm">
            <label className="flex items-center gap-2">
              <input
                type="radio"
                checked={reminderMode === 'default'}
                onChange={() => setReminderMode('default')}
              />
              Use template default
            </label>
            <label className="flex items-center gap-2">
              <input
                type="radio"
                checked={reminderMode === 'override'}
                onChange={() => setReminderMode('override')}
              />
              Override:
              <Input
                type="number"
                className="ml-1 w-20"
                min={1}
                max={365}
                value={reminderDays}
                onChange={(e) => setReminderDays(Number(e.target.value))}
                onFocus={() => setReminderMode('override')}
              />
              days
            </label>
            <label className="flex items-center gap-2">
              <input
                type="radio"
                checked={reminderMode === 'disabled'}
                onChange={() => setReminderMode('disabled')}
              />
              Disable reminders for this document
            </label>
          </div>
        </section>
      </div>

      <div className="flex items-center justify-end gap-2">
        <Button variant="outline" asChild>
          <Link href={`/${portSlug}/documents`}>Cancel</Link>
        </Button>
        <Button onClick={handleSubmit} disabled={submitting}>
          {submitting ? 'Creating…' : 'Create document'}
        </Button>
      </div>
    </div>
  );
}
