import React, { useEffect, useState } from 'react';
import tw from 'twin.macro';
import { Dialog } from '@/components/elements/dialog';
import { Button } from '@/components/elements/button';
import Input from '@/components/elements/Input';
import Label from '@/components/elements/Label';
import FlashMessageRender from '@/components/FlashMessageRender';
import useFlash from '@/plugins/useFlash';
import { ServerContext } from '@/state/server';
import { httpErrorToHuman } from '@/api/http';
import { dropColumn, OperationResponse } from '../api/tableDataOperations';

interface DeleteColumnDialogContext {
    databaseId: string;
    tableName: string;
    columnName: string;
}

interface DeleteColumnDialogProps {
    open: boolean;
    onClose: () => void;
    context: DeleteColumnDialogContext;
    onSuccess?: (response: OperationResponse) => void;
}

const FLASH_KEY = 'database:content:delete-column-dialog';

const DeleteColumnDialog = ({ open, onClose, context, onSuccess }: DeleteColumnDialogProps) => {
    const uuid = ServerContext.useStoreState((state) => state.server.data!.uuid);
    const { clearFlashes, addError } = useFlash();

    const [isSubmitting, setIsSubmitting] = useState(false);
    const [confirmationText, setConfirmationText] = useState('');

    useEffect(() => {
        if (!open) {
            clearFlashes(FLASH_KEY);
            setIsSubmitting(false);
            setConfirmationText('');
            return;
        }

        clearFlashes(FLASH_KEY);
    }, [open]);

    const canDelete =
        !!context.databaseId.trim() &&
        !!context.tableName.trim() &&
        !!context.columnName.trim() &&
        confirmationText.trim() === context.columnName;

    const submit = async () => {
        clearFlashes(FLASH_KEY);

        if (!context.databaseId.trim() || !context.tableName.trim() || !context.columnName.trim()) {
            addError({ key: FLASH_KEY, message: 'Database table context is missing. Close and reopen the dialog.' });
            return;
        }

        if (confirmationText.trim() !== context.columnName) {
            addError({ key: FLASH_KEY, message: 'Confirmation text must match the column name.' });
            return;
        }

        setIsSubmitting(true);

        try {
            const response = await dropColumn(uuid, context.databaseId, context.tableName, context.columnName);

            if (!response.success) {
                throw new Error(response.error || 'Failed to delete column.');
            }

            onSuccess?.(response);
            onClose();
        } catch (error) {
            addError({ key: FLASH_KEY, message: httpErrorToHuman(error) });
        }

        setIsSubmitting(false);
    };

    return (
        <Dialog
            open={open}
            onClose={onClose}
            title={'Delete column'}
            description={`This will permanently delete column "${context.columnName || '-'}" from "${
                context.tableName || '-'
            }".`}
            preventExternalClose={isSubmitting}
        >
            <div css={tw`mt-6 space-y-4`}>
                <FlashMessageRender byKey={FLASH_KEY} css={tw`mb-2`} />

                <p css={tw`text-sm text-neutral-300`}>Type the column name to confirm this deletion.</p>

                <div>
                    <Label htmlFor={'delete-column-confirmation'}>Confirm column name</Label>
                    <Input
                        id={'delete-column-confirmation'}
                        value={confirmationText}
                        onChange={(event) => setConfirmationText(event.currentTarget.value)}
                        disabled={isSubmitting}
                    />
                </div>
            </div>

            <Dialog.Footer>
                <Button type={'button'} variant={Button.Variants.Secondary} onClick={onClose} disabled={isSubmitting}>
                    Cancel
                </Button>
                <Button.Danger type={'button'} onClick={submit} disabled={isSubmitting || !canDelete}>
                    Delete Column
                </Button.Danger>
            </Dialog.Footer>
        </Dialog>
    );
};

export default DeleteColumnDialog;
