'use client';

import { useState } from 'react';
import Link from 'next/link';
import { useParams } from 'next/navigation';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { AlertTriangle, ExternalLink } from 'lucide-react';
import { format } from 'date-fns';

import { Button } from '@/components/ui/button';
import { apiFetch } from '@/lib/api/client';
import { cn } from '@/lib/utils';
import { formatCurrency } from '@/lib/utils/currency';
import type { ExpenseRow } from './expense-columns';

interface Props {
  expense: ExpenseRow;
}

export function ExpenseDuplicateBanner({ expense }: Props) {
  const params = useParams<{ portSlug: string }>();
  const portSlug = params?.portSlug ?? '';
  const queryClient = useQueryClient();
  const [resolving, setResolving] = useState(false);

  // Fetch the candidate expense for context.
  const { data: candidateResp } = useQuery<{ data: ExpenseRow }>({
    queryKey: ['expenses', expense.duplicateOf],
    queryFn: () => apiFetch(`/api/v1/expenses/${expense.duplicateOf}`),
    enabled: Boolean(expense.duplicateOf),
    staleTime: 30_000,
  });
  const candidate = candidateResp?.data;

  const invalidate = () => {
    queryClient.invalidateQueries({ queryKey: ['expenses'] });
  };

  const merge = useMutation({
    mutationFn: () =>
      apiFetch(`/api/v1/expenses/${expense.id}/merge`, {
        method: 'POST',
        body: { targetId: expense.duplicateOf },
      }),
    onSuccess: () => {
      invalidate();
      setResolving(false);
    },
  });

  const clear = useMutation({
    mutationFn: () =>
      apiFetch(`/api/v1/expenses/${expense.id}/clear-duplicate`, { method: 'POST' }),
    onSuccess: () => {
      invalidate();
      setResolving(false);
    },
  });

  if (!expense.duplicateOf) return null;

  const candidateLabel = candidate
    ? `${candidate.establishmentName ?? 'Unnamed expense'} · ${formatCurrency(
        candidate.amount,
        candidate.currency,
      )} · ${format(new Date(candidate.expenseDate), 'd MMM yyyy')}`
    : 'a previously recorded expense';

  return (
    <div
      data-testid="expense-duplicate-banner"
      className={cn(
        'flex flex-col gap-2 rounded-lg border border-amber-300 bg-amber-50 px-4 py-3 text-sm text-amber-900',
        'sm:flex-row sm:items-center sm:justify-between',
      )}
    >
      <div className="flex min-w-0 items-start gap-2">
        <AlertTriangle className="mt-0.5 h-4 w-4 shrink-0" aria-hidden />
        <div className="min-w-0">
          <p className="font-medium">Looks like a duplicate</p>
          <p className="mt-0.5 text-xs text-amber-800">
            This expense matches{' '}
            <Link
              href={`/${portSlug}/expenses/${expense.duplicateOf}` as never}
              className="inline-flex items-center gap-1 font-medium underline-offset-2 hover:underline"
            >
              {candidateLabel}
              <ExternalLink className="h-3 w-3" aria-hidden />
            </Link>
            . Merge to consolidate, or mark as not a duplicate to keep them separate.
          </p>
        </div>
      </div>
      <div className="flex shrink-0 items-center gap-2">
        <Button
          variant="outline"
          size="sm"
          className="border-amber-400 bg-white"
          disabled={resolving || merge.isPending || clear.isPending}
          onClick={() => {
            setResolving(true);
            merge.mutate();
          }}
          data-testid="expense-merge-btn"
        >
          Merge them
        </Button>
        <Button
          variant="ghost"
          size="sm"
          disabled={resolving || merge.isPending || clear.isPending}
          onClick={() => {
            setResolving(true);
            clear.mutate();
          }}
          data-testid="expense-not-duplicate-btn"
        >
          Not a duplicate
        </Button>
      </div>
    </div>
  );
}
