import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { Input } from '@/components/ui/input';
import { TableCell, TableRow } from '@/components/ui/table';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { useTranslation } from '@/hooks/use-translation';
import { router } from '@inertiajs/react';
import { Check, Copy, ExternalLink, MoreVertical, Pencil, RotateCcw, Trash2 } from 'lucide-react';
import * as React from 'react';
import { toast } from 'sonner';
import { FrDateInput } from './fr-date-input';
import { SourceBadge } from './source-badge';
import type { LedgerRow, LedgerSource } from './types';

interface Props {
    row: LedgerRow;
    selected?: boolean;
    onToggleSelect?: (checked: boolean) => void;
    onOpenSource?: (source: LedgerSource, sourceId: number) => void;
    onEditSource?: (source: LedgerSource, sourceId: number) => void;
    onDeleteSource?: (source: LedgerSource, sourceId: number) => void;
}

function frDate(iso: string): string {
    const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(iso);
    return m ? `${m[3]}/${m[2]}/${m[1]}` : iso;
}

/**
 * Date + time stamp for the ledger Date cell.
 *   - business date: dd/mm/yyyy (from the row's editable `date` column)
 *   - creation time: HH:mm     (from `created_at`, if available)
 */
function frDateTime(date: string, createdAt: string | null): { date: string; time: string | null } {
    const d = frDate(date);
    if (!createdAt) return { date: d, time: null };
    const parsed = new Date(createdAt);
    if (isNaN(parsed.getTime())) return { date: d, time: null };
    const hh = String(parsed.getHours()).padStart(2, '0');
    const mm = String(parsed.getMinutes()).padStart(2, '0');
    return { date: d, time: `${hh}:${mm}` };
}

