import {
    index,
    store,
} from '@/actions/App/Http/Controllers/AccountBalanceController';
import { AmountInput } from '@/components/ui/amount-input';
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 type { Account, AccountBalance } from '@/types/account';
import { __ } from '@/utils/i18n';
import { useEffect, useRef, useState } from 'react';

interface UpdateBalanceDialogProps {
    account: Account;
    open: boolean;
    onOpenChange: (open: boolean) => void;
    onSuccess?: () => void;
}

function getTodayDate(): string {
    const today = new Date();
    return today.toISOString().split('T')[0];
}

interface PaginatedBalanceResponse {
    data: AccountBalance[];
}

export function UpdateBalanceDialog({
    account,
    open,
    onOpenChange,
    onSuccess,
}: UpdateBalanceDialogProps) {
    const [date, setDate] = useState(getTodayDate());
    const [balance, setBalance] = useState(0);
    const [isSubmitting, setIsSubmitting] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [isLoadingLastBalance, setIsLoadingLastBalance] = useState(false);
    const inputRef = useRef<HTMLInputElement>(null);

    useEffect(() => {
        async function fetchLastBalance() {
            if (!open) return;

            setIsLoadingLastBalance(true);
            try {
                const response = await fetch(
                    index.url(account.id, { query: { page: '1' } }),
                    {
                        headers: {
                            Accept: 'application/json',
                        },
                    },
                );

                if (!response.ok) {
                    throw new Error('Failed to fetch last balance');
                }

                const data: PaginatedBalanceResponse = await response.json();
                if (data.data.length > 0) {
                    setBalance(data.data[0].balance);
                } else {
                    setBalance(0);
                }
            } catch (err) {
                console.error('Failed to fetch last balance:', err);
                setBalance(0);
            } finally {
                setIsLoadingLastBalance(false);
            }
        }

        if (open) {
            setDate(getTodayDate());
            setError(null);
            fetchLastBalance();
        }
    }, [open, account.id]);

    useEffect(() => {
        if (open && !isLoadingLastBalance && inputRef.current) {
            setTimeout(() => {
                const input = inputRef.current;
                if (input) {
                    input.focus();
                    // Use requestAnimationFrame to ensure selection happens after focus events
                    requestAnimationFrame(() => {
                        input.setSelectionRange(0, input.value.length);
                    });
                }
            }, 100);
        }
    }, [open, isLoadingLastBalance]);

    function handleOpenChange(newOpen: boolean) {
        onOpenChange(newOpen);
    }

    async function handleSubmit(e: React.FormEvent) {
        e.preventDefault();
        setIsSubmitting(true);
        setError(null);

        try {
            const response = await fetch(store.url(account.id), {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-XSRF-TOKEN': decodeURIComponent(
                        document.cookie
                            .split('; ')
                            .find((row) => row.startsWith('XSRF-TOKEN='))
                            ?.split('=')[1] || '',
                    ),
                    Accept: 'application/json',
                },
                body: JSON.stringify({
                    balance_date: date,
                    balance: balance,
                }),
            });

            if (!response.ok) {
                const data = await response.json();
                throw new Error(data.message || 'Failed to update balance');
            }

            handleOpenChange(false);
            onSuccess?.();
        } catch (err) {
            setError(
                err instanceof Error ? err.message : 'Failed to update balance',
            );
        } finally {
            setIsSubmitting(false);
        }
    }

    return (
        <Dialog open={open} onOpenChange={handleOpenChange}>
            <DialogContent hasKeyboard className="sm:max-w-[400px]">
                <DialogHeader>
                    <DialogTitle>{__('Update balance')}</DialogTitle>
                    <DialogDescription>
                        {__(
                            'Set the balance for this account on a specific date.',
                        )}
                    </DialogDescription>
                </DialogHeader>

                <form onSubmit={handleSubmit} className="space-y-4">
                    <div className="space-y-2">
                        <Label htmlFor="balance-amount">{__('Balance')}</Label>
                        {isLoadingLastBalance ? (
                            <div className="flex h-10 items-center rounded-md border border-input bg-muted px-3 text-sm text-muted-foreground">
                                {__('Loading last balance...')}
                            </div>
                        ) : (
                            <AmountInput
                                ref={inputRef}
                                id="balance-amount"
                                className="mt-1"
                                value={balance}
                                onChange={setBalance}
                                currencyCode={account.currency_code}
                                required
                            />
                        )}
                    </div>

                    <div className="space-y-2">
                        <Label htmlFor="balance-date">{__('Date')}</Label>
                        <Input
                            id="balance-date"
                            type="date"
                            className="mt-1"
                            value={date}
                            onChange={(e) => setDate(e.target.value)}
                            required
                        />
                    </div>

                    {error && (
                        <p className="text-sm text-destructive">{error}</p>
                    )}

                    <DialogFooter>
                        <Button
                            type="button"
                            variant="outline"
                            onClick={() => handleOpenChange(false)}
                            disabled={isSubmitting || isLoadingLastBalance}
                        >
                            {__('Cancel')}
                        </Button>
                        <Button
                            type="submit"
                            disabled={isSubmitting || isLoadingLastBalance}
                        >
                            {isSubmitting
                                ? __('Saving...')
                                : isLoadingLastBalance
                                  ? __('Loading...')
                                  : __('Save')}
                        </Button>
                    </DialogFooter>
                </form>
            </DialogContent>
        </Dialog>
    );
}
