'use client';

import { useState } from 'react';
import Link from 'next/link';
import type { Route } from 'next';
import { useRouter } from 'next/navigation';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { ArrowLeft, Bell, Download, Mail, Trash2, X } from 'lucide-react';
import { toast } from 'sonner';

import { Button } from '@/components/ui/button';
import { PageHeader } from '@/components/shared/page-header';
import { StatusPill, type StatusPillStatus } from '@/components/ui/status-pill';
import { useRealtimeInvalidation } from '@/hooks/use-realtime-invalidation';
import { apiFetch } from '@/lib/api/client';

interface DetailDoc {
  id: string;
  title: string;
  status: string;
  documentType: string;
  documensoId: string | null;
  signedFileId: string | null;
  reservationId: string | null;
  interestId: string | null;
  clientId: string | null;
  yachtId: string | null;
  companyId: string | null;
  createdAt: string;
  createdBy: string;
}

interface DetailSigner {
  id: string;
  signerName: string;
  signerEmail: string;
  signerRole: string;
  signingOrder: number;
  status: string;
  signedAt: string | null;
  signingUrl: string | null;
}

interface DetailEvent {
  id: string;
  eventType: string;
  createdAt: string;
  signerId: string | null;
  eventData: Record<string, unknown> | null;
}

interface DetailWatcher {
  userId: string;
  addedBy: string;
  addedAt: string;
}

interface DetailResponse {
  data: {
    document: DetailDoc;
    signers: DetailSigner[];
    events: DetailEvent[];
    watchers: DetailWatcher[];
  };
}

const STATUS_PILL_MAP: Record<string, StatusPillStatus> = {
  draft: 'draft',
  sent: 'sent',
  partially_signed: 'partial',
  completed: 'completed',
  signed: 'signed',
  expired: 'expired',
  cancelled: 'cancelled',
  rejected: 'rejected',
  pending: 'pending',
  declined: 'declined',
};

const SIGNER_PILL_MAP: Record<string, StatusPillStatus> = {
  pending: 'pending',
  signed: 'signed',
  declined: 'declined',
};

interface DocumentDetailProps {
  documentId: string;
  portSlug: string;
}

