import { Link2Off, Layers } from 'lucide-react'; import { cn, fmtDate } from '@/lib/utils'; import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, } from '@/components/ui/dialog'; import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction, } from '@/components/ui/alert-dialog'; import { transactionTitle, transactionDate, fmtTransactionAmount } from '@/components/bill-modal/transactionDisplay'; import type { Dispatch, SetStateAction } from 'react'; import type { BankTransaction } from '@/types'; interface MerchantRuleLite { id: number; merchant: string; } export interface BulkUnmatchState { similar: BankTransaction[]; checkedIds: Set; rules: MerchantRuleLite[]; removeRuleId: number | null; } interface UnmatchDialogsProps { unmatchTarget: BankTransaction | null; bulkUnmatch: BulkUnmatchState | null; setBulkUnmatch: Dispatch>; unmatchConfirmOpen: boolean; setUnmatchConfirmOpen: (v: boolean) => void; transactionBusyId?: number | string | null; bulkBusy?: boolean; closeUnmatch: () => void; onSingleUnmatch: () => void; onOpenBulkUnmatch: () => void; onBulkConfirm: () => void; } // The three unmatch flows for a linked bank transaction: the choice dialog // (single vs. review-similar), the single-unmatch confirm, and the bulk review // dialog (with optional merchant-rule removal). Presentational — the parent owns // the unmatch state and the confirm/bulk handlers. export default function UnmatchDialogs({ unmatchTarget, bulkUnmatch, setBulkUnmatch, unmatchConfirmOpen, setUnmatchConfirmOpen, transactionBusyId, bulkBusy, closeUnmatch, onSingleUnmatch, onOpenBulkUnmatch, onBulkConfirm, }: UnmatchDialogsProps) { return ( <> {/* ── Unmatch choice dialog ─────────────────────────────────── */} { if (!open) closeUnmatch(); }} > Unmatch transaction How would you like to proceed? {unmatchTarget && (

{transactionTitle(unmatchTarget)}

{transactionDate(unmatchTarget) ? fmtDate(transactionDate(unmatchTarget)) : 'No date'} {' · '} {fmtTransactionAmount(unmatchTarget.amount, unmatchTarget.currency ?? undefined)}

)}
{/* ── Single unmatch confirm ────────────────────────────────── */} { if (!open) setUnmatchConfirmOpen(false); }} > Unmatch this transaction? {unmatchTarget && ( <> {transactionTitle(unmatchTarget)} {' '}will be unlinked from this bill. {(unmatchTarget.linked_payment as { payment_source?: string } | null | undefined)?.payment_source === 'provider_sync' ? ' The payment record will be removed and the balance restored.' : ' The payment record will be removed.'} )} setUnmatchConfirmOpen(false)}> Cancel {transactionBusyId ? 'Unmatching…' : 'Confirm Unmatch'} {/* ── Bulk unmatch dialog ───────────────────────────────────── */} { if (!open) closeUnmatch(); }} > Review similar matches {unmatchTarget && ( Transactions similar to {transactionTitle(unmatchTarget)}. Uncheck any you want to keep matched. )} {bulkUnmatch && ( <>
Quick select: {bulkUnmatch.checkedIds.size} of {bulkUnmatch.similar.length} selected
{bulkUnmatch.similar.map(tx => ( ))}
{bulkUnmatch.rules.length > 0 && (

Merchant rules

{bulkUnmatch.rules.map(rule => ( ))}
)} )}
); }