import React, { useState, useEffect } from 'react';
import { EditableMetadata } from '@theorchard/suite-components';
import type { EditableMetadataProps } from '@theorchard/suite-components';

const SUCCESS_TIMEOUT_MS = 2000; // how long to show success before clearing

interface EditableCellProps {
    value: string;
    onSave: (newValue: string) => Promise<void> | void; // called to persist changes
    afterSave?: () => void | Promise<void>; // optional callback after success (e.g. refetch)
    validationFn?: EditableMetadataProps['validationFn'];
    validationError?: EditableMetadataProps['validationError'];
    ['data-testid']?: string;
}

export const EditableCell: React.FC<EditableCellProps> = ({
    value,
    onSave,
    afterSave,
    validationFn,
    validationError,
    'data-testid': dataTestId,
}) => {
    // state for showing loading/success/error messages in EditableMetadata
    const [processing, setProcessing] =
        useState<EditableMetadataProps['processing']>();

    // local state for editable field value
    const [internalValue, setInternalValue] = useState(value);

    // track if component is still mounted (prevents setting state after unmount)
    const isMounted = React.useRef(true);

    // keep internal value in sync if parent prop changes
    useEffect(() => {
        setInternalValue(value);
    }, [value]);

    // mark component as mounted/unmounted
    useEffect(() => {
        isMounted.current = true;
        return () => {
            isMounted.current = false;
        };
    }, []);

    const handleConfirm = async (newValue: string) => {
        // show "saving" state immediately
        setProcessing({ type: 'loading', message: 'Saving...' });

        try {
            // attempt to persist the new value
            await onSave(newValue);

            if (isMounted.current) {
                // update local state and show success
                setInternalValue(newValue);
                setProcessing({
                    type: 'success',
                    message: 'Saved successfully!',
                });

                // keep success visible briefly, then clear and run afterSave (e.g. refetch)
                setTimeout(() => {
                    if (isMounted.current) {
                        setProcessing(undefined);
                        void afterSave?.(); // fire-and-forget
                    }
                }, SUCCESS_TIMEOUT_MS);
            }
        } catch {
            // show error message if save fails
            if (isMounted.current) {
                setProcessing({
                    type: 'error' as any,
                    message: 'Failed to save',
                });
            }
        }
    };

    return (
        <EditableMetadata
            label=""
            value={internalValue}
            onConfirm={handleConfirm}
            validationFn={validationFn}
            validationError={validationError}
            processing={processing}
            data-testid={dataTestId}
        />
    );
};
