import { store } from '@/actions/App/Http/Controllers/Settings/AccountController';
import { store as storeBank } from '@/actions/App/Http/Controllers/Settings/BankController';
import {
    AccountForm,
    AccountFormData,
} from '@/components/accounts/account-form';
import { StepHeader } from '@/components/onboarding/step-header';
import { Button } from '@/components/ui/button';
import { CreatedAccount } from '@/hooks/use-onboarding-state';
import { encrypt, importKey } from '@/lib/crypto';
import { getStoredKey } from '@/lib/key-storage';
import { type AccountType, formatAccountType } from '@/types/account';
import { __ } from '@/utils/i18n';
import { AlertCircle, CheckCircle2, CreditCard } from 'lucide-react';
import { useCallback, useMemo, useRef, useState } from 'react';
import { StepButton } from './step-button';

interface ExistingAccount {
    id: string;
    name: string;
    name_iv: string;
    type: string;
    currency_code: string;
    bank_id: string;
    bank?: {
        id: string;
        name: string;
        logo: string | null;
    };
}

interface StepCreateAccountProps {
    banks: { id: string; name: string; logo: string | null }[];
    isFirstAccount: boolean;
    existingAccounts?: ExistingAccount[];
    onAccountCreated: (account: CreatedAccount) => void;
    onSkip?: () => void;
}

