'use client';

import { useState } from 'react';
import Link from 'next/link';
import type { Route } from 'next';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import {
  ArrowLeft,
  ArrowRightLeft,
  Bell,
  Download,
  FileSignature,
  Mail,
  Pencil,
  RefreshCw,
  StopCircle,
} from 'lucide-react';
import { toast } from 'sonner';

import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Label } from '@/components/ui/label';
import { DatePicker } from '@/components/ui/date-picker';
import { PageHeader } from '@/components/shared/page-header';
import { StatusPill, type StatusPillStatus } from '@/components/ui/status-pill';
import { EmptyState } from '@/components/ui/empty-state';
import { useBreadcrumbHint } from '@/hooks/use-breadcrumb-hint';
import { useRealtimeInvalidation } from '@/hooks/use-realtime-invalidation';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';
import { ClientLink, YachtLink, BerthLink } from '@/components/tenancies/tenancy-list';
import { TenancyEditDialog } from '@/components/tenancies/tenancy-edit-dialog';
import { TenancyRenewDialog } from '@/components/tenancies/tenancy-renew-dialog';
import { TenancyTransferDialog } from '@/components/tenancies/tenancy-transfer-dialog';

interface TenancyDoc {
  id: string;
  title: string;
  status: string;
  documentType: string;
  signedFileId: string | null;
  signers: Array<{ id: string; status: string; signerName: string }>;
}

interface TenancyData {
  id: string;
  status: string;
  startDate: string;
  endDate: string | null;
  tenureType: string;
  contractFileId: string | null;
  berthId: string;
  yachtId: string;
  clientId: string;
  notes: string | null;
}

const TENANCY_PILL: Record<string, StatusPillStatus> = {
  pending: 'pending',
  active: 'active',
  ended: 'archived',
  cancelled: 'cancelled',
};

function todayIso(): string {
  return new Date().toISOString().slice(0, 10);
}