export function DocumentDetail({ documentId, portSlug }: DocumentDetailProps) {
  const router = useRouter();
  const queryClient = useQueryClient();
  const [isCancelling, setIsCancelling] = useState(false);

  const { data, isLoading, error } = useQuery<DetailResponse>({
    queryKey: ['document-detail', documentId],
    queryFn: () => apiFetch<DetailResponse>(`/api/v1/documents/${documentId}?detail=true`),
  });

  useRealtimeInvalidation({
    'document:updated': [['document-detail', documentId]],
    'document:sent': [['document-detail', documentId]],
    'document:completed': [['document-detail', documentId]],
    'document:cancelled': [['document-detail', documentId]],
    'document:rejected': [['document-detail', documentId]],
    'document:expired': [['document-detail', documentId]],
    'document:signer:signed': [['document-detail', documentId]],
    'document:signer:opened': [['document-detail', documentId]],
  });

  if (isLoading) {
    return (
      <div className="flex flex-col gap-4">
        <div className="h-24 animate-pulse rounded-xl bg-muted/40" />
        <div className="grid gap-4 lg:grid-cols-[2fr_1fr]">
          <div className="h-64 animate-pulse rounded-md bg-muted/40" />
          <div className="h-64 animate-pulse rounded-md bg-muted/40" />
        </div>
      </div>
    );
  }

  if (error || !data) {
    return (
      <div className="flex flex-col gap-4">
        <PageHeader
          title="Document not found"
          description="This document was deleted or you don't have access to it."
          actions={
            <Button asChild variant="outline">
              <Link href={`/${portSlug}/documents`}>
                <ArrowLeft className="mr-1.5 h-4 w-4" />
                Back to documents
              </Link>
            </Button>
          }
        />
      </div>
    );
  }

  const { document: doc, signers, events, watchers } = data.data;

  const handleRemind = async (signerId: string) => {
    try {
      await apiFetch(`/api/v1/documents/${documentId}/remind`, {
        method: 'POST',
        body: { signerId },
      });
      toast.success('Reminder sent');
      queryClient.invalidateQueries({ queryKey: ['document-detail', documentId] });
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to send reminder');
    }
  };

  const handleCancel = async () => {
    if (!confirm('Cancel this document? This voids it in Documenso and cannot be undone.')) return;
    setIsCancelling(true);
    try {
      await apiFetch(`/api/v1/documents/${documentId}/cancel`, { method: 'POST' });
      toast.success('Document cancelled');
      router.push(`/${portSlug}/documents`);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Cancel failed');
      setIsCancelling(false);
    }
  };

  const handleEmailSignedPdf = async () => {
    try {
      const draft = await apiFetch<{
        data: { to: string[]; subject: string; attachments: Array<{ fileId: string }> };
      }>(`/api/v1/documents/${documentId}/compose-completion-email`, { method: 'POST' });
      toast.info(
        `Email composer prepared for ${draft.data.to.length} signer${draft.data.to.length === 1 ? '' : 's'} — opens in PR8 wizard`,
      );
    } catch (err) {
      toast.error(err instanceof Error ? err.message : 'Failed to prepare email');
    }
  };

  const isInFlight = ['sent', 'partially_signed'].includes(doc.status);
  const isComplete = ['completed', 'signed'].includes(doc.status);

  const subjectLink = doc.reservationId
    ? { href: `/${portSlug}/berth-reservations/${doc.reservationId}`, label: 'Reservation' }
    : doc.interestId
      ? { href: `/${portSlug}/interests/${doc.interestId}`, label: 'Interest' }
      : doc.clientId
        ? { href: `/${portSlug}/clients/${doc.clientId}`, label: 'Client' }
        : doc.yachtId
          ? { href: `/${portSlug}/yachts/${doc.yachtId}`, label: 'Yacht' }
          : doc.companyId
            ? { href: `/${portSlug}/companies/${doc.companyId}`, label: 'Company' }
            : null;

  return (
    <div className="flex flex-col gap-4">
      <PageHeader
        eyebrow={doc.documentType.replace(/_/g, ' ')}
        title={doc.title}
        description={`Created ${new Date(doc.createdAt).toLocaleDateString('en-GB')}`}
        kpiLine={
          <>
            <StatusPill status={STATUS_PILL_MAP[doc.status] ?? 'pending'} withDot>
              {doc.status.replace(/_/g, ' ')}
            </StatusPill>
            <span>
              {signers.filter((s) => s.status === 'signed').length}/{signers.length} signed
            </span>
            {watchers.length > 0 ? <span>{watchers.length} watching</span> : null}
          </>
        }
        actions={
          <div className="flex items-center gap-2">
            <Button asChild variant="outline" size="sm">
              <Link href={`/${portSlug}/documents`}>
                <ArrowLeft className="mr-1.5 h-4 w-4" /> Back
              </Link>
            </Button>
            {isComplete && doc.signedFileId ? (
              <>
                <Button asChild size="sm">
                  <Link href={`/api/v1/files/${doc.signedFileId}/download`}>
                    <Download className="mr-1.5 h-4 w-4" /> Download signed PDF
                  </Link>
                </Button>
                <Button size="sm" variant="outline" onClick={handleEmailSignedPdf}>
                  <Mail className="mr-1.5 h-4 w-4" /> Email signatories
                </Button>
              </>
            ) : null}
            {isInFlight ? (
              <Button size="sm" variant="outline" onClick={handleCancel} disabled={isCancelling}>
                <X className="mr-1.5 h-4 w-4" /> Cancel
              </Button>
            ) : null}
          </div>
        }
        variant="gradient"
      />

      <div className="grid gap-4 lg:grid-cols-[2fr_1fr]">
        {/* Left column */}
        <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">
              Signers
            </h2>
            {signers.length === 0 ? (
              <p className="text-sm text-muted-foreground">No signers attached.</p>
            ) : (
              <ul className="space-y-3">
                {signers.map((signer, idx) => (
                  <li
                    key={signer.id}
                    className="flex items-start gap-3 rounded-md border bg-white p-3 shadow-xs transition-colors hover:bg-muted/30"
                  >
                    <div
                      className={`flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-xs font-semibold ${
                        signer.status === 'signed'
                          ? 'bg-success-bg text-success'
                          : signer.status === 'declined'
                            ? 'bg-error-bg text-error'
                            : 'bg-slate-100 text-slate-600'
                      }`}
                    >
                      {idx + 1}
                    </div>
                    <div className="min-w-0 flex-1">
                      <div className="flex items-center justify-between gap-2">
                        <div className="font-medium text-foreground">{signer.signerName}</div>
                        <StatusPill status={SIGNER_PILL_MAP[signer.status] ?? 'pending'}>
                          {signer.status}
                        </StatusPill>
                      </div>
                      <div className="text-xs text-muted-foreground">
                        {signer.signerEmail} · {signer.signerRole}
                      </div>
                      <div className="mt-1 text-xs text-muted-foreground">
                        {signer.signedAt
                          ? `Signed ${new Date(signer.signedAt).toLocaleDateString('en-GB')}`
                          : 'Pending'}
                      </div>
                      {signer.status === 'pending' && doc.documensoId && isInFlight ? (
                        <div className="mt-2 flex items-center gap-2">
                          <Button
                            size="sm"
                            variant="outline"
                            onClick={() => handleRemind(signer.id)}
                          >
                            <Bell className="mr-1.5 h-3 w-3" /> Remind
                          </Button>
                          {signer.signingUrl ? (
                            <button
                              type="button"
                              onClick={() => {
                                navigator.clipboard.writeText(signer.signingUrl!);
                                toast.success('Signing link copied');
                              }}
                              className="text-xs text-brand hover:underline"
                            >
                              Copy signing link
                            </button>
                          ) : null}
                        </div>
                      ) : null}
                    </div>
                  </li>
                ))}
              </ul>
            )}
          </section>

          {subjectLink ? (
            <section className="rounded-md border bg-white p-4">
              <h2 className="mb-2 text-sm font-semibold uppercase tracking-wide text-muted-foreground">
                Linked entity
              </h2>
              <Link
                href={subjectLink.href as Route}
                className="text-sm font-medium text-brand hover:underline"
              >
                {subjectLink.label} →
              </Link>
            </section>
          ) : null}
        </div>

        {/* Right column */}
        <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">
              Watchers
            </h2>
            {watchers.length === 0 ? (
              <p className="text-xs text-muted-foreground">No one is watching this document yet.</p>
            ) : (
              <ul className="space-y-1">
                {watchers.map((w) => (
                  <li key={w.userId} className="flex items-center justify-between text-sm">
                    <span className="truncate font-mono text-xs text-muted-foreground">
                      {w.userId.slice(0, 8)}…
                    </span>
                    <button
                      type="button"
                      aria-label="Remove watcher"
                      onClick={async () => {
                        try {
                          await apiFetch(`/api/v1/documents/${documentId}/watchers/${w.userId}`, {
                            method: 'DELETE',
                          });
                          toast.success('Watcher removed');
                          queryClient.invalidateQueries({
                            queryKey: ['document-detail', documentId],
                          });
                        } catch (err) {
                          toast.error(
                            err instanceof Error ? err.message : 'Failed to remove watcher',
                          );
                        }
                      }}
                      className="text-muted-foreground hover:text-destructive"
                    >
                      <Trash2 className="h-3.5 w-3.5" />
                    </button>
                  </li>
                ))}
              </ul>
            )}
          </section>

          <section className="rounded-md border bg-white p-4">
            <h2 className="mb-2 text-sm font-semibold uppercase tracking-wide text-muted-foreground">
              Activity
            </h2>
            {events.length === 0 ? (
              <p className="text-xs text-muted-foreground">No events yet.</p>
            ) : (
              <ul className="space-y-2">
                {events.slice(0, 12).map((e) => (
                  <li key={e.id} className="text-xs">
                    <div className="font-medium text-foreground">
                      {e.eventType.replace(/_/g, ' ')}
                    </div>
                    <div className="text-muted-foreground">
                      {new Date(e.createdAt).toLocaleString('en-GB')}
                    </div>
                  </li>
                ))}
              </ul>
            )}
          </section>
        </div>
      </div>
    </div>
  );
}
