'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, Bell, Download, FileSignature, Mail, 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 { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { PageHeader } from '@/components/shared/page-header';
import { StatusPill, type StatusPillStatus } from '@/components/ui/status-pill';
import { EmptyState } from '@/components/ui/empty-state';
import { useRealtimeInvalidation } from '@/hooks/use-realtime-invalidation';
import { apiFetch } from '@/lib/api/client';
import { ClientLink, YachtLink, BerthLink } from '@/components/reservations/reservation-list';

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

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

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

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

interface EndReservationDialogProps {
  reservationId: string;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

function EndReservationDialog({ reservationId, open, onOpenChange }: EndReservationDialogProps) {
  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/berth-reservations/${reservationId}`, {
        method: 'PATCH',
        body: { action: 'end', endDate },
      });
      qc.invalidateQueries({ queryKey: ['reservation', reservationId] });
      toast.success('Reservation ended');
      onOpenChange(false);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to end reservation');
    } finally {
      setSubmitting(false);
    }
  }

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

interface ReservationDetailProps {
  reservationId: string;
  portSlug: string;
}

export function ReservationDetail({ reservationId, portSlug }: ReservationDetailProps) {
  const [endDialogOpen, setEndDialogOpen] = useState(false);
  const reservation = useQuery<{ data: ReservationData }>({
    queryKey: ['reservation', reservationId],
    queryFn: () => apiFetch(`/api/v1/berth-reservations/${reservationId}`),
  });

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

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

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

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

  const res = reservation.data.data;
  const docs = documentsForRes.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`}>
                  <Download className="mr-1.5 h-4 w-4" /> 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" /> View document
              </Link>
            </Button>
          </div>
          <p className="text-xs text-muted-foreground">
            Signed contract attached to this reservation.
          </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" /> 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) {
                  toast.error(err instanceof Error ? err.message : 'Failed');
                }
              }}
            >
              <Bell className="mr-1.5 h-4 w-4" /> Remind signers
            </Button>
          </div>
        </div>
      );
    }

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

  return (
    <div className="flex flex-col gap-4">
      <PageHeader
        eyebrow="Berth reservation"
        title={`Reservation #${res.id.slice(0, 8)}`}
        description={`${res.tenureType.replace(/_/g, ' ')} · ${new Date(res.startDate).toLocaleDateString('en-GB')}${res.endDate ? ` → ${new Date(res.endDate).toLocaleDateString('en-GB')}` : ''}`}
        kpiLine={
          <>
            <StatusPill status={RESERVATION_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">
            {res.status === 'active' && (
              <Button variant="outline" size="sm" onClick={() => setEndDialogOpen(true)}>
                <StopCircle className="mr-1.5 h-4 w-4" />
                End reservation
              </Button>
            )}
            <Button asChild variant="outline">
              <Link href={`/${portSlug}/berths`}>
                <ArrowLeft className="mr-1.5 h-4 w-4" /> Back to berths
              </Link>
            </Button>
          </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">
              Reservation 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>

      <EndReservationDialog
        reservationId={reservationId}
        open={endDialogOpen}
        onOpenChange={setEndDialogOpen}
      />
    </div>
  );
}
