import React, { useEffect, useMemo, useState } from 'react';
import { RequiredModalProps } from '@/components/elements/Modal';
import { Dialog } from '@/components/elements/dialog';
import { Button } from '@/components/elements/button';
import Label from '@/components/elements/Label';
import Input from '@/components/elements/Input';
import FlashMessageRender from '@/components/FlashMessageRender';
import GreyRowBox from '@/components/elements/GreyRowBox';
import tw from 'twin.macro';
import useFlash from '@/plugins/useFlash';
import { httpErrorToHuman } from '@/api/http';
import { ServerContext } from '@/state/server';
import uploadDatabase from './api/uploadDatabase';
import analyzeFile, { AnalyzedTable } from './api/analyzeFile';
import analyzeExternalDatabase from './api/analyzeExternalDatabase';
import getImportPreview, { ImportPreviewProgress, ImportPreviewResult } from './api/getImportPreview';
import getImportJobStatus, { ImportJobStatus } from './api/getImportJobStatus';

type ImportType = 'file' | 'credentials';
type ImportMode = 'wipe' | 'merge';

type Props = RequiredModalProps & {
    databaseId: string;
    engine?: 'mysql' | 'postgresql' | 'mongodb' | string;
};

interface SourceCredentials {
    engine: 'mysql' | 'postgresql' | 'mongodb';
    host: string;
    port: string;
    username: string;
    password: string;
    database: string;
}

const FLASH_KEY = 'database:import';
const LARGE_FILE_ANALYZE_LIMIT = 25 * 1024 * 1024;

const defaultCredentials: SourceCredentials = {
    engine: 'mysql',
    host: '',
    port: '3306',
    username: '',
    password: '',
    database: '',
};

const credentialsForEngine = (engine?: string): SourceCredentials => ({
    ...defaultCredentials,
    engine: engine === 'postgresql' || engine === 'mongodb' ? engine : 'mysql',
    port: engine === 'postgresql' ? '5432' : engine === 'mongodb' ? '27017' : '3306',
});