export function StepCreateAccount({
    isFirstAccount,
    existingAccounts = [],
    onAccountCreated,
    onSkip,
}: StepCreateAccountProps) {
    const [isSubmitting, setIsSubmitting] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const formDataRef = useRef<AccountFormData>({
        displayName: '',
        bankId: null,
        type: isFirstAccount ? 'checking' : null,
        currencyCode: null,
        customBank: null,
    });

    const handleFormChange = useCallback((data: AccountFormData) => {
        formDataRef.current = data;
    }, []);

    async function createBankAndGetId(): Promise<string | null> {
        const customBank = formDataRef.current.customBank;
        if (!customBank) return null;

        const formData = new FormData();
        formData.append('name', customBank.name);
        if (customBank.logo) {
            formData.append('logo', customBank.logo);
        }

        const response = await fetch(storeBank.url(), {
            method: 'POST',
            body: formData,
            headers: {
                'X-XSRF-TOKEN': decodeURIComponent(
                    document.cookie
                        .split('; ')
                        .find((row) => row.startsWith('XSRF-TOKEN='))
                        ?.split('=')[1] || '',
                ),
                Accept: 'application/json',
            },
        });

        if (!response.ok) {
            const errorData = await response.json();
            throw new Error(errorData.message || 'Failed to create bank');
        }

        const data = await response.json();
        return data.id;
    }

    async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
        event.preventDefault();
        setError(null);

        const { displayName, bankId, type, currencyCode, customBank } =
            formDataRef.current;

        const keyString = getStoredKey();
        if (!keyString) {
            setError(
                __(
                    'Encryption key not available. Please go back and set up encryption.',
                ),
            );
            return;
        }

        if (!displayName.trim()) {
            setError(__('Please enter an account name.'));
            return;
        }

        if (!type || !currencyCode) {
            setError(__('Please fill in all required fields.'));
            return;
        }

        if (isFirstAccount && type !== 'checking') {
            setError(__('Your first account must be a checking account.'));
            return;
        }

        setIsSubmitting(true);

        try {
            let finalBankId: string;

            if (customBank) {
                if (!customBank.name.trim()) {
                    setError(__('Please enter a bank name.'));
                    setIsSubmitting(false);
                    return;
                }
                const createdBankId = await createBankAndGetId();
                if (!createdBankId) {
                    throw new Error('Failed to create bank');
                }
                finalBankId = createdBankId;
            } else {
                if (!bankId) {
                    setError(__('Please select a bank.'));
                    setIsSubmitting(false);
                    return;
                }
                finalBankId = String(bankId);
            }

            const key = await importKey(keyString);
            const { encrypted, iv } = await encrypt(displayName, key);

            const response = await fetch(store.url(), {
                method: 'POST',
                body: JSON.stringify({
                    name: encrypted,
                    name_iv: iv,
                    bank_id: finalBankId,
                    type: type,
                    currency_code: currencyCode,
                }),
                headers: {
                    'Content-Type': 'application/json',
                    'X-XSRF-TOKEN': decodeURIComponent(
                        document.cookie
                            .split('; ')
                            .find((row) => row.startsWith('XSRF-TOKEN='))
                            ?.split('=')[1] || '',
                    ),
                    Accept: 'application/json',
                },
            });

            if (!response.ok) {
                const errorData = await response.json();
                throw new Error(
                    errorData.message ||
                        Object.values(errorData.errors || {})[0] ||
                        'Failed to create account',
                );
            }

            const accountData = await response.json();

            onAccountCreated({
                id: accountData.id || finalBankId,
                name: displayName,
                type: type,
                currencyCode: currencyCode,
            });
            setIsSubmitting(false);
        } catch (err) {
            console.error('Account creation failed:', err);
            setError(
                err instanceof Error
                    ? err.message
                    : __('Failed to create account. Please try again.'),
            );
            setIsSubmitting(false);
        }
    }

    const hasExistingAccounts = existingAccounts.length > 0;

    const { title, description } = useMemo(() => {
        if (hasExistingAccounts) {
            return {
                title: __('Your Accounts'),
                description: __(
                    "You already have accounts set up. Let's continue with the onboarding.",
                ),
            };
        }
        if (isFirstAccount) {
            return {
                title: __('Create an Account'),
                description: __(
                    "Let's start with your main checking account. You can add more accounts later.",
                ),
            };
        }
        return {
            title: __('Add Another Account'),
            description: __(
                'Add another account to track more of your finances.',
            ),
        };
    }, [hasExistingAccounts, isFirstAccount]);

    return (
        <div className="flex animate-in flex-col items-center duration-500 fade-in slide-in-from-bottom-4">
            <StepHeader
                icon={CreditCard}
                iconContainerClassName="bg-gradient-to-br from-emerald-400 to-teal-500"
                title={title}
                description={description}
            />

            {hasExistingAccounts ? (
                <div className="w-full max-w-md">
                    <div className="mb-6 space-y-2">
                        {existingAccounts.map((account) => (
                            <div
                                key={account.id}
                                className="flex items-center gap-3 rounded-lg border bg-card p-4"
                            >
                                <div className="flex h-10 w-10 items-center justify-center rounded-full bg-emerald-100 dark:bg-emerald-900/30">
                                    <CheckCircle2 className="h-5 w-5 text-emerald-600 dark:text-emerald-400" />
                                </div>
                                <div className="flex-1">
                                    <p className="font-medium">
                                        {account.bank?.name || 'Account'}
                                    </p>
                                    <p className="text-sm text-muted-foreground">
                                        {formatAccountType(
                                            account.type as AccountType,
                                        )}{' '}
                                        • {account.currency_code}
                                    </p>
                                </div>
                            </div>
                        ))}
                    </div>

                    <StepButton
                        text={__('Continue')}
                        className="w-full sm:w-full"
                        onClick={() =>
                            onAccountCreated({
                                id: existingAccounts[0].id,
                                name:
                                    existingAccounts[0].bank?.name || 'Account',
                                type: existingAccounts[0].type,
                                currencyCode: existingAccounts[0].currency_code,
                            })
                        }
                    />
                </div>
            ) : (
                <form
                    onSubmit={handleSubmit}
                    autoFocus
                    className="w-full max-w-md space-y-4"
                >
                    <AccountForm
                        forceAccountType={
                            isFirstAccount ? 'checking' : undefined
                        }
                        onChange={handleFormChange}
                    />

                    {isFirstAccount && (
                        <div className="rounded-lg border border-blue-100 bg-blue-50 p-3 text-sm dark:border-blue-900/50 dark:bg-blue-900/20">
                            <p className="text-center">
                                {__('Your first account must be a')}{' '}
                                <strong>{__('Checking')}</strong>{' '}
                                {__('account.')}
                            </p>
                        </div>
                    )}

                    {error && (
                        <div className="flex items-center gap-2 rounded-lg bg-destructive/10 p-3 text-sm text-destructive">
                            <AlertCircle className="h-4 w-4 shrink-0" />
                            {error}
                        </div>
                    )}

                    <StepButton
                        type="submit"
                        className="w-full sm:w-full"
                        disabled={isSubmitting}
                        loading={isSubmitting}
                        loadingText={__('Creating...')}
                        text={__('Create Account')}
                    />

                    {!isFirstAccount && onSkip && (
                        <Button
                            size="lg"
                            className="w-full opacity-50 transition-all duration-200 hover:opacity-100"
                            variant={'ghost'}
                            disabled={isSubmitting}
                            onClick={() => onSkip()}
                        >
                            {__('Ignore')}
                        </Button>
                    )}
                </form>
            )}
        </div>
    );
}
