import { useForm, Link } from '@inertiajs/react';
import { type FormEvent, useEffect, useMemo, useState } from 'react';
import InputError from '@/components/input-error';
import { ConfirmActionModal } from '@/components/confirm-action-modal';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import { Textarea } from '@/components/ui/textarea';

export type WithdrawOption = {
    id: number;
    currency_network: string;
    address: string;
    label: string | null;
    is_default: boolean;
};

function defaultWalletIdFrom(list: WithdrawOption[]): string {
    const d = list.find((w) => w.is_default) ?? list[0];
    return d ? String(d.id) : '';
}

function round2(n: number): number {
    return Math.round(n * 100) / 100;
}

function parseUsdInput(raw: string): number {
    const n = Number.parseFloat(raw.replace(',', '.'));
    return Number.isFinite(n) ? n : 0;
}

type Props = {
    wallets: WithdrawOption[];
    /** Monto máximo retirable (bruto) desde el balance disponible. */
    capitalAvailableUsd: string;
    minWithdrawalUsd: string;
    withdrawalFeePercent: string;
    withdrawalFeeFixed: string;
    open: boolean;
    onClose: () => void;
};

export function RequestWithdrawalDialog({
    wallets,
    capitalAvailableUsd,
    minWithdrawalUsd,
    withdrawalFeePercent,
    withdrawalFeeFixed,
    open,
    onClose,
}: Props) {
    const form = useForm({
        amount: '',
        user_wallet_id: '',
        requester_note: '',
    });

    const [amountDraft, setAmountDraft] = useState('');
    const [confirmOpen, setConfirmOpen] = useState(false);

    useEffect(() => {
        if (open) {
            form.setData({
                amount: '',
                user_wallet_id: defaultWalletIdFrom(wallets),
                requester_note: '',
            });
            setAmountDraft('');
            setConfirmOpen(false);
            form.clearErrors();
        }
    }, [open, wallets.length]);

    const feePct = Number.parseFloat(withdrawalFeePercent.replace(',', '.')) || 0;
    const feeFix = Number.parseFloat(withdrawalFeeFixed.replace(',', '.')) || 0;

    const preview = useMemo(() => {
        const gross = parseUsdInput(amountDraft);
        if (gross <= 0) {
            return {
                gross: 0,
                pctPart: 0,
                fixedPart: 0,
                rawFee: 0,
                fee: 0,
                net: 0,
                wasCapped: false,
            };
        }
        const pctPart = round2(gross * (feePct / 100));
        const fixedPart = round2(feeFix);
        const rawFee = round2(pctPart + fixedPart);
        const fee = Math.min(rawFee, Math.max(0, gross - 0.01));
        const net = round2(Math.max(0, gross - fee));
        const wasCapped = rawFee > fee + 0.000_1;

        return { gross, pctPart, fixedPart, rawFee, fee, net, wasCapped };
    }, [amountDraft, feePct, feeFix]);

    const capitalUsd = Number.parseFloat(capitalAvailableUsd.replace(',', '.')) || 0;
    const minGross = Number.parseFloat(minWithdrawalUsd.replace(',', '.')) || 0;
    const meetsMinWithdrawal = preview.gross <= 0 || preview.gross + 1e-9 >= minGross;

    const selectedWallet = wallets.find(
        (w) => String(w.id) === (form.data.user_wallet_id || defaultWalletIdFrom(wallets)),
    );

    function submit(event: FormEvent<HTMLFormElement>) {
        event.preventDefault();
        if (preview.gross > 0 && !meetsMinWithdrawal) {
            return;
        }
        if (preview.gross <= 0) {
            return;
        }
        setConfirmOpen(true);
    }

    function executeWithdraw() {
        form.transform((data) => ({
            ...data,
            amount: amountDraft.trim(),
            requester_note: data.requester_note.trim() === '' ? null : data.requester_note.trim(),
        }));

        form.post('/balances/solicitud-retiro', {
            preserveScroll: true,
            onFinish: () => setConfirmOpen(false),
            onSuccess: () => onClose(),
        });
    }

    return (
        <>
            <ConfirmActionModal
                cancelLabel="Revisar datos"
                confirmLabel="Sí, enviar solicitud"
                open={confirmOpen}
                processing={form.processing}
                title="¿Confirmar solicitud de retiro?"
                onConfirm={executeWithdraw}
                onOpenChange={setConfirmOpen}
                description="Te enviaremos un correo para confirmar el retiro antes de que el equipo lo revise."
            >
                <div className="space-y-2 text-muted-foreground">
                    <p>
                        <span className="font-medium text-foreground">Monto bruto:</span>{' '}
                        <span className="tabular-nums text-foreground">{preview.gross.toFixed(2)} US$</span>
                    </p>
                    <p>
                        <span className="font-medium text-foreground">Comisión total:</span>{' '}
                        <span className="tabular-nums">{preview.fee.toFixed(2)} US$</span>
                    </p>
                    <p>
                        <span className="font-medium text-foreground">Neto estimado a recibir:</span>{' '}
                        <span className="tabular-nums text-primary">{preview.net.toFixed(2)} US$</span>
                    </p>
                    {selectedWallet ? (
                        <p className="border-t pt-2">
                            <span className="font-medium text-foreground">Destino:</span> [{selectedWallet.currency_network}
                            ]{selectedWallet.label ? ` ${selectedWallet.label}` : ''}
                        </p>
                    ) : null}
                </div>
            </ConfirmActionModal>

            <Dialog open={open} onOpenChange={(next) => !next && onClose()}>
                <DialogContent className="sm:max-w-md xl:max-w-lg">
                    <DialogHeader>
                        <DialogTitle>Solicitud de retiro</DialogTitle>
                        <DialogDescription>
                            Indica el monto a retirar. El monto mínimo de retiro es de {minGross.toFixed(2)} US$.
                        </DialogDescription>
                    </DialogHeader>

                    {wallets.length === 0 ? (
                    <>
                        <Alert>
                            <AlertTitle>Añade una billetera primero</AlertTitle>
                            <AlertDescription>
                                Registra direcciones en{' '}
                                <Link href="/balances/billeteras" className="font-medium underline">
                                    Mis billeteras
                                </Link>
                                .
                            </AlertDescription>
                        </Alert>
                        <DialogFooter>
                            <Button onClick={() => onClose()} type="button" variant="outline">
                                Cerrar
                            </Button>
                        </DialogFooter>
                    </>
                ) : (
                    <form className="space-y-4" onSubmit={submit}>
                        <div className="rounded-md border bg-muted/35 px-3 py-2 text-sm tabular-nums">
                            Máximo retirable:{' '}
                            <strong className="text-primary">${' '}
                                {Number.isFinite(capitalUsd) ? capitalUsd.toFixed(2) : capitalAvailableUsd}
                            </strong>
                        </div>

                        <div className="space-y-2">
                            <Label htmlFor="wd_wallet">Billetera destino</Label>
                            <Select
                                value={form.data.user_wallet_id || defaultWalletIdFrom(wallets)}
                                onValueChange={(v) => form.setData('user_wallet_id', v)}
                                disabled={form.processing}
                            >
                                <SelectTrigger id="wd_wallet" className="w-full">
                                    <SelectValue placeholder="Elige dirección de retiro" />
                                </SelectTrigger>
                                <SelectContent>
                                    {wallets.map((w) => (
                                        <SelectItem key={w.id} value={String(w.id)}>
                                            [{w.currency_network}]
                                            {w.label ? ` ${w.label} · ` : ' '}
                                            {w.address.length > 42
                                                ? `${w.address.slice(0, 14)}…${w.address.slice(-8)}`
                                                : w.address}
                                        </SelectItem>
                                    ))}
                                </SelectContent>
                            </Select>
                            <InputError
                                message={
                                    typeof form.errors.user_wallet_id === 'string'
                                        ? form.errors.user_wallet_id
                                        : form.errors.user_wallet_id?.[0]
                                }
                            />
                        </div>

                        <div className="space-y-2">
                            <Label htmlFor="wd_amount">Monto bruto a retirar (US$)</Label>
                            <Input
                                id="wd_amount"
                                inputMode="decimal"
                                min="0.01"
                                placeholder="Ej. 100.00"
                                required
                                step="any"
                                value={amountDraft}
                                disabled={form.processing}
                                onChange={(ev) => setAmountDraft(ev.target.value)}
                            />
                            {preview.gross > 0 ? (
                                <div className="rounded-md border bg-muted/25 px-3 py-2 text-xs tabular-nums">
                                    <p className="text-muted-foreground mb-1.5 leading-snug">
                                        Detalles de la solicitud de retiro:
                                    </p>
                                    <ul className="space-y-1">
                                        <li className="flex justify-between gap-3">
                                            <span>Monto solicitado</span>
                                            <span>{preview.gross.toFixed(2)} US$</span>
                                        </li>
                                        <li className="flex justify-between gap-3">
                                            <span>
                                                Comisión variable ({feePct.toLocaleString('es-US')}%)
                                            </span>
                                            <span>{preview.pctPart.toFixed(2)} US$</span>
                                        </li>
                                        <li className="flex justify-between gap-3">
                                            <span>Comisión fija</span>
                                            <span>{preview.fixedPart.toFixed(2)} US$</span>
                                        </li>
                                        <li className="flex justify-between gap-3 font-medium">
                                            <span>Total comisión</span>
                                            <span>{preview.fee.toFixed(2)} US$</span>
                                        </li>
                                        <li className="flex justify-between gap-3 text-primary">
                                            <span>Monto a recibir</span>
                                            <span>{preview.net.toFixed(2)} US$</span>
                                        </li>
                                    </ul>
                                </div>
                            ) : (
                                <p className="text-muted-foreground text-xs">
                                    Indica el monto bruto para ver el desglose (porcentaje, fijo, tope y neto estimado).
                                </p>
                            )}
                            {preview.gross > 0 && !meetsMinWithdrawal ? (
                                <p className="text-destructive text-xs">
                                    El monto bruto debe ser al menos {minGross.toFixed(2)} US$ (mínimo de retiro).
                                </p>
                            ) : null}
                            <InputError
                                message={
                                    typeof form.errors.amount === 'string'
                                        ? form.errors.amount
                                        : form.errors.amount?.[0]
                                }
                            />
                        </div>

                        <div className="space-y-2">
                            <Label htmlFor="wd_note">Comentario (opcional)</Label>
                            <Textarea
                                id="wd_note"
                                className="min-h-[84px]"
                                placeholder="Instrucciones, preferencia de canal o cualquier aclaración para el equipo…"
                                disabled={form.processing}
                                value={form.data.requester_note}
                                onChange={(ev) => form.setData('requester_note', ev.target.value)}
                            />
                            <InputError
                                message={
                                    typeof form.errors.requester_note === 'string'
                                        ? form.errors.requester_note
                                        : form.errors.requester_note?.[0]
                                }
                            />
                        </div>

                        <DialogFooter className="gap-2 sm:gap-0">
                            <Button
                                disabled={form.processing}
                                onClick={() => onClose()}
                                type="button"
                                variant="ghost"
                            >
                                Cancelar
                            </Button>
                            <Button
                                disabled={form.processing || (preview.gross > 0 && !meetsMinWithdrawal)}
                                type="submit"
                            >
                                {form.processing ? 'Enviando…' : 'Enviar y confirmar por correo'}
                            </Button>
                        </DialogFooter>
                    </form>
                )}
                </DialogContent>
            </Dialog>
        </>
    );
}
