import { Head, Link, router, useForm, usePage } from '@inertiajs/react';
import { ArrowLeft, Check, Copy, Pencil, Plus, Star, Trash2, Wallet } from 'lucide-react';
import { type FormEvent, useState } from 'react';
import {
    AppBackLinkRow,
    AppPage,
    AppPageActions,
    AppPageHeader,
    AppPageTitleBlock,
} from '@/components/app-page';
import { ConfirmActionModal } from '@/components/confirm-action-modal';
import InputError from '@/components/input-error';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import {
    Dialog,
    DialogContent,
    DialogFooter,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useClipboard } from '@/hooks/use-clipboard';
import { cn } from '@/lib/utils';
import { dashboard } from '@/routes';

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

type Props = {
    wallets: SavedWalletRow[];
};

const NETWORK_PRESETS = ['TRC20 USDT', 'ERC20 USDT', 'BTC', 'BEP20 USDT'] as const;

function shortAddress(address: string): string {
    if (address.length <= 28) {
        return address;
    }

    return `${address.slice(0, 14)}…${address.slice(-8)}`;
}

function WalletFormFields({
    idPrefix,
    currencyNetwork,
    address,
    label,
    isDefault,
    errors,
    disabled,
    onCurrencyNetworkChange,
    onAddressChange,
    onLabelChange,
    onIsDefaultChange,
}: {
    idPrefix: string;
    currencyNetwork: string;
    address: string;
    label: string;
    isDefault: boolean;
    errors: Record<string, string | undefined>;
    disabled?: boolean;
    onCurrencyNetworkChange: (value: string) => void;
    onAddressChange: (value: string) => void;
    onLabelChange: (value: string) => void;
    onIsDefaultChange: (value: boolean) => void;
}) {
    return (
        <fieldset className="space-y-3" disabled={disabled}>
            <div className="space-y-1.5">
                <Label htmlFor={`${idPrefix}_network`}>Red / moneda</Label>
                <Input
                    id={`${idPrefix}_network`}
                    name="currency_network"
                    placeholder="Ej. TRC20 USDT"
                    required
                    value={currencyNetwork}
                    onChange={(ev) => onCurrencyNetworkChange(ev.target.value)}
                />
                <div className="flex flex-wrap gap-1">
                    {NETWORK_PRESETS.map((preset) => (
                        <button
                            key={preset}
                            type="button"
                            className={cn(
                                'rounded-md border px-2 py-0.5 text-xs transition-colors',
                                currencyNetwork === preset
                                    ? 'border-primary bg-primary/15'
                                    : 'border-border text-muted-foreground hover:text-foreground',
                            )}
                            onClick={() => onCurrencyNetworkChange(preset)}
                        >
                            {preset}
                        </button>
                    ))}
                </div>
                <InputError message={errors.currency_network} />
            </div>
            <div className="space-y-1.5">
                <Label htmlFor={`${idPrefix}_address`}>Dirección</Label>
                <Input
                    id={`${idPrefix}_address`}
                    name="address"
                    required
                    className="font-mono text-sm"
                    value={address}
                    onChange={(ev) => onAddressChange(ev.target.value)}
                />
                <InputError message={errors.address} />
            </div>
            <div className="space-y-1.5">
                <Label htmlFor={`${idPrefix}_label`}>Etiqueta (opcional)</Label>
                <Input
                    id={`${idPrefix}_label`}
                    name="label"
                    value={label}
                    onChange={(ev) => onLabelChange(ev.target.value)}
                />
                <InputError message={errors.label} />
            </div>
            <label className="flex cursor-pointer items-center gap-2 text-sm">
                <Checkbox
                    checked={isDefault}
                    id={`${idPrefix}_default`}
                    onCheckedChange={(v) => onIsDefaultChange(v === true)}
                />
                Predeterminada al retirar
            </label>
        </fieldset>
    );
}