interface EndTenancyDialogProps {
  tenancyId: string;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

function EndTenancyDialog({ tenancyId, open, onOpenChange }: EndTenancyDialogProps) {
  const qc = useQueryClient();
  const [endDate, setEndDate] = useState(todayIso);
  const [submitting, setSubmitting] = useState(false);

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setSubmitting(true);
    try {
      await apiFetch(`/api/v1/tenancies/${tenancyId}`, {
        method: 'PATCH',
        body: { action: 'end', endDate },
      });
      qc.invalidateQueries({ queryKey: ['tenancy', tenancyId] });
      toast.success('Tenancy ended');
      onOpenChange(false);
    } catch (err) {
      toastError(err);
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-sm">
        <DialogHeader>
          <DialogTitle>End tenancy</DialogTitle>
        </DialogHeader>
        <form onSubmit={handleSubmit} className="space-y-4 pt-2">
          <div className="space-y-1.5">
            <Label htmlFor="end-date">End date</Label>
            <DatePicker id="end-date" value={endDate} onChange={setEndDate} />
          </div>
          <DialogFooter>
            <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
              Cancel
            </Button>
            <Button type="submit" variant="destructive" disabled={submitting}>
              {submitting ? 'Ending…' : 'End tenancy'}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}

interface TenancyDetailProps {
  tenancyId: string;
  portSlug: string;
}

export function TenancyDetail({ tenancyId, portSlug }: TenancyDetailProps) {
  const [endDialogOpen, setEndDialogOpen] = useState(false);
  const [editDialogOpen, setEditDialogOpen] = useState(false);
  const [renewDialogOpen, setRenewDialogOpen] = useState(false);
  const [transferDialogOpen, setTransferDialogOpen] = useState(false);
  // Smart-back target: tenancies are reached via berths in this UI -
  // sending the user back to /berths matches the navigation they took
  // to get here, rather than the generic /tenancies list.
  useBreadcrumbHint({
    parents: [{ label: 'Berths', href: `/${portSlug}/berths` }],
    current: 'Tenancy',
  });
  const tenancy = useQuery<{ data: TenancyData }>({
    queryKey: ['tenancy', tenancyId],
    queryFn: () => apiFetch(`/api/v1/tenancies/${tenancyId}`),
  });

  const documentsForTenancy = useQuery<{ data: TenancyDoc[] }>({
    queryKey: ['documents', 'by-tenancy', tenancyId],
    queryFn: () =>
      apiFetch(
        `/api/v1/documents?documentType=reservation_agreement&signatureOnly=true&limit=10`,
      ).then((res) => {
        const r = res as { data: TenancyDoc[] & Array<{ tenancyId?: string }> };
        return {
          data: r.data.filter(
            (d: TenancyDoc & { tenancyId?: string }) => d.tenancyId === tenancyId,
          ),
        } as { data: TenancyDoc[] };
      }),
  });

  useRealtimeInvalidation({
    'document:created': [['documents', 'by-tenancy', tenancyId]],
    'document:completed': [
      ['documents', 'by-tenancy', tenancyId],
      ['tenancy', tenancyId],
    ],
    'document:cancelled': [['documents', 'by-tenancy', tenancyId]],
  });

  if (tenancy.isLoading) {
    return <div className="h-32 animate-pulse rounded-md bg-muted/40" />;
  }

  if (tenancy.error || !tenancy.data) {
    return (
      <PageHeader
        title="Tenancy not found"
        actions={
          <Button asChild variant="outline">
            <Link href={`/${portSlug}/berths`}>
              <ArrowLeft className="mr-1.5 h-4 w-4" aria-hidden /> Back
            </Link>
          </Button>
        }
      />
    );
  }

  const res = tenancy.data.data;
  const docs = documentsForTenancy.data?.data ?? [];
  const activeAgreement = docs.find((d) => ['sent', 'partially_signed'].includes(d.status));
  const completedAgreement = docs.find((d) => ['completed', 'signed'].includes(d.status));

  const renderAgreementCard = (): React.ReactNode => {
    if (completedAgreement) {
      return (
        <div className="flex flex-col gap-3 rounded-md border bg-success-bg/50 p-4">
          <div className="flex items-start justify-between gap-2">
            <div>
              <h3 className="text-sm font-semibold text-foreground">Agreement signed</h3>
              <p className="mt-1 text-xs text-muted-foreground">{completedAgreement.title}</p>
            </div>
            <StatusPill status="completed" withDot>
              Completed
            </StatusPill>
          </div>
          <div className="flex flex-wrap items-center gap-2">
            {completedAgreement.signedFileId ? (
              <Button asChild size="sm" variant="outline">
                <Link href={`/api/v1/files/${completedAgreement.signedFileId}/download?redirect=1`}>
                  <Download className="mr-1.5 h-4 w-4" aria-hidden /> Download signed PDF
                </Link>
              </Button>
            ) : null}
            <Button asChild size="sm" variant="outline">
              <Link href={`/${portSlug}/documents/${completedAgreement.id}`}>
                <Mail className="mr-1.5 h-4 w-4" aria-hidden /> View document
              </Link>
            </Button>
          </div>
          <p className="text-xs text-muted-foreground">Signed contract attached to this tenancy.</p>
        </div>
      );
    }

    if (activeAgreement) {
      const signedCount = activeAgreement.signers.filter((s) => s.status === 'signed').length;
      return (
        <div className="flex flex-col gap-3 rounded-md border bg-brand-50 p-4">
          <div className="flex items-start justify-between gap-2">
            <div>
              <h3 className="text-sm font-semibold text-foreground">Agreement out for signing</h3>
              <p className="mt-1 text-xs text-muted-foreground">
                {signedCount}/{activeAgreement.signers.length} signed · {activeAgreement.title}
              </p>
            </div>
            <StatusPill
              status={activeAgreement.status === 'partially_signed' ? 'partial' : 'sent'}
              withDot
            >
              {activeAgreement.status.replace(/_/g, ' ')}
            </StatusPill>
          </div>
          <div className="flex flex-wrap items-center gap-2">
            <Button asChild size="sm">
              <Link href={`/${portSlug}/documents/${activeAgreement.id}`}>
                <FileSignature className="mr-1.5 h-4 w-4" aria-hidden /> View document
              </Link>
            </Button>
            <Button
              size="sm"
              variant="outline"
              onClick={async () => {
                try {
                  await apiFetch(`/api/v1/documents/${activeAgreement.id}/remind`, {
                    method: 'POST',
                  });
                  toast.success('Reminder sent');
                } catch (err) {
                  toastError(err);
                }
              }}
            >
              <Bell className="mr-1.5 h-4 w-4" aria-hidden /> Remind signers
            </Button>
          </div>
        </div>
      );
    }

    return (
      <EmptyState
        icon={<FileSignature className="h-7 w-7" aria-hidden />}
        title="No tenancy agreement yet"
        body="Generate an agreement for the parties to sign before activation."
        actions={
          <Button asChild>
            <Link
              href={
                `/${portSlug}/documents/new?tenancyId=${tenancyId}&documentType=reservation_agreement` as Route
              }
            >
              Generate agreement
            </Link>
          </Button>
        }
      />
    );
  };

  return (
    <div className="flex flex-col gap-4">
      <PageHeader
        eyebrow="Berth tenancy"
        title={`Tenancy #${res.id.slice(0, 8)}`}
        description={`${res.tenureType.replace(/_/g, ' ')} · ${new Date(res.startDate).toLocaleDateString(undefined)}${res.endDate ? ` → ${new Date(res.endDate).toLocaleDateString(undefined)}` : ''}`}
        kpiLine={
          <>
            <StatusPill status={TENANCY_PILL[res.status] ?? 'pending'} withDot>
              {res.status}
            </StatusPill>
            {res.contractFileId ? <span>Contract attached</span> : <span>No contract</span>}
          </>
        }
        actions={
          <div className="flex items-center gap-2">
            <Button variant="outline" size="sm" onClick={() => setEditDialogOpen(true)}>
              <Pencil className="mr-1.5 h-4 w-4" aria-hidden />
              Edit
            </Button>
            {res.status === 'active' && (
              <>
                <Button variant="outline" size="sm" onClick={() => setRenewDialogOpen(true)}>
                  <RefreshCw className="mr-1.5 h-4 w-4" aria-hidden />
                  Renew
                </Button>
                <Button variant="outline" size="sm" onClick={() => setTransferDialogOpen(true)}>
                  <ArrowRightLeft className="mr-1.5 h-4 w-4" aria-hidden />
                  Transfer
                </Button>
                <Button variant="outline" size="sm" onClick={() => setEndDialogOpen(true)}>
                  <StopCircle className="mr-1.5 h-4 w-4" aria-hidden />
                  End tenancy
                </Button>
              </>
            )}
            {/* Topbar smart-back covers "Back to Berths" via the
                useBreadcrumbHint registration above; no duplicate
                action-bar button needed. */}
          </div>
        }
        variant="gradient"
      />

      <div className="grid gap-4 lg:grid-cols-[2fr_1fr]">
        <div className="flex flex-col gap-4">
          <section className="rounded-md border bg-white p-4">
            <h2 className="mb-2 text-sm font-semibold uppercase tracking-wide text-muted-foreground">
              Tenancy details
            </h2>
            <dl className="grid grid-cols-2 gap-3 text-sm">
              <div>
                <dt className="text-xs text-muted-foreground">Berth</dt>
                <dd className="font-medium">
                  <BerthLink berthId={res.berthId} portSlug={portSlug} />
                </dd>
              </div>
              <div>
                <dt className="text-xs text-muted-foreground">Yacht</dt>
                <dd className="font-medium">
                  <YachtLink yachtId={res.yachtId} portSlug={portSlug} />
                </dd>
              </div>
              <div>
                <dt className="text-xs text-muted-foreground">Client</dt>
                <dd className="font-medium">
                  <ClientLink clientId={res.clientId} portSlug={portSlug} />
                </dd>
              </div>
              <div>
                <dt className="text-xs text-muted-foreground">Tenure</dt>
                <dd className="font-medium">{res.tenureType.replace(/_/g, ' ')}</dd>
              </div>
            </dl>
            {res.notes ? (
              <div className="mt-3 border-t pt-3 text-sm">
                <div className="text-xs text-muted-foreground">Notes</div>
                <p className="mt-1 text-foreground whitespace-pre-wrap">{res.notes}</p>
              </div>
            ) : null}
          </section>
        </div>

        <div className="flex flex-col gap-4">
          <section className="rounded-md border bg-white p-4">
            <h2 className="mb-3 text-sm font-semibold uppercase tracking-wide text-muted-foreground">
              Agreement
            </h2>
            {renderAgreementCard()}
          </section>
        </div>
      </div>

      <EndTenancyDialog
        tenancyId={tenancyId}
        open={endDialogOpen}
        onOpenChange={setEndDialogOpen}
      />
      <TenancyEditDialog
        tenancyId={tenancyId}
        open={editDialogOpen}
        onOpenChange={setEditDialogOpen}
        initialStartDate={res.startDate}
        initialEndDate={res.endDate}
        initialTenureType={res.tenureType}
        initialNotes={res.notes}
      />
      <TenancyRenewDialog
        tenancyId={tenancyId}
        open={renewDialogOpen}
        onOpenChange={setRenewDialogOpen}
        tenureType={res.tenureType}
        currentEndDate={res.endDate}
      />
      <TenancyTransferDialog
        tenancyId={tenancyId}
        open={transferDialogOpen}
        onOpenChange={setTransferDialogOpen}
      />
    </div>
  );
}