function fmtAmount(n: number): string {
    return n.toLocaleString('fr-TN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}

export function EditableRow({ row, selected = false, onToggleSelect, onOpenSource, onEditSource, onDeleteSource }: Props) {
    const { t } = useTranslation();
    const [draft, setDraft] = React.useState(row);
    // Manual rows render read-only by default (like Recovery/Dépense rows).
    // "Modifier" in the ⋮ menu flips this on to expose the inline editors.
    const [editing, setEditing] = React.useState(false);
    const isDeleted = row.deleted_at !== null;
    const isMirror = row.source !== 'manual';

    React.useEffect(() => setDraft(row), [row]);

    const patch = (changes: Partial<LedgerRow>) => {
        const next = { ...draft, ...changes };
        setDraft(next);

        const payload: Record<string, string | number | null> = {};
        (Object.keys(changes) as (keyof LedgerRow)[]).forEach((k) => {
            payload[k] = next[k] as string | number | null;
        });

        if ('amount' in changes) {
            payload.amount_tnd = next.amount;
            payload.currency = 'TND';
        }

        router.patch(route('fond-de-caisse.update', { id: row.id }), payload, {
            preserveScroll: true,
            preserveState: true,
            only: ['rows', 'summary', 'flash'],
            onError: () => {
                toast.error(t('fond_de_caisse', 'error_saving'));
                setDraft(row);
            },
        });
    };

    const onDelete = () => {
        if (!confirm(t('fond_de_caisse', 'confirm_delete'))) return;
        router.delete(route('fond-de-caisse.destroy', { id: row.id }), {
            preserveScroll: true,
            only: ['rows', 'summary', 'flash'],
        });
    };

    const onRestore = () => {
        router.post(
            route('fond-de-caisse.restore', { id: row.id }),
            {},
            { preserveScroll: true, only: ['rows', 'summary', 'flash'] },
        );
    };

    const onDuplicate = () => {
        router.post(
            route('fond-de-caisse.duplicate', { id: row.id }),
            {},
            { preserveScroll: true, only: ['rows', 'summary', 'flash'] },
        );
    };

    // For allocation rows the "source id" is the fond_de_caisse row id itself
    // (the receipt lives on one paired side only). For the classic mirror
    // sources it's the linked recovery/expense/receipt id.
    const sourceId = () =>
        row.source === 'allocation'
            ? row.id
            : (row.recovery_id ?? row.expense_id ?? row.receipt_id);

    const openSource = () => {
        const id = sourceId();
        if (id != null && onOpenSource) onOpenSource(row.source, id);
    };

    const editSource = () => {
        const id = sourceId();
        if (id != null && onEditSource) onEditSource(row.source, id);
    };

    const deleteSource = () => {
        const id = sourceId();
        if (id != null && onDeleteSource) onDeleteSource(row.source, id);
    };

    const isEntree = draft.type === 'entree';
    const soldeClass = isDeleted
        ? 'text-muted-foreground'
        : (draft.solde ?? 0) >= 0
            ? 'text-emerald-700 font-semibold'
            : 'text-red-700 font-semibold';

    const commitAmount = (active: boolean, value: number) => {
        if (isDeleted || isMirror) return;
        if (!active && value === 0) return;
        if (active) {
            patch({ type: 'entree', amount: value, amount_tnd: value, currency: 'TND' });
        } else {
            patch({ type: 'sortie', amount: value, amount_tnd: value, currency: 'TND' });
        }
    };

    // Read-only render — used for mirror rows (Recovery/Dépense/Reçu/Allocation)
    // AND for manual rows that aren't in edit mode. Styled plain text + a
    // source badge, no faux-editable inputs.
    if (!isDeleted && (isMirror || !editing)) {
        const entreeTxt = isEntree ? `${fmtAmount(draft.amount)} TND` : '—';
        const sortieTxt = !isEntree ? `${fmtAmount(draft.amount)} TND` : '—';
        const sourceLabel =
            row.source === 'recovery'   ? 'Recouvrement' :
            row.source === 'expense'    ? 'Dépense' :
            row.source === 'receipt'    ? 'Reçu' :
            row.source === 'allocation' ? 'Allocation' : 'Manuel';
        // Allocation rows: giver-side has receipt_id; receiver-side uses
        // paired_entry_id as the linked row reference.
        const sourceRefId = row.recovery_id ?? row.expense_id ?? row.receipt_id ?? row.paired_entry_id ?? row.id;

        return (
            <TableRow className="group hover:bg-muted/40">
                <TableCell className="py-3 text-center">
                    {/* Manual rows stay bulk-selectable; mirror rows don't. */}
                    {!isMirror && onToggleSelect && (
                        <Checkbox
                            checked={selected}
                            onCheckedChange={(v) => onToggleSelect(v === true)}
                            aria-label="Sélectionner cette ligne"
                        />
                    )}
                </TableCell>

                <TableCell className="py-3 text-base tabular-nums">
                    {(() => {
                        const dt = frDateTime(draft.date, row.created_at);
                        return (
                            <div className="flex flex-col leading-tight">
                                <span>{dt.date}</span>
                                {dt.time && <span className="text-muted-foreground text-[11px] font-normal">{dt.time}</span>}
                            </div>
                        );
                    })()}
                </TableCell>

                <TableCell className="py-3 min-w-0">
                    <div className="flex items-center gap-2 min-w-0">
                        <Tooltip>
                            <TooltipTrigger asChild>
                                <button
                                    type="button"
                                    onClick={isMirror ? openSource : () => setEditing(true)}
                                    className="min-w-0 flex-1 text-left focus:outline-none"
                                >
                                    {/* Designation truncates; the action badge
                                        is a separate shrink-0 sibling so it's
                                        never clipped by the truncation. */}
                                    <div className="flex items-center gap-1.5 min-w-0">
                                        <span className="truncate text-base hover:underline">
                                            {draft.designation}
                                        </span>
                                        {row.facture_pending && (
                                            <span className="shrink-0 rounded-full bg-amber-100 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-amber-700">
                                                ⏳ facture en attente
                                            </span>
                                        )}
                                        {row.alloc_can_report && (
                                            <span className="shrink-0 rounded-full bg-emerald-100 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-emerald-700">
                                                ▶ à traiter
                                            </span>
                                        )}
                                        {row.alloc_can_approve && (
                                            <span className="shrink-0 rounded-full bg-amber-100 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-amber-700">
                                                ✔ à approuver
                                            </span>
                                        )}
                                        {row.alloc_can_return && (
                                            <span className="shrink-0 rounded-full bg-sky-100 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-sky-700">
                                                ↩ retour à confirmer
                                            </span>
                                        )}
                                        {row.allocation_status === 'closed' && (
                                            <span className="shrink-0 rounded-full bg-slate-100 px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-slate-600">
                                                ✓ clôturé
                                            </span>
                                        )}
                                    </div>
                                    {row.owner_name && (
                                        <div className="text-muted-foreground truncate text-[11px]">
                                            👤 {row.owner_name}
                                        </div>
                                    )}
                                </button>
                            </TooltipTrigger>
                            <TooltipContent side="top" align="start" className="max-w-md space-y-1.5">
                                <div className="text-white font-semibold">{draft.designation}</div>
                                <div className="text-white/80 text-xs space-y-1">
                                    <div>{sourceLabel} #{sourceRefId}</div>
                                    <div>Date : {frDate(draft.date)}</div>
                                    <div className="flex items-center gap-1.5">
                                        <span>Montant :</span>
                                        <span
                                            className={
                                                isEntree
                                                    ? 'rounded bg-emerald-500/30 px-1.5 py-0.5 font-semibold text-emerald-100'
                                                    : 'rounded bg-red-500/30 px-1.5 py-0.5 font-semibold text-red-100'
                                            }
                                        >
                                            {fmtAmount(draft.amount)} TND ({isEntree ? 'Entrée' : 'Sortie'})
                                        </span>
                                    </div>
                                    <div className="pt-1 italic text-white/60">
                                        {isMirror ? 'Cliquer pour voir le détail complet' : 'Cliquer pour modifier'}
                                    </div>
                                </div>
                            </TooltipContent>
                        </Tooltip>
                        <div className="shrink-0">
                            <SourceBadge row={row} onClick={isMirror ? openSource : undefined} />
                        </div>
                    </div>
                </TableCell>

                <TableCell className={`py-3 text-right pr-4 text-base tabular-nums ${isEntree ? 'text-emerald-700 font-semibold' : 'text-muted-foreground/40'}`}>
                    {entreeTxt}
                </TableCell>

                <TableCell className={`py-3 text-right pr-4 text-base tabular-nums ${!isEntree ? 'text-red-700 font-semibold' : 'text-muted-foreground/40'}`}>
                    {sortieTxt}
                </TableCell>

                <TableCell className={`tabular-nums text-right pr-4 text-base ${soldeClass}`}>
                    {draft.solde !== null
                        ? `${fmtAmount(draft.solde)} TND`
                        : '—'}
                </TableCell>

                <TableCell>
                    <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                            <Button variant="ghost" size="icon" className="h-9 w-9">
                                <MoreVertical className="h-5 w-5" />
                            </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                            {isMirror ? (
                                <>
                                    <DropdownMenuItem onClick={openSource}>
                                        <ExternalLink className="mr-2 h-4 w-4" />
                                        {row.alloc_can_report
                                            ? 'Traiter — déclarer la dépense'
                                            : row.alloc_can_approve
                                                ? 'Approuver la déclaration'
                                                : row.alloc_can_return
                                                    ? 'Confirmer le retour'
                                                    : t('fond_de_caisse', 'action_view_source')}
                                    </DropdownMenuItem>
                                    {(row.source === 'recovery' || row.source === 'expense') && onEditSource && (
                                        <DropdownMenuItem onClick={editSource}>
                                            <Pencil className="mr-2 h-4 w-4" />
                                            Modifier
                                        </DropdownMenuItem>
                                    )}
                                    {(row.source === 'recovery' || row.source === 'expense') && onDeleteSource && (
                                        <DropdownMenuItem
                                            onClick={deleteSource}
                                            className="text-red-600 focus:text-red-600"
                                        >
                                            <Trash2 className="mr-2 h-4 w-4" />
                                            Supprimer
                                        </DropdownMenuItem>
                                    )}
                                </>
                            ) : (
                                // Manual rows: edit inline, duplicate, delete.
                                <>
                                    <DropdownMenuItem onClick={() => setEditing(true)}>
                                        <Pencil className="mr-2 h-4 w-4" />
                                        Modifier
                                    </DropdownMenuItem>
                                    <DropdownMenuItem onClick={onDuplicate}>
                                        <Copy className="mr-2 h-4 w-4" />
                                        {t('fond_de_caisse', 'action_duplicate')}
                                    </DropdownMenuItem>
                                    <DropdownMenuItem onClick={onDelete} className="text-red-600 focus:text-red-600">
                                        <Trash2 className="mr-2 h-4 w-4" />
                                        {t('fond_de_caisse', 'action_delete')}
                                    </DropdownMenuItem>
                                </>
                            )}
                        </DropdownMenuContent>
                    </DropdownMenu>
                </TableCell>
            </TableRow>
        );
    }

    // Manual or soft-deleted rows: keep editable inputs (line-through when deleted).
    const rowClass = isDeleted ? 'group line-through text-muted-foreground bg-muted/30' : 'group';
    const inputClass = `h-11 border-transparent text-base focus:border-input ${
        isDeleted ? 'line-through text-muted-foreground' : ''
    }`;

    return (
        <TableRow className={rowClass}>
            <TableCell className="py-2 text-center">
                {!isDeleted && onToggleSelect && (
                    <Checkbox
                        checked={selected}
                        onCheckedChange={(v) => onToggleSelect(v === true)}
                        aria-label="Sélectionner cette ligne"
                    />
                )}
            </TableCell>

            <TableCell className="py-2">
                <div className="flex flex-col leading-tight">
                    <FrDateInput
                        value={draft.date}
                        disabled={isDeleted}
                        inputClassName={`border-transparent text-base focus:border-input ${
                            isDeleted ? 'line-through text-muted-foreground' : ''
                        }`}
                        onChange={(iso) => {
                            if (iso && iso !== row.date) patch({ date: iso });
                        }}
                    />
                    {(() => {
                        const dt = frDateTime(draft.date, row.created_at);
                        return dt.time ? (
                            <span className="text-muted-foreground ml-3 text-[11px]">{dt.time}</span>
                        ) : null;
                    })()}
                </div>
            </TableCell>

            <TableCell className="py-2">
                <Input
                    type="text"
                    defaultValue={draft.designation}
                    placeholder={t('fond_de_caisse', 'designation_placeholder')}
                    disabled={isDeleted}
                    onBlur={(e) => {
                        if (e.target.value !== row.designation) patch({ designation: e.target.value });
                    }}
                    className={inputClass}
                />
            </TableCell>

            <TableCell className="py-2">
                <AmountInput
                    tone="entree"
                    active={isEntree}
                    disabled={isDeleted}
                    value={isEntree ? draft.amount : 0}
                    onCommit={(v) => commitAmount(true, v)}
                />
            </TableCell>

            <TableCell className="py-2">
                <AmountInput
                    tone="sortie"
                    active={!isEntree}
                    disabled={isDeleted}
                    value={!isEntree ? draft.amount : 0}
                    onCommit={(v) => commitAmount(false, v)}
                />
            </TableCell>

            <TableCell className={`tabular-nums text-right pr-4 text-base ${soldeClass}`}>
                {draft.solde !== null
                    ? `${fmtAmount(draft.solde)} TND`
                    : '—'}
            </TableCell>

            <TableCell>
                <DropdownMenu>
                    <DropdownMenuTrigger asChild>
                        <Button variant="ghost" size="icon" className="h-9 w-9">
                            <MoreVertical className="h-5 w-5" />
                        </Button>
                    </DropdownMenuTrigger>
                    <DropdownMenuContent align="end">
                        {isDeleted ? (
                            <DropdownMenuItem onClick={onRestore} className="text-emerald-700 focus:text-emerald-700">
                                <RotateCcw className="mr-2 h-4 w-4" />
                                {t('fond_de_caisse', 'action_restore')}
                            </DropdownMenuItem>
                        ) : (
                            <>
                                <DropdownMenuItem onClick={() => setEditing(false)}>
                                    <Check className="mr-2 h-4 w-4" />
                                    Terminer l'édition
                                </DropdownMenuItem>
                                <DropdownMenuItem onClick={onDuplicate}>
                                    <Copy className="mr-2 h-4 w-4" />
                                    {t('fond_de_caisse', 'action_duplicate')}
                                </DropdownMenuItem>
                                <DropdownMenuItem onClick={onDelete} className="text-red-600 focus:text-red-600">
                                    <Trash2 className="mr-2 h-4 w-4" />
                                    {t('fond_de_caisse', 'action_delete')}
                                </DropdownMenuItem>
                            </>
                        )}
                    </DropdownMenuContent>
                </DropdownMenu>
            </TableCell>
        </TableRow>
    );
}

function AmountInput({
    active,
    value,
    disabled,
    tone,
    onCommit,
}: {
    active: boolean;
    value: number;
    disabled?: boolean;
    tone: 'entree' | 'sortie';
    onCommit: (v: number) => void;
}) {
    const [local, setLocal] = React.useState<number>(value);
    React.useEffect(() => setLocal(value), [value]);

    let toneClass = 'text-muted-foreground/50';
    if (active && !disabled) {
        toneClass = tone === 'entree' ? 'text-emerald-700 font-semibold' : 'text-red-700 font-semibold';
    }

    return (
        <Input
            type="number"
            step="0.01"
            min="0"
            value={local || ''}
            disabled={disabled}
            onChange={(e) => setLocal(parseFloat(e.target.value) || 0)}
            onBlur={() => onCommit(local)}
            placeholder="0.00"
            className={`h-11 border-transparent text-right text-base tabular-nums focus:border-input ${toneClass} ${
                disabled ? 'line-through' : ''
            }`}
        />
    );
}
