import React, { useEffect, useMemo, 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 { deleteTableRow, OperationResponse } from '../api/tableDataOperations';

interface DeleteRowDialogContext {
    databaseId: string;
    tableName: string;
    primaryKeyValues: Record<string, any>;
}

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

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

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

    const [isSubmitting, setIsSubmitting] = useState(false);
    const [force, setForce] = useState(false);

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

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

    const hasPrimaryKeys = useMemo(
        () => Object.keys(context.primaryKeyValues || {}).length > 0,
        [context.primaryKeyValues]
    );

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

        if (!context.databaseId.trim() || !context.tableName.trim() || !hasPrimaryKeys) {
            addError({ key: FLASH_KEY, message: 'Missing primary key values for row deletion.' });
            return;
        }

        setIsSubmitting(true);

        try {
            const response = await deleteTableRow(uuid, context.databaseId, context.tableName, {
                primary_key_values: context.primaryKeyValues,
                force,
            });

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

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

        setIsSubmitting(false);
    };

    return (
        <Dialog
            open={open}
            onClose={onClose}
            title={'Delete row'}
            description={`Table: ${context.tableName || '-'}`}
            preventExternalClose={isSubmitting}
        >
            <div css={tw`mt-6 space-y-4 max-h-[65vh] overflow-y-auto pr-1`}>
                <FlashMessageRender byKey={FLASH_KEY} css={tw`mb-2`} />

                {!hasPrimaryKeys ? (
                    <p css={tw`text-sm text-neutral-400`}>
                        This row cannot be deleted because no primary key values were found.
                    </p>
                ) : (
                    <>
                        <p css={tw`text-sm text-neutral-300`}>Delete this row by primary key values:</p>
                        <div css={tw`border border-neutral-600 rounded p-3 bg-neutral-700`}>
                            {Object.entries(context.primaryKeyValues).map(([key, value]) => (
                                <div key={key} css={tw`text-xs text-neutral-200 mb-1 last:mb-0`}>
                                    <span css={tw`text-neutral-400`}>{key}:</span> {String(value)}
                                </div>
                            ))}
                        </div>

                        <div css={tw`flex items-center`}>
                            <Input
                                id={'delete-row-force'}
                                type={'checkbox'}
                                checked={force}
                                onChange={(event) => setForce(event.currentTarget.checked)}
                                disabled={isSubmitting}
                            />
                            <Label htmlFor={'delete-row-force'} css={tw`ml-3 mb-0`}>
                                Force override
                            </Label>
                        </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 || !hasPrimaryKeys}>
                    Delete Row
                </Button.Danger>
            </Dialog.Footer>
        </Dialog>
    );
};

export default DeleteRowDialog;
