'use client';

import { useParams } from 'next/navigation';
import Link from 'next/link';
import { useQuery } from '@tanstack/react-query';

import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import { EmptyState } from '@/components/shared/empty-state';
import { apiFetch } from '@/lib/api/client';

export interface ReservationRow {
  id: string;
  berthId: string;
  portId: string;
  clientId: string;
  yachtId: string;
  status: 'pending' | 'active' | 'ended' | 'cancelled';
  startDate: string;
  endDate: string | null;
  tenureType: string;
  contractFileId: string | null;
  notes: string | null;
  createdAt: string;
}

export interface ReservationListProps {
  reservations: ReservationRow[];
  showBerth?: boolean;
  portSlug?: string;
  emptyMessage?: string;
}

/**
 * Renders a client's name as a link by fetching the client record.
 * Uses TanStack Query cache for memoization of repeated clientId queries.
 */
function ClientLink({ clientId, portSlug }: { clientId: string; portSlug: string }) {
  const { data } = useQuery<{ fullName: string }>({
    queryKey: ['clients', clientId, 'name-only'],
    queryFn: () =>
      apiFetch<{ data: { fullName: string } }>(`/api/v1/clients/${clientId}`).then((r) => r.data),
  });

  return (
    <Link
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      href={`/${portSlug}/clients/${clientId}` as any}
      className="text-primary hover:underline"
    >
      {data?.fullName ?? `Client ${clientId.slice(0, 8)}`}
    </Link>
  );
}

/**
 * Renders a yacht's name as a link by fetching the yacht record.
 */
function YachtLink({ yachtId, portSlug }: { yachtId: string; portSlug: string }) {
  const { data } = useQuery<{ name: string }>({
    queryKey: ['yachts', yachtId, 'name-only'],
    queryFn: () =>
      apiFetch<{ data: { name: string } }>(`/api/v1/yachts/${yachtId}`).then((r) => r.data),
  });

  return (
    <Link
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      href={`/${portSlug}/yachts/${yachtId}` as any}
      className="text-primary hover:underline"
    >
      {data?.name ?? `Yacht ${yachtId.slice(0, 8)}`}
    </Link>
  );
}

/**
 * Renders a berth's mooring number as a link by fetching the berth record.
 */
function BerthLink({ berthId, portSlug }: { berthId: string; portSlug: string }) {
  const { data } = useQuery<{ mooringNumber: string }>({
    queryKey: ['berths', berthId, 'name-only'],
    queryFn: () =>
      apiFetch<{ data: { mooringNumber: string } }>(`/api/v1/berths/${berthId}`).then(
        (r) => r.data,
      ),
  });

  return (
    <Link
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      href={`/${portSlug}/berths/${berthId}` as any}
      className="text-primary hover:underline"
    >
      {data?.mooringNumber ?? `Berth ${berthId.slice(0, 8)}`}
    </Link>
  );
}

/**
 * Renders a status badge with appropriate color coding.
 */
function StatusBadge({ status }: { status: ReservationRow['status'] }) {
  const colorMap: Record<ReservationRow['status'], string> = {
    pending: 'bg-gray-100 text-gray-800',
    active: 'bg-green-100 text-green-800',
    ended: 'bg-blue-100 text-blue-800',
    cancelled: 'bg-red-100 text-red-800',
  };

  const color = colorMap[status];
  const label = status.charAt(0).toUpperCase() + status.slice(1);

  return (
    <span className={`inline-block rounded-full px-2 py-0.5 text-xs font-medium ${color}`}>
      {label}
    </span>
  );
}

/**
 * Pretty-prints tenure type for display.
 */
function prettyTenure(tenureType: string): string {
  const tenureMap: Record<string, string> = {
    permanent: 'Permanent',
    fixed_term: 'Fixed term',
    seasonal: 'Seasonal',
  };
  return tenureMap[tenureType] ?? tenureType;
}

/**
 * Formats a date range as "{startDate} → {endDate or 'ongoing'}".
 */
function formatDateRange(startDate: string, endDate: string | null): string {
  const start = new Date(startDate).toLocaleDateString();
  const end = endDate ? new Date(endDate).toLocaleDateString() : 'ongoing';
  return `${start} → ${end}`;
}

export function ReservationList({
  reservations,
  showBerth = false,
  portSlug: portSlugProp,
  emptyMessage,
}: ReservationListProps) {
  const routeParams = useParams<{ portSlug: string }>();
  const portSlug = portSlugProp ?? routeParams?.portSlug ?? '';

  if (reservations.length === 0) {
    return (
      <EmptyState title="No reservations" description={emptyMessage ?? 'No reservations yet.'} />
    );
  }

  return (
    <div className="rounded-md border">
      <Table>
        <TableHeader>
          <TableRow>
            {showBerth && <TableHead>Berth</TableHead>}
            <TableHead>Client</TableHead>
            <TableHead>Yacht</TableHead>
            <TableHead>Dates</TableHead>
            <TableHead>Tenure</TableHead>
            <TableHead>Status</TableHead>
            <TableHead>Contract</TableHead>
          </TableRow>
        </TableHeader>
        <TableBody>
          {reservations.map((r) => (
            <TableRow key={r.id}>
              {showBerth && (
                <TableCell>
                  <BerthLink berthId={r.berthId} portSlug={portSlug} />
                </TableCell>
              )}
              <TableCell>
                <ClientLink clientId={r.clientId} portSlug={portSlug} />
              </TableCell>
              <TableCell>
                <YachtLink yachtId={r.yachtId} portSlug={portSlug} />
              </TableCell>
              <TableCell>{formatDateRange(r.startDate, r.endDate)}</TableCell>
              <TableCell>{prettyTenure(r.tenureType)}</TableCell>
              <TableCell>
                <StatusBadge status={r.status} />
              </TableCell>
              <TableCell>
                {r.contractFileId ? (
                  // TODO: Confirm final file-download endpoint URL when available
                  <a
                    href={`/api/v1/files/${r.contractFileId}/download`}
                    className="text-primary hover:underline"
                  >
                    View contract
                  </a>
                ) : (
                  '—'
                )}
              </TableCell>
            </TableRow>
          ))}
        </TableBody>
      </Table>
    </div>
  );
}