function WalletCard({
    row,
    copiedAddress,
    onCopy,
    onEdit,
    onDelete,
    onSetDefault,
    settingDefaultId,
}: {
    row: SavedWalletRow;
    copiedAddress: string | null;
    onCopy: (address: string) => void;
    onEdit: (row: SavedWalletRow) => void;
    onDelete: (row: SavedWalletRow) => void;
    onSetDefault: (row: SavedWalletRow) => void;
    settingDefaultId: number | null;
}) {
    const addressCopied = copiedAddress === row.address;

    return (
        <article
            className={cn(
                'flex flex-col rounded-xl border bg-card p-4 shadow-sm',
                row.is_default ? 'border-primary/45 ring-1 ring-primary/15' : 'border-border/80',
            )}
        >
            <div className="flex items-start gap-3">
                <div
                    className={cn(
                        'flex size-9 shrink-0 items-center justify-center rounded-lg',
                        row.is_default ? 'bg-primary/15 text-primary' : 'bg-muted text-muted-foreground',
                    )}
                >
                    <Wallet className="size-4" aria-hidden />
                </div>
                <div className="min-w-0 flex-1">
                    <div className="flex flex-wrap items-center gap-1.5">
                        <h3 className="text-sm font-semibold leading-tight">{row.currency_network}</h3>
                        {row.is_default ? (
                            <Badge className="h-5 gap-0.5 border-primary/30 bg-primary/10 px-1.5 text-[10px] text-primary">
                                <Star className="size-2.5 fill-current" aria-hidden />
                                Predeterminada
                            </Badge>
                        ) : null}
                    </div>
                    {row.label ? (
                        <p className="text-muted-foreground mt-0.5 truncate text-xs">{row.label}</p>
                    ) : null}
                </div>
            </div>

            <div className="mt-3 flex items-center gap-1.5 rounded-md border border-border/60 bg-muted/20 px-2.5 py-2">
                <code
                    className="min-w-0 flex-1 truncate font-mono text-xs"
                    title={row.address}
                >
                    <span className="sm:hidden">{shortAddress(row.address)}</span>
                    <span className="hidden sm:inline">{row.address}</span>
                </code>
                <Button
                    className="size-7 shrink-0"
                    size="icon"
                    type="button"
                    variant="ghost"
                    aria-label={addressCopied ? 'Copiada' : 'Copiar dirección'}
                    onClick={() => onCopy(row.address)}
                >
                    {addressCopied ? (
                        <Check className="size-3.5 text-emerald-600" aria-hidden />
                    ) : (
                        <Copy className="size-3.5" aria-hidden />
                    )}
                </Button>
            </div>

            <div className="mt-3 flex flex-wrap gap-1.5 border-t border-border/50 pt-3">
                {!row.is_default ? (
                    <Button
                        className="h-8 gap-1 px-2.5 text-xs"
                        disabled={settingDefaultId === row.id}
                        size="sm"
                        type="button"
                        variant="secondary"
                        onClick={() => onSetDefault(row)}
                    >
                        <Star className="size-3" aria-hidden />
                        {settingDefaultId === row.id ? '…' : 'Predeterminada'}
                    </Button>
                ) : null}
                <Button
                    className="h-8 gap-1 px-2.5 text-xs"
                    size="sm"
                    type="button"
                    variant="outline"
                    onClick={() => onEdit(row)}
                >
                    <Pencil className="size-3" aria-hidden />
                    Editar
                </Button>
                <Button
                    className="h-8 gap-1 px-2.5 text-xs"
                    size="sm"
                    type="button"
                    variant="ghost"
                    onClick={() => onDelete(row)}
                >
                    <Trash2 className="size-3 text-destructive" aria-hidden />
                    Eliminar
                </Button>
            </div>
        </article>
    );
}