const ImportDatabaseModal = ({ databaseId, engine = 'mysql', visible, onDismissed }: Props) => {
    const uuid = ServerContext.useStoreState((state) => state.server.data!.uuid);
    const { clearFlashes, addError } = useFlash();

    const [isSubmitting, setIsSubmitting] = useState(false);
    const [isAnalyzingFile, setIsAnalyzingFile] = useState(false);
    const [isAnalyzingExternal, setIsAnalyzingExternal] = useState(false);
    const [isGeneratingPreview, setIsGeneratingPreview] = useState(false);

    const [importType, setImportType] = useState<ImportType>('file');
    const [mode, setMode] = useState<ImportMode>('merge');
    const [force, setForce] = useState(false);
    const [selective, setSelective] = useState(false);

    const [file, setFile] = useState<File | null>(null);
    const [credentials, setCredentials] = useState<SourceCredentials>(defaultCredentials);

    const [fileTables, setFileTables] = useState<AnalyzedTable[]>([]);
    const [externalTables, setExternalTables] = useState<AnalyzedTable[]>([]);
    const [selectedTables, setSelectedTables] = useState<string[]>([]);
    const [selectedColumns, setSelectedColumns] = useState<Record<string, string[]>>({});
    const [expandedTables, setExpandedTables] = useState<string[]>([]);

    const [manualTablesInput, setManualTablesInput] = useState('');
    const [manualColumnsInput, setManualColumnsInput] = useState<Record<string, string>>({});

    const [preview, setPreview] = useState<ImportPreviewResult | null>(null);
    const [previewProgress, setPreviewProgress] = useState<ImportPreviewProgress | null>(null);
    const [importNotice, setImportNotice] = useState<string | null>(null);
    const [uploadProgress, setUploadProgress] = useState<number | null>(null);
    const [queuedJobId, setQueuedJobId] = useState<string | null>(null);
    const [importJobStatus, setImportJobStatus] = useState<ImportJobStatus | null>(null);

    useEffect(() => {
        if (!visible) {
            setIsSubmitting(false);
            setIsAnalyzingFile(false);
            setIsAnalyzingExternal(false);
            setIsGeneratingPreview(false);
            setImportType('file');
            setMode('merge');
            setForce(false);
            setSelective(false);
            setFile(null);
            setCredentials(credentialsForEngine(engine));
            setFileTables([]);
            setExternalTables([]);
            setSelectedTables([]);
            setSelectedColumns({});
            setExpandedTables([]);
            setManualTablesInput('');
            setManualColumnsInput({});
            setPreview(null);
            setPreviewProgress(null);
            setImportNotice(null);
            setUploadProgress(null);
            setQueuedJobId(null);
            setImportJobStatus(null);
        }
    }, [visible, engine]);

    useEffect(() => {
        setSelectedTables([]);
        setSelectedColumns({});
        setExpandedTables([]);
        setPreview(null);
        setPreviewProgress(null);
        setImportNotice(null);
        setUploadProgress(null);
        setQueuedJobId(null);
        setImportJobStatus(null);
    }, [importType]);

    useEffect(() => {
        setPreview(null);
        setPreviewProgress(null);
    }, [selective, file]);

    useEffect(() => {
        if (
            !visible ||
            !queuedJobId ||
            importJobStatus?.status === 'completed' ||
            importJobStatus?.status === 'failed'
        ) {
            return;
        }

        let mounted = true;

        const refreshStatus = () => {
            getImportJobStatus(uuid, databaseId, queuedJobId)
                .then((status) => {
                    if (!mounted) {
                        return;
                    }

                    setImportJobStatus(status);
                    setImportNotice(
                        status.status === 'queued'
                            ? 'Import queued.'
                            : status.status === 'processing'
                            ? 'Import running...'
                            : status.status === 'completed'
                            ? 'Import complete.'
                            : status.force_recommended
                            ? 'Retry with Force enabled.'
                            : status.message
                    );
                })
                .catch((error) => {
                    if (!mounted) {
                        return;
                    }

                    setImportNotice(httpErrorToHuman(error));
                });
        };

        refreshStatus();
        const interval = window.setInterval(refreshStatus, 3000);

        return () => {
            mounted = false;
            window.clearInterval(interval);
        };
    }, [visible, queuedJobId, importJobStatus?.status, uuid, databaseId]);

    const dismiss = () => {
        clearFlashes(FLASH_KEY);
        onDismissed();
    };

    const activeTables = importType === 'file' ? fileTables : externalTables;

    const manualTables = useMemo(
        () =>
            Array.from(
                new Set(
                    manualTablesInput
                        .split(',')
                        .map((value) => value.trim())
                        .filter(Boolean)
                )
            ),
        [manualTablesInput]
    );

    const hasCredentialFields = useMemo(
        () =>
            !!(
                credentials.host.trim() &&
                credentials.port.trim() &&
                credentials.username.trim() &&
                credentials.password.trim() &&
                credentials.database.trim()
            ),
        [credentials]
    );

    const selectedTableCount = useMemo(() => {
        if (!selective) return 0;

        if (selectedTables.length > 0) return selectedTables.length;

        return importType === 'credentials' ? manualTables.length : 0;
    }, [selective, selectedTables.length, importType, manualTables.length]);

    const canSubmit = useMemo(() => {
        if (isSubmitting || isAnalyzingFile || isAnalyzingExternal || isGeneratingPreview) {
            return false;
        }

        if (importType === 'file' && !file) {
            return false;
        }

        if (importType === 'credentials' && !hasCredentialFields) {
            return false;
        }

        if (selective && selectedTableCount < 1) {
            return false;
        }

        return true;
    }, [
        isSubmitting,
        isAnalyzingFile,
        isAnalyzingExternal,
        isGeneratingPreview,
        importType,
        file,
        hasCredentialFields,
        selective,
        selectedTableCount,
    ]);

    const analyzeSelectedFile = async (nextFile: File) => {
        clearFlashes(FLASH_KEY);

        if (engine === 'mongodb') {
            setImportNotice('MongoDB archives are queued directly. Select collections manually for selective imports.');
            setFileTables([]);
            setSelectedTables([]);
            setSelectedColumns({});
            setExpandedTables([]);
            setQueuedJobId(null);
            setImportJobStatus(null);
            return;
        }

        if (nextFile.size > LARGE_FILE_ANALYZE_LIMIT) {
            setImportNotice('Large file selected. Preview or import will run in the background.');
            setFileTables([]);
            setSelectedTables([]);
            setSelectedColumns({});
            setExpandedTables([]);
            setQueuedJobId(null);
            setImportJobStatus(null);
            return;
        }

        setIsAnalyzingFile(true);

        try {
            const result = await analyzeFile(uuid, databaseId, nextFile);
            const tables = result.tables || [];
            setFileTables(tables);
            setSelectedTables(tables.map((table) => table.name));
            setSelectedColumns({});
            setExpandedTables([]);
        } catch (error) {
            addError({ key: FLASH_KEY, message: httpErrorToHuman(error) });
            setFileTables([]);
            setSelectedTables([]);
            setSelectedColumns({});
            setExpandedTables([]);
        }

        setIsAnalyzingFile(false);
    };

    const analyzeCredentials = async () => {
        if (!hasCredentialFields) return;

        clearFlashes(FLASH_KEY);
        setIsAnalyzingExternal(true);

        try {
            const result = await analyzeExternalDatabase(uuid, databaseId, {
                engine: credentials.engine,
                host: credentials.host.trim(),
                port: Number(credentials.port),
                username: credentials.username.trim(),
                password: credentials.password,
                database: credentials.database.trim(),
            });

            if (!result.success) {
                throw new Error(result.error || 'Failed to analyze external database.');
            }

            const tables: AnalyzedTable[] = (result.tables || []).map((table) => ({
                name: table.name,
                estimated_rows: table.rows,
                has_data: table.has_data,
                primary_keys: table.columns
                    .filter((column) => column.column_key === 'PRI')
                    .map((column) => column.column_name),
                columns: table.columns.map((column) => ({
                    name: column.column_name,
                    type: column.data_type,
                    nullable: column.is_nullable,
                    default: column.column_default,
                    auto_increment: column.extra.includes('auto_increment'),
                })),
            }));

            setExternalTables(tables);
            setSelectedTables(tables.map((table) => table.name));
            setSelectedColumns({});
            setExpandedTables([]);
            setManualTablesInput(tables.map((table) => table.name).join(','));
        } catch (error) {
            addError({ key: FLASH_KEY, message: httpErrorToHuman(error) });
            setExternalTables([]);
            setSelectedTables([]);
            setSelectedColumns({});
            setExpandedTables([]);
        }

        setIsAnalyzingExternal(false);
    };

    const generatePreview = async () => {
        if (!file) return;

        clearFlashes(FLASH_KEY);
        setIsGeneratingPreview(true);
        setPreviewProgress({
            preview_id: '',
            status: 'waiting',
            percent: 0,
            message: 'Starting preview...',
        });

        try {
            const previewTables = selective ? selectedTables : fileTables.map((table) => table.name);

            const result = await getImportPreview(uuid, databaseId, file, previewTables, {
                onProgress: setPreviewProgress,
            });

            if (result.selected_tables.length > 0) {
                setFileTables(result.selected_tables);
                setSelectedTables((current) =>
                    current.length > 0 ? current : result.selected_tables.map((table) => table.name)
                );
            }

            setPreview(result);
        } catch (error) {
            addError({ key: FLASH_KEY, message: httpErrorToHuman(error) });
            setPreview(null);
        }

        setIsGeneratingPreview(false);
    };

    const toggleTable = (tableName: string) => {
        setSelectedTables((current) => {
            if (current.includes(tableName)) {
                const next = current.filter((table) => table !== tableName);
                setSelectedColumns((columns) => {
                    const copy = { ...columns };
                    delete copy[tableName];
                    return copy;
                });
                return next;
            }

            return [...current, tableName];
        });
        setPreview(null);
        setPreviewProgress(null);
    };

    const toggleTableExpanded = (tableName: string) => {
        setExpandedTables((current) =>
            current.includes(tableName) ? current.filter((table) => table !== tableName) : [...current, tableName]
        );
    };

    const toggleColumn = (tableName: string, columnName: string) => {
        setSelectedColumns((current) => {
            const existing = current[tableName] || [];
            const next = existing.includes(columnName)
                ? existing.filter((column) => column !== columnName)
                : [...existing, columnName];

            if (next.length < 1) {
                const copy = { ...current };
                delete copy[tableName];
                return copy;
            }

            return { ...current, [tableName]: next };
        });
        setPreview(null);
        setPreviewProgress(null);
    };

    const onSubmit = async () => {
        clearFlashes(FLASH_KEY);
        setIsSubmitting(true);
        setImportNotice(importType === 'file' ? 'Uploading...' : null);
        setUploadProgress(importType === 'file' ? 0 : null);
        setQueuedJobId(null);
        setImportJobStatus(null);

        try {
            const payload: {
                file?: File;
                mode: ImportMode;
                force?: boolean;
                import_type: ImportType;
                selective?: boolean;
                selected_tables?: string[];
                selected_columns?: Record<string, string[]>;
                source_credentials?: {
                    engine: 'mysql' | 'postgresql' | 'mongodb';
                    host: string;
                    port: number;
                    username: string;
                    password: string;
                    database: string;
                };
            } = {
                mode,
                import_type: importType,
                force,
                selective,
            };

            if (importType === 'file' && file) {
                payload.file = file;
            }

            if (importType === 'credentials') {
                payload.source_credentials = {
                    engine: credentials.engine,
                    host: credentials.host.trim(),
                    port: Number(credentials.port),
                    username: credentials.username.trim(),
                    password: credentials.password,
                    database: credentials.database.trim(),
                };
            }

            if (selective) {
                if (selectedTables.length > 0) {
                    payload.selected_tables = selectedTables;
                    payload.selected_columns = selectedColumns;
                } else {
                    payload.selected_tables = manualTables;
                    payload.selected_columns = manualTables.reduce<Record<string, string[]>>((acc, tableName) => {
                        const columns = (manualColumnsInput[tableName] || '')
                            .split(',')
                            .map((value) => value.trim())
                            .filter(Boolean);

                        if (columns.length > 0) {
                            acc[tableName] = columns;
                        }

                        return acc;
                    }, {});
                }
            }

            const response = await uploadDatabase(uuid, databaseId, payload, {
                onUploadProgress: ({ percent }) => {
                    if (percent === undefined) {
                        setImportNotice('Uploading...');
                        return;
                    }

                    setUploadProgress(percent);
                    setImportNotice(percent >= 100 ? 'Queueing import...' : `Uploading... ${percent}%`);
                },
            });

            if (response.queued) {
                setUploadProgress(null);

                if (response.job_id) {
                    setQueuedJobId(response.job_id);
                    setImportJobStatus({
                        job_id: response.job_id,
                        status: 'queued',
                        message: 'Import queued.',
                        database_id: 0,
                        updated_at: new Date().toISOString(),
                    });
                }

                setImportNotice('Import queued.');
                setIsSubmitting(false);
                return;
            }

            dismiss();
        } catch (error) {
            addError({ key: FLASH_KEY, message: httpErrorToHuman(error) });
            setIsSubmitting(false);
            setUploadProgress(null);
        }
    };

    return (
        <Dialog
            open={visible}
            onClose={dismiss}
            preventExternalClose={isSubmitting || isAnalyzingFile || isAnalyzingExternal || isGeneratingPreview}
            title={'Import database'}
            description={`Target: ${databaseId}`}
        >
            <div className={'mt-6 space-y-4'}>
                <FlashMessageRender byKey={FLASH_KEY} css={tw`mb-2`} />

                {importNotice && (
                    <GreyRowBox $hoverable={false} css={tw`block p-3 border border-neutral-600 bg-neutral-700`}>
                        <p css={tw`text-sm font-semibold text-neutral-100`}>
                            {uploadProgress !== null
                                ? 'Uploading'
                                : importJobStatus?.status === 'completed'
                                ? 'Complete'
                                : importJobStatus?.status === 'failed'
                                ? importJobStatus.force_recommended
                                    ? 'Failed - try Force'
                                    : 'Failed'
                                : importJobStatus?.status === 'processing'
                                ? 'Running'
                                : 'Queued'}
                        </p>
                        <p css={tw`text-xs text-neutral-300 mt-1`}>{importNotice}</p>
                        {uploadProgress !== null && (
                            <div css={tw`mt-3 h-2 overflow-hidden rounded bg-neutral-800 border border-neutral-600`}>
                                <div
                                    css={tw`h-full bg-primary-500 transition-all duration-200`}
                                    style={{ width: `${uploadProgress}%` }}
                                />
                            </div>
                        )}
                        {queuedJobId && <p css={tw`text-xs text-neutral-400 mt-2 font-mono`}>Job: {queuedJobId}</p>}
                    </GreyRowBox>
                )}

                <GreyRowBox $hoverable={false} css={tw`block p-4`}>
                    <div css={tw`grid grid-cols-1 sm:grid-cols-2 gap-4`}>
                        <div>
                            <Label>Import source</Label>
                            <div css={tw`grid grid-cols-2 gap-2`}>
                                <Button
                                    type={'button'}
                                    size={Button.Sizes.Small}
                                    variant={
                                        importType === 'file' ? Button.Variants.Primary : Button.Variants.Secondary
                                    }
                                    className={'!h-9'}
                                    onClick={() => setImportType('file')}
                                >
                                    File
                                </Button>
                                <Button
                                    type={'button'}
                                    size={Button.Sizes.Small}
                                    variant={
                                        importType === 'credentials'
                                            ? Button.Variants.Primary
                                            : Button.Variants.Secondary
                                    }
                                    className={'!h-9'}
                                    onClick={() => setImportType('credentials')}
                                >
                                    Credentials
                                </Button>
                            </div>
                        </div>

                        <div>
                            <Label>Import mode</Label>
                            <div css={tw`grid grid-cols-2 gap-2`}>
                                <Button
                                    type={'button'}
                                    size={Button.Sizes.Small}
                                    variant={mode === 'merge' ? Button.Variants.Primary : Button.Variants.Secondary}
                                    className={'!h-9'}
                                    onClick={() => setMode('merge')}
                                >
                                    Merge
                                </Button>
                                <Button
                                    type={'button'}
                                    size={Button.Sizes.Small}
                                    variant={mode === 'wipe' ? Button.Variants.Primary : Button.Variants.Secondary}
                                    className={'!h-9'}
                                    onClick={() => setMode('wipe')}
                                >
                                    Wipe
                                </Button>
                            </div>
                        </div>
                    </div>

                    <p css={tw`text-xs text-neutral-400 mt-3`}>Merge keeps existing data. Wipe clears it first.</p>
                </GreyRowBox>

                <div css={tw`grid grid-cols-1 sm:grid-cols-2 gap-2`}>
                    <GreyRowBox $hoverable={false} css={tw`px-3 py-2`}>
                        <Input
                            id={'import-force-toggle'}
                            type={'checkbox'}
                            checked={force}
                            onChange={(event) => setForce(event.currentTarget.checked)}
                        />
                        <Label htmlFor={'import-force-toggle'} css={tw`ml-3 mb-0`}>
                            Force import
                        </Label>
                    </GreyRowBox>

                    <GreyRowBox $hoverable={false} css={tw`px-3 py-2`}>
                        <Input
                            id={'import-selective-toggle'}
                            type={'checkbox'}
                            checked={selective}
                            onChange={(event) => setSelective(event.currentTarget.checked)}
                        />
                        <Label htmlFor={'import-selective-toggle'} css={tw`ml-3 mb-0`}>
                            Selective import
                        </Label>
                    </GreyRowBox>
                </div>

                {!force && (
                    <p css={tw`text-xs text-neutral-400 -mt-1`}>
                        Use Force if the dump stops on duplicate objects, ordering errors, or unsupported statements.
                    </p>
                )}

                {importType === 'file' ? (
                    <GreyRowBox $hoverable={false} css={tw`block p-4`}>
                        <Label htmlFor={'import_database_file'}>Import file</Label>
                        <Input
                            id={'import_database_file'}
                            type={'file'}
                            accept={'.sql,.sql.gz,.zip,.gz,.bz2,.tar,.7z,.rar,.archive,.archive.gz'}
                            onChange={(event) => {
                                const nextFile = event.currentTarget.files?.[0] || null;
                                setFile(nextFile);
                                setFileTables([]);
                                setSelectedTables([]);
                                setSelectedColumns({});
                                setExpandedTables([]);
                                setPreview(null);
                                setUploadProgress(null);

                                if (nextFile) {
                                    analyzeSelectedFile(nextFile);
                                }
                            }}
                        />
                        <p className={'input-help'}>
                            {isAnalyzingFile ? 'Reading file structure...' : file ? file.name : 'SQL dump or archive.'}
                        </p>
                        <div css={tw`mt-3 flex justify-end`}>
                            <Button
                                type={'button'}
                                size={Button.Sizes.Small}
                                variant={Button.Variants.Secondary}
                                disabled={!file || isGeneratingPreview || isAnalyzingFile}
                                onClick={generatePreview}
                            >
                                {isGeneratingPreview ? 'Previewing...' : 'Generate Preview'}
                            </Button>
                        </div>
                    </GreyRowBox>
                ) : (
                    <GreyRowBox $hoverable={false} css={tw`block p-4`}>
                        <div css={tw`grid grid-cols-1 sm:grid-cols-2 gap-4`}>
                            <div css={tw`sm:col-span-2`}>
                                <Label>Source engine</Label>
                                <div css={tw`grid grid-cols-3 gap-2`}>
                                    {[
                                        { id: 'mysql', label: 'MySQL', port: '3306' },
                                        { id: 'postgresql', label: 'PostgreSQL', port: '5432' },
                                        { id: 'mongodb', label: 'MongoDB', port: '27017' },
                                    ].map((engine) => (
                                        <Button
                                            key={engine.id}
                                            type={'button'}
                                            size={Button.Sizes.Small}
                                            variant={
                                                credentials.engine === engine.id
                                                    ? Button.Variants.Primary
                                                    : Button.Variants.Secondary
                                            }
                                            className={'!h-9 !px-2'}
                                            onClick={() =>
                                                setCredentials((current) => ({
                                                    ...current,
                                                    engine: engine.id as SourceCredentials['engine'],
                                                    port: ['3306', '5432', '27017'].includes(current.port)
                                                        ? engine.port
                                                        : current.port,
                                                }))
                                            }
                                        >
                                            {engine.label}
                                        </Button>
                                    ))}
                                </div>
                            </div>
                            <div css={tw`sm:col-span-2`}>
                                <Label htmlFor={'source_host'}>Source host</Label>
                                <Input
                                    id={'source_host'}
                                    value={credentials.host}
                                    onChange={(event) =>
                                        setCredentials({ ...credentials, host: event.currentTarget.value })
                                    }
                                    placeholder={'127.0.0.1'}
                                />
                            </div>
                            <div>
                                <Label htmlFor={'source_port'}>Port</Label>
                                <Input
                                    id={'source_port'}
                                    type={'number'}
                                    min={1}
                                    max={65535}
                                    value={credentials.port}
                                    onChange={(event) =>
                                        setCredentials({ ...credentials, port: event.currentTarget.value })
                                    }
                                />
                            </div>
                            <div>
                                <Label htmlFor={'source_db'}>Database name</Label>
                                <Input
                                    id={'source_db'}
                                    value={credentials.database}
                                    onChange={(event) =>
                                        setCredentials({ ...credentials, database: event.currentTarget.value })
                                    }
                                />
                            </div>
                            <div>
                                <Label htmlFor={'source_user'}>Username</Label>
                                <Input
                                    id={'source_user'}
                                    value={credentials.username}
                                    onChange={(event) =>
                                        setCredentials({ ...credentials, username: event.currentTarget.value })
                                    }
                                />
                            </div>
                            <div>
                                <Label htmlFor={'source_pass'}>Password</Label>
                                <Input
                                    id={'source_pass'}
                                    type={'password'}
                                    value={credentials.password}
                                    onChange={(event) =>
                                        setCredentials({ ...credentials, password: event.currentTarget.value })
                                    }
                                />
                            </div>
                        </div>

                        <div css={tw`mt-3 flex justify-end`}>
                            <Button
                                type={'button'}
                                size={Button.Sizes.Small}
                                variant={Button.Variants.Secondary}
                                disabled={!hasCredentialFields || isAnalyzingExternal}
                                onClick={analyzeCredentials}
                            >
                                {isAnalyzingExternal ? 'Analyzing Source...' : 'Analyze Source Database'}
                            </Button>
                        </div>
                    </GreyRowBox>
                )}

                {preview && importType === 'file' && (
                    <GreyRowBox $hoverable={false} css={tw`block p-3`}>
                        <div css={tw`grid grid-cols-2 sm:grid-cols-4 gap-3 text-xs`}>
                            <div>
                                <p css={tw`text-neutral-400`}>Preview Tables</p>
                                <p css={tw`text-neutral-100`}>{preview.total_tables}</p>
                            </div>
                            <div>
                                <p css={tw`text-neutral-400`}>Estimated Rows</p>
                                <p css={tw`text-neutral-100`}>{preview.total_estimated_rows}</p>
                            </div>
                            <div>
                                <p css={tw`text-neutral-400`}>File</p>
                                <p css={tw`text-neutral-100 truncate`}>{preview.file_info.name}</p>
                            </div>
                            <div>
                                <p css={tw`text-neutral-400`}>Preview Selected</p>
                                <p css={tw`text-neutral-100`}>{preview.selected_tables.length}</p>
                            </div>
                        </div>
                    </GreyRowBox>
                )}

                {preview && importType === 'file' && preview.selected_tables.length > 0 && (
                    <GreyRowBox $hoverable={false} css={tw`block p-3`}>
                        <div css={tw`mb-3 flex items-center justify-between`}>
                            <Label css={tw`mb-0`}>Previewed tables</Label>
                            <span css={tw`text-xs text-neutral-400`}>{preview.selected_tables.length}</span>
                        </div>
                        <div css={tw`max-h-72 overflow-y-auto border border-neutral-600 rounded`}>
                            {preview.selected_tables.map((table) => {
                                const isExpanded = expandedTables.includes(table.name);

                                return (
                                    <div
                                        key={`preview_${table.name}`}
                                        css={tw`border-b border-neutral-600 last:border-b-0`}
                                    >
                                        <div css={tw`flex items-center justify-between gap-3 px-3 py-2`}>
                                            <div css={tw`min-w-0`}>
                                                <p css={tw`text-sm font-medium text-neutral-100 truncate`}>
                                                    {table.name}
                                                </p>
                                                <p css={tw`text-xs text-neutral-400`}>
                                                    {table.columns.length} columns, ~{table.estimated_rows} rows
                                                </p>
                                            </div>
                                            <Button
                                                type={'button'}
                                                size={Button.Sizes.Small}
                                                variant={Button.Variants.Secondary}
                                                disabled={table.columns.length < 1}
                                                onClick={() => toggleTableExpanded(table.name)}
                                            >
                                                {isExpanded ? 'Hide' : 'Columns'}
                                            </Button>
                                        </div>

                                        {isExpanded && (
                                            <div css={tw`px-3 pb-3`}>
                                                <div css={tw`grid grid-cols-1 sm:grid-cols-2 gap-2`}>
                                                    {table.columns.map((column) => (
                                                        <div
                                                            key={`${table.name}_${column.name}`}
                                                            css={tw`rounded border border-neutral-600 px-2 py-1 text-xs`}
                                                        >
                                                            <span css={tw`text-neutral-100`}>{column.name}</span>
                                                            <span css={tw`ml-2 text-neutral-400`}>{column.type}</span>
                                                        </div>
                                                    ))}
                                                </div>
                                            </div>
                                        )}
                                    </div>
                                );
                            })}
                        </div>
                    </GreyRowBox>
                )}

                {isGeneratingPreview && previewProgress && (
                    <GreyRowBox $hoverable={false} css={tw`block p-4 border border-neutral-600`}>
                        <div css={tw`flex items-center justify-between`}>
                            <p css={tw`text-sm font-semibold text-neutral-100`}>Generating preview</p>
                            <span css={tw`text-xs text-neutral-400`}>{previewProgress.percent}%</span>
                        </div>
                        <p css={tw`text-xs text-neutral-300 mt-1`}>{previewProgress.message}</p>
                        <div css={tw`mt-3 h-2 overflow-hidden rounded bg-neutral-800 border border-neutral-600`}>
                            <div
                                css={tw`h-full bg-primary-500 transition-all duration-200`}
                                style={{ width: `${previewProgress.percent}%` }}
                            />
                        </div>
                    </GreyRowBox>
                )}

                {selective && (activeTables.length > 0 || importType === 'credentials') && (
                    <div>
                        <div css={tw`mb-2 flex items-center justify-between`}>
                            <Label css={tw`mb-0`}>Tables</Label>
                            <span css={tw`text-xs text-neutral-400`}>{selectedTables.length} selected</span>
                        </div>

                        {activeTables.length > 0 ? (
                            <div css={tw`max-h-72 overflow-y-auto border border-neutral-600 rounded p-2`}>
                                {activeTables.map((table) => {
                                    const isSelected = selectedTables.includes(table.name);
                                    const isExpanded = expandedTables.includes(table.name);
                                    const selectedForTable = selectedColumns[table.name] || [];

                                    return (
                                        <div key={table.name} css={tw`mb-2 last:mb-0`}>
                                            <GreyRowBox $hoverable={false} css={tw`px-3 py-2 justify-between`}>
                                                <div css={tw`flex items-center min-w-0`}>
                                                    <Input
                                                        id={`import_table_${table.name}`}
                                                        type={'checkbox'}
                                                        checked={isSelected}
                                                        onChange={() => toggleTable(table.name)}
                                                    />
                                                    <Label htmlFor={`import_table_${table.name}`} css={tw`ml-3 mb-0`}>
                                                        {table.name}
                                                    </Label>
                                                    <span css={tw`text-xs text-neutral-400 ml-3`}>
                                                        ~{table.estimated_rows} rows
                                                    </span>
                                                </div>
                                                <Button
                                                    type={'button'}
                                                    size={Button.Sizes.Small}
                                                    variant={Button.Variants.Secondary}
                                                    disabled={!isSelected}
                                                    onClick={() => toggleTableExpanded(table.name)}
                                                >
                                                    {isExpanded ? 'Hide Columns' : 'Columns'}
                                                </Button>
                                            </GreyRowBox>

                                            {isExpanded && isSelected && (
                                                <div
                                                    css={tw`border border-neutral-600 border-t-0 rounded-b p-2 bg-neutral-700/40`}
                                                >
                                                    <p css={tw`text-xs text-neutral-400 mb-2`}>
                                                        Leave empty to import all columns.
                                                    </p>
                                                    <div css={tw`flex flex-wrap gap-2`}>
                                                        {table.columns.map((column) => (
                                                            <Button
                                                                key={`${table.name}-${column.name}`}
                                                                type={'button'}
                                                                size={Button.Sizes.Small}
                                                                variant={
                                                                    selectedForTable.includes(column.name)
                                                                        ? Button.Variants.Primary
                                                                        : Button.Variants.Secondary
                                                                }
                                                                className={'!px-2 !py-1 !text-xs'}
                                                                onClick={() => toggleColumn(table.name, column.name)}
                                                            >
                                                                {column.name}
                                                            </Button>
                                                        ))}
                                                    </div>
                                                </div>
                                            )}
                                        </div>
                                    );
                                })}
                            </div>
                        ) : (
                            <GreyRowBox $hoverable={false} css={tw`block p-4`}>
                                <Label htmlFor={'manual_tables'}>Tables (comma separated)</Label>
                                <Input
                                    id={'manual_tables'}
                                    value={manualTablesInput}
                                    onChange={(event) => setManualTablesInput(event.currentTarget.value)}
                                    placeholder={'users,sessions,audit_logs'}
                                />

                                {manualTables.length > 0 && (
                                    <div css={tw`mt-4 max-h-48 overflow-y-auto border border-neutral-600 rounded p-3`}>
                                        {manualTables.map((tableName) => (
                                            <div key={tableName} css={tw`mb-3 last:mb-0`}>
                                                <Label htmlFor={`columns_${tableName}`}>
                                                    Columns for {tableName} (optional)
                                                </Label>
                                                <Input
                                                    id={`columns_${tableName}`}
                                                    value={manualColumnsInput[tableName] || ''}
                                                    onChange={(event) =>
                                                        setManualColumnsInput({
                                                            ...manualColumnsInput,
                                                            [tableName]: event.currentTarget.value,
                                                        })
                                                    }
                                                    placeholder={'id,email,created_at'}
                                                />
                                            </div>
                                        ))}
                                    </div>
                                )}
                            </GreyRowBox>
                        )}
                    </div>
                )}
            </div>

            <Dialog.Footer>
                <Button
                    type={'button'}
                    variant={Button.Variants.Secondary}
                    disabled={isSubmitting || isAnalyzingFile || isAnalyzingExternal || isGeneratingPreview}
                    onClick={dismiss}
                >
                    Cancel
                </Button>
                <Button type={'button'} disabled={!canSubmit} onClick={onSubmit}>
                    {isSubmitting && uploadProgress !== null
                        ? `Uploading ${uploadProgress}%`
                        : isSubmitting
                        ? 'Queueing...'
                        : 'Import Database'}
                </Button>
            </Dialog.Footer>
        </Dialog>
    );
};

export default ImportDatabaseModal;
