'use client';

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

import { apiFetch } from '@/lib/api/client';

interface BerthRow {
  id: string;
  mooringNumber: string;
  status: string;
  isPrimary: boolean;
}

interface BerthsResponse {
  data: BerthRow[];
}

interface CompetingInterest {
  interestId: string;
  clientName: string;
  pipelineStage: string;
  isPrimary: boolean;
}

/**
 * Surfaces when one of the interest's linked berths is sold or under offer
 * to a different deal. We don't block the rep from proceeding (the user
 * explicitly wanted v1 to still let the deal advance - the assumption is
 * that the rep is aware and treating the current deal as a fallback if
 * the other one falls through), but the banner makes the conflict visible
 * so they aren't surprised when the rules engine flags it.
 *
 * Fires only for active (non-archived, non-closed) interests - banners on
 * lost deals are noise.
 */
export function InterestBerthStatusBanner({
  interestId,
  interestPipelineStage,
  interestOutcome,
  archivedAt,
}: {
  interestId: string;
  interestPipelineStage: string;
  interestOutcome?: string | null;
  archivedAt?: string | null;
}) {
  const params = useParams<{ portSlug: string }>();
  const portSlug = params?.portSlug ?? '';
  const { data } = useQuery<BerthsResponse>({
    queryKey: ['interest-berths', interestId],
    queryFn: () => apiFetch(`/api/v1/interests/${interestId}/berths`),
  });

  const berths = data?.data ?? [];
  const conflicts = berths.filter((b) => b.status === 'sold' || b.status === 'under_offer');

  // Resolve the competing deal per conflicting berth via the
  // `/active-interests` endpoint shipped in 292a8b5. Filtered client-side
  // to interests OTHER THAN this one so a deal looking at its own berth
  // doesn't see itself in the banner.
  const competingQueries = useQueries({
    queries: conflicts.map((b) => ({
      queryKey: ['berth-competing', b.id, interestId] as const,
      queryFn: () =>
        apiFetch<{ data: CompetingInterest[] }>(`/api/v1/berths/${b.id}/active-interests`).then(
          (r) => r.data.filter((row) => row.interestId !== interestId),
        ),
      enabled: conflicts.length > 0,
      staleTime: 30_000,
    })),
  });

  if (archivedAt || interestOutcome) return null;
  // The banner is most useful before the rep is committed to the deal -
  // once contract is in motion, the conflict is moot.
  if (interestPipelineStage === 'contract') return null;

  if (conflicts.length === 0) return null;

  const lines = conflicts.map((b, idx) => {
    const q = competingQueries[idx];
    const competing = (q?.data ?? []).find((c) => c.isPrimary) ?? (q?.data ?? [])[0] ?? null;
    return { berth: b, competing };
  });

  return (
    <div
      role="status"
      className="flex items-start gap-2 rounded-md border border-rose-200 bg-rose-50 px-3 py-2 text-xs text-rose-900"
    >
      <AlertTriangle className="size-3.5 mt-0.5 shrink-0" aria-hidden />
      <div className="min-w-0">
        <p className="font-medium">
          {lines.length === 1
            ? `Berth ${lines[0]!.berth.mooringNumber} is ${
                lines[0]!.berth.status === 'sold' ? 'Sold' : 'Under Offer'
              } to another deal.`
            : `${lines.length} linked berths are no longer freely available.`}
        </p>
        {lines.some((l) => l.competing) ? (
          <ul className="mt-1 space-y-0.5">
            {lines.map(({ berth, competing }) =>
              competing ? (
                <li key={berth.id} className="text-rose-900">
                  <span className="font-medium">{berth.mooringNumber}:</span>{' '}
                  <Link
                    /* eslint-disable-next-line @typescript-eslint/no-explicit-any */
                    href={`/${portSlug}/interests/${competing.interestId}` as any}
                    className="underline-offset-2 hover:underline"
                  >
                    {competing.clientName}
                  </Link>
                </li>
              ) : null,
            )}
          </ul>
        ) : null}
        <p className="mt-0.5 text-rose-800">
          You can still progress this interest as a backup, but the rep on the other deal owns the
          primary path. If their deal falls through, this one can step in.
        </p>
      </div>
    </div>
  );
}