export default function BalanceWalletsPage({ wallets }: Props) {
    const page = usePage<{ kyc?: { investor_portal_unlocked?: boolean } }>();
    const kycAllowsNewWallets = page.props.kyc?.investor_portal_unlocked === true;

    const [addOpen, setAddOpen] = useState(false);
    const [editing, setEditing] = useState<SavedWalletRow | null>(null);
    const [deleteTarget, setDeleteTarget] = useState<SavedWalletRow | null>(null);
    const [settingDefaultId, setSettingDefaultId] = useState<number | null>(null);
    const [copiedAddress, copy] = useClipboard();

    const addForm = useForm({
        currency_network: '',
        address: '',
        label: '',
        is_default: false as boolean,
    });

    const editForm = useForm({
        currency_network: '',
        address: '',
        label: '',
        is_default: false as boolean,
    });

    function openEdit(row: SavedWalletRow) {
        setEditing(row);
        editForm.setData({
            currency_network: row.currency_network,
            address: row.address,
            label: row.label ?? '',
            is_default: row.is_default,
        });
        editForm.clearErrors();
    }

    function closeEdit() {
        setEditing(null);
        editForm.reset();
        editForm.clearErrors();
    }

    function closeAdd() {
        setAddOpen(false);
        addForm.reset();
        addForm.clearErrors();
    }

    function submitAdd(e: FormEvent) {
        e.preventDefault();
        if (!kycAllowsNewWallets) {
            return;
        }
        addForm.transform((data) => ({
            ...data,
            label: data.label.trim() === '' ? null : data.label,
        }));
        addForm.post('/balances/billeteras', {
            preserveScroll: true,
            onSuccess: () => closeAdd(),
        });
    }

    function submitEdit(e: FormEvent) {
        e.preventDefault();
        if (!editing) {
            return;
        }
        editForm.transform((data) => ({
            ...data,
            label: data.label.trim() === '' ? null : data.label,
        }));
        editForm.put(`/balances/billeteras/${editing.id}`, {
            preserveScroll: true,
            onSuccess: () => closeEdit(),
        });
    }

    function setAsDefault(row: SavedWalletRow) {
        setSettingDefaultId(row.id);
        router.put(
            `/balances/billeteras/${row.id}`,
            {
                currency_network: row.currency_network,
                address: row.address,
                label: row.label,
                is_default: true,
            },
            {
                preserveScroll: true,
                onFinish: () => setSettingDefaultId(null),
            },
        );
    }

    function executeDelete() {
        if (!deleteTarget) {
            return;
        }
        router.delete(`/balances/billeteras/${deleteTarget.id}`, {
            preserveScroll: true,
            onFinish: () => setDeleteTarget(null),
        });
    }

    return (
        <>
            <Head title="Mis billeteras" />

            <ConfirmActionModal
                cancelLabel="Cancelar"
                confirmLabel="Sí, eliminar"
                confirmVariant="destructive"
                description={
                    wallets.length <= 1
                        ? 'Es tu única billetera. Necesitarás otra para solicitar retiros.'
                        : 'Podrás registrar otra dirección cuando quieras.'
                }
                open={deleteTarget !== null}
                title="¿Eliminar esta billetera?"
                onConfirm={executeDelete}
                onOpenChange={(open) => !open && setDeleteTarget(null)}
            >
                {deleteTarget ? (
                    <p className="break-all font-mono text-xs text-muted-foreground">
                        {deleteTarget.currency_network} · {deleteTarget.address}
                    </p>
                ) : null}
            </ConfirmActionModal>

            <Dialog open={addOpen} onOpenChange={(open) => !open && closeAdd()}>
                <DialogContent className="sm:max-w-md">
                    <DialogHeader>
                        <DialogTitle>Nueva billetera</DialogTitle>
                    </DialogHeader>
                    <form className="space-y-4" onSubmit={submitAdd}>
                        <WalletFormFields
                            idPrefix="add"
                            address={addForm.data.address}
                            currencyNetwork={addForm.data.currency_network}
                            disabled={!kycAllowsNewWallets || addForm.processing}
                            errors={addForm.errors}
                            isDefault={addForm.data.is_default}
                            label={addForm.data.label}
                            onAddressChange={(v) => addForm.setData('address', v)}
                            onCurrencyNetworkChange={(v) => addForm.setData('currency_network', v)}
                            onIsDefaultChange={(v) => addForm.setData('is_default', v)}
                            onLabelChange={(v) => addForm.setData('label', v)}
                        />
                        <DialogFooter className="gap-2 pt-1">
                            <Button type="button" variant="ghost" onClick={() => closeAdd()}>
                                Cancelar
                            </Button>
                            <Button disabled={!kycAllowsNewWallets || addForm.processing} type="submit">
                                {addForm.processing ? 'Guardando…' : 'Guardar'}
                            </Button>
                        </DialogFooter>
                    </form>
                </DialogContent>
            </Dialog>

            <Dialog open={editing !== null} onOpenChange={(open) => !open && closeEdit()}>
                <DialogContent className="sm:max-w-md">
                    <DialogHeader>
                        <DialogTitle>Editar billetera</DialogTitle>
                    </DialogHeader>
                    {editing ? (
                        <form className="space-y-4" onSubmit={submitEdit}>
                            <WalletFormFields
                                idPrefix="edit"
                                address={editForm.data.address}
                                currencyNetwork={editForm.data.currency_network}
                                disabled={editForm.processing}
                                errors={editForm.errors}
                                isDefault={editForm.data.is_default}
                                label={editForm.data.label}
                                onAddressChange={(v) => editForm.setData('address', v)}
                                onCurrencyNetworkChange={(v) =>
                                    editForm.setData('currency_network', v)
                                }
                                onIsDefaultChange={(v) => editForm.setData('is_default', v)}
                                onLabelChange={(v) => editForm.setData('label', v)}
                            />
                            <DialogFooter className="gap-2 pt-1">
                                <Button type="button" variant="ghost" onClick={() => closeEdit()}>
                                    Cancelar
                                </Button>
                                <Button disabled={editForm.processing} type="submit">
                                    {editForm.processing ? 'Guardando…' : 'Actualizar'}
                                </Button>
                            </DialogFooter>
                        </form>
                    ) : null}
                </DialogContent>
            </Dialog>

            <AppPage className="gap-5 sm:gap-6">
                <AppBackLinkRow>
                    <Button asChild size="sm" variant="ghost">
                        <Link href="/balances">
                            <ArrowLeft className="size-4" />
                            Mis balances
                        </Link>
                    </Button>
                </AppBackLinkRow>

                <AppPageHeader className="pb-4">
                    <AppPageTitleBlock
                        description="Direcciones de destino para tus retiros en cripto."
                        descriptionClassName="text-sm"
                        title="Mis billeteras"
                    />
                    <AppPageActions>
                        <Button
                            disabled={!kycAllowsNewWallets}
                            type="button"
                            onClick={() => setAddOpen(true)}
                        >
                            <Plus className="size-4" />
                            Añadir billetera
                        </Button>
                    </AppPageActions>
                </AppPageHeader>

                {!kycAllowsNewWallets ? (
                    <p className="rounded-lg border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-sm">
                        Aprueba tu{' '}
                        <Link className="font-medium underline" href="/verificacion-kyc">
                            verificación KYC
                        </Link>{' '}
                        para añadir direcciones nuevas.
                    </p>
                ) : null}

                {wallets.length === 0 ? (
                    <Card className="border-dashed">
                        <CardContent className="flex flex-col items-center gap-3 py-10 text-center">
                            <div className="flex size-11 items-center justify-center rounded-xl bg-muted">
                                <Wallet className="text-muted-foreground size-5" aria-hidden />
                            </div>
                            <p className="text-muted-foreground max-w-xs text-sm">
                                Aún no tienes billeteras guardadas para recibir retiros.
                            </p>
                            <Button
                                disabled={!kycAllowsNewWallets}
                                size="sm"
                                type="button"
                                onClick={() => setAddOpen(true)}
                            >
                                <Plus className="size-4" />
                                Registrar primera billetera
                            </Button>
                        </CardContent>
                    </Card>
                ) : (
                    <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
                        {wallets.map((row) => (
                            <WalletCard
                                key={row.id}
                                copiedAddress={copiedAddress}
                                row={row}
                                settingDefaultId={settingDefaultId}
                                onCopy={copy}
                                onDelete={setDeleteTarget}
                                onEdit={openEdit}
                                onSetDefault={setAsDefault}
                            />
                        ))}
                    </div>
                )}
            </AppPage>
        </>
    );
}

BalanceWalletsPage.layout = {
    breadcrumbs: [
        { title: 'Inicio', href: dashboard() },
        { title: 'Mis balances', href: '/balances' },
        { title: 'Mis billeteras', href: '/balances/billeteras' },
    ],
};
