import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { __ } from '@/utils/i18n';
import { ImagePlus, X } from 'lucide-react';
import { useCallback, useRef, useState } from 'react';

const MAX_FILE_SIZE = 500 * 1024; // 500KB
const MAX_DIMENSIONS = 500;

export interface CustomBankData {
    name: string;
    logo: File | null;
    logoPreview: string | null;
}

interface CustomBankFormProps {
    defaultName?: string;
    onCancel: () => void;
    onChange: (data: CustomBankData) => void;
    value: CustomBankData;
}

export function CustomBankForm({
    defaultName = '',
    onCancel,
    onChange,
    value,
}: CustomBankFormProps) {
    const [error, setError] = useState<string | null>(null);
    const fileInputRef = useRef<HTMLInputElement>(null);

    const validateImage = useCallback((file: File): Promise<string | null> => {
        return new Promise((resolve) => {
            if (file.size > MAX_FILE_SIZE) {
                resolve(
                    `File size must be less than ${MAX_FILE_SIZE / 1024}KB`,
                );
                return;
            }

            const img = new Image();
            const objectUrl = URL.createObjectURL(file);

            img.onload = () => {
                URL.revokeObjectURL(objectUrl);

                if (img.width !== img.height) {
                    resolve('Image must be square (same width and height)');
                    return;
                }

                if (img.width > MAX_DIMENSIONS) {
                    resolve(
                        `Image dimensions must be ${MAX_DIMENSIONS}x${MAX_DIMENSIONS} pixels or smaller`,
                    );
                    return;
                }

                resolve(null);
            };

            img.onerror = () => {
                URL.revokeObjectURL(objectUrl);
                resolve('Invalid image file');
            };

            img.src = objectUrl;
        });
    }, []);

    const handleFileChange = useCallback(
        async (e: React.ChangeEvent<HTMLInputElement>) => {
            const file = e.target.files?.[0];
            setError(null);

            if (!file) {
                onChange({ ...value, logo: null, logoPreview: null });
                return;
            }

            const validationError = await validateImage(file);
            if (validationError) {
                setError(validationError);
                e.target.value = '';
                return;
            }

            const preview = URL.createObjectURL(file);
            onChange({ ...value, logo: file, logoPreview: preview });
        },
        [onChange, validateImage, value],
    );

    const handleNameChange = useCallback(
        (e: React.ChangeEvent<HTMLInputElement>) => {
            onChange({ ...value, name: e.target.value });
        },
        [onChange, value],
    );

    return (
        <>
            <Button
                type="button"
                variant="link"
                size="sm"
                onClick={onCancel}
                className="float-right -mr-2 ml-auto cursor-pointer"
            >
                <X className="size-4" />
            </Button>

            <div className="mt-1 space-y-2 rounded-sm border border-border p-3">
                <div className="space-y-2">
                    <Label htmlFor="bank_name">{__('Bank name')}</Label>
                    <Input
                        id="bank_name"
                        placeholder={__('Bank name')}
                        defaultValue={defaultName}
                        value={value.name}
                        className="mt-1"
                        onChange={handleNameChange}
                        required
                    />
                </div>

                <div className="space-y-2">
                    <Label htmlFor="bank_logo">{__('Logo')}</Label>
                    <div className="mt-1 flex items-center gap-2">
                        <Input
                            ref={fileInputRef}
                            type="file"
                            id="bank_logo"
                            accept="image/png,image/jpeg,image/webp"
                            onChange={handleFileChange}
                        />

                        <button
                            type="button"
                            onClick={() => fileInputRef.current?.click()}
                            className="flex aspect-square h-9 w-9 items-center justify-center rounded-lg border border-muted-foreground/25 transition-colors hover:border-muted-foreground/50"
                        >
                            {value.logoPreview ? (
                                <img
                                    src={value.logoPreview}
                                    alt={__('Bank logo preview')}
                                    className="size-5 rounded-full object-contain"
                                />
                            ) : (
                                <ImagePlus className="size-4 text-muted-foreground" />
                            )}
                        </button>
                    </div>
                    <div className="text-xs text-muted-foreground">
                        <p>
                            {__('Square images only (max')}
                            {MAX_DIMENSIONS}x{MAX_DIMENSIONS}
                            {__('px) /')}
                            {MAX_FILE_SIZE / 1024}
                            {__('KB max.')}
                        </p>
                    </div>
                    {error && (
                        <p className="text-sm text-destructive">{error}</p>
                    )}
                </div>
            </div>
        </>
    );
}
