/**
 * Reconcile-diff dialog (Phase 6b — see plan §4.7b, §14.6).
 *
 * Shown after a successful per-berth PDF upload + parse. Surfaces three
 * sections:
 *   - Warnings (mooring-number mismatch, imperial-vs-metric drift, etc.)
 *     so the rep can abort before applying.
 *   - Auto-applied fields — fields the parser found that the CRM had as null;
 *     these are pre-checked and applied on confirm.
 *   - Conflicts — fields where CRM and PDF disagree on a non-null value.
 *     The rep picks "Keep CRM" or "Use PDF" per row before confirming.
 *
 * On confirm, the dialog POSTs to /pdf-versions/parse-results/apply with the
 * rep-curated `fieldsToApply` map.
 */

'use client';

import { useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';

import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';

interface AutoAppliedField {
  field: string;
  value: string | number;
}

interface ConflictField {
  field: string;
  crmValue: string | number | null;
  pdfValue: string | number | null;
  pdfConfidence: number;
}

export interface PdfReconcileDialogProps {
  berthId: string;
  versionId: string;
  autoApplied: AutoAppliedField[];
  conflicts: ConflictField[];
  warnings: string[];
  onClose: () => void;
}

export function PdfReconcileDialog({
  berthId,
  versionId,
  autoApplied,
  conflicts,
  warnings,
  onClose,
}: PdfReconcileDialogProps) {
  const qc = useQueryClient();
  // For each auto-applied field: rep can opt out by unchecking.
  const [autoChecked, setAutoChecked] = useState<Record<string, boolean>>(
    Object.fromEntries(autoApplied.map((f) => [f.field, true])),
  );
  // For each conflict: 'pdf' applies the PDF value, 'crm' keeps CRM (omit from
  // payload), 'skip' is the same as 'crm' but distinct in the UI for clarity.
  const [conflictChoice, setConflictChoice] = useState<Record<string, 'pdf' | 'crm'>>(
    Object.fromEntries(conflicts.map((c) => [c.field, 'crm'])),
  );

  const apply = useMutation({
    mutationFn: async () => {
      const fieldsToApply: Record<string, string | number> = {};
      for (const f of autoApplied) if (autoChecked[f.field]) fieldsToApply[f.field] = f.value;
      for (const c of conflicts) {
        if (conflictChoice[c.field] === 'pdf' && c.pdfValue != null) {
          fieldsToApply[c.field] = c.pdfValue;
        }
      }
      return apiFetch(`/api/v1/berths/${berthId}/pdf-versions/parse-results/apply`, {
        method: 'POST',
        body: { versionId, fieldsToApply },
      });
    },
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ['berth', berthId] });
      void qc.invalidateQueries({ queryKey: ['berth-pdf-versions', berthId] });
      toast.success('Berth fields updated from PDF.');
      onClose();
    },
    onError: (err: Error) => {
      toastError(err);
    },
  });

  return (
    <Dialog open onOpenChange={(open) => (!open ? onClose() : undefined)}>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>Review parsed fields</DialogTitle>
          <DialogDescription>
            The PDF parser extracted these values. Review and apply the ones you trust.
          </DialogDescription>
        </DialogHeader>

        {warnings.length > 0 ? (
          <div className="rounded-md border border-yellow-300 bg-yellow-50 p-3 text-sm">
            <p className="font-medium">Warnings</p>
            <ul className="mt-1 list-disc pl-5">
              {warnings.map((w, i) => (
                <li key={i}>{w}</li>
              ))}
            </ul>
          </div>
        ) : null}

        {autoApplied.length > 0 ? (
          <section>
            <h3 className="text-sm font-medium">
              Auto-applied <span className="text-muted-foreground">({autoApplied.length})</span>
            </h3>
            <p className="text-xs text-muted-foreground">
              CRM had no value; the PDF supplied one. Uncheck to skip.
            </p>
            <ul className="mt-2 space-y-1">
              {autoApplied.map((f) => (
                <li key={f.field} className="flex items-center gap-2 text-sm">
                  <Checkbox
                    id={`auto-${f.field}`}
                    checked={autoChecked[f.field]}
                    onCheckedChange={(checked) =>
                      setAutoChecked((prev) => ({ ...prev, [f.field]: checked === true }))
                    }
                  />
                  <label htmlFor={`auto-${f.field}`} className="flex-1">
                    <span className="font-medium">{f.field}</span>:{' '}
                    <span className="text-muted-foreground">{String(f.value)}</span>
                  </label>
                </li>
              ))}
            </ul>
          </section>
        ) : null}

        {conflicts.length > 0 ? (
          <section>
            <h3 className="text-sm font-medium">
              Conflicts <span className="text-muted-foreground">({conflicts.length})</span>
            </h3>
            <p className="text-xs text-muted-foreground">
              Pick which value to keep for each field.
            </p>
            <ul className="mt-2 space-y-2">
              {conflicts.map((c) => (
                <li
                  key={c.field}
                  className="grid grid-cols-[1fr_auto_auto] items-center gap-2 rounded border p-2 text-sm"
                >
                  <span className="font-medium">{c.field}</span>
                  <Button
                    size="sm"
                    variant={conflictChoice[c.field] === 'crm' ? 'default' : 'outline'}
                    onClick={() => setConflictChoice((prev) => ({ ...prev, [c.field]: 'crm' }))}
                  >
                    Keep: {String(c.crmValue)}
                  </Button>
                  <Button
                    size="sm"
                    variant={conflictChoice[c.field] === 'pdf' ? 'default' : 'outline'}
                    onClick={() => setConflictChoice((prev) => ({ ...prev, [c.field]: 'pdf' }))}
                  >
                    Use PDF: {String(c.pdfValue)} ({Math.round(c.pdfConfidence * 100)}%)
                  </Button>
                </li>
              ))}
            </ul>
          </section>
        ) : null}

        <DialogFooter>
          <Button variant="outline" onClick={onClose}>
            Cancel
          </Button>
          <Button onClick={() => apply.mutate()} disabled={apply.isPending}>
            {apply.isPending ? 'Applying…' : 'Apply'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
