import {useEffect, useMemo, useRef, useState} from "@wordpress/element";
import {__} from "@wordpress/i18n";
import ToggleButton from "../../../../../../../../fields/toggle-button";
import Badge from "../../../../../../../../fields/badge";
import NestedTabs from "../../../../../../../../sections/nested-tabs";
import confirm from "../../../../../../../../../helpers/confirm";
import {DEFAULT_TABS, getTabsByType} from "./_data";
import {CALLBACK_TYPES} from "../../../../../../../../popups/actions/add-callback";
import {getTypeConfig} from "./types";

export default function CallbackItem({
                                         index,
                                         callback,
                                         update,
                                         remove,
                                         newCallbackIds,
                                         notifications,
                                         actionId,
                                         onDeleteCallback,
                                         allParameters = [],
                                         allCallbacks = [],
                                         forceOpen = false,
                                         onValidationRef
                                     }) {

    const [opened, setOpened] = useState(newCallbackIds?.includes(callback.id));
    const prevForceOpenRef = useRef(forceOpen);
    const configurationRef = useRef(null);

    /**
     * Trigger validation for all fields
     */
    const triggerValidation = () => {
        if (configurationRef.current?.triggerValidation) {
            configurationRef.current.triggerValidation();
        }
    };

    // Expose validation trigger to parent
    useEffect(() => {
        if (onValidationRef) {
            onValidationRef(triggerValidation);
        }
        return () => {
            if (onValidationRef) {
                onValidationRef(null);
            }
        };
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [onValidationRef]);

    // Open accordion when forceOpen becomes true (allows user to close manually, but reopens on save if errors persist)
    useEffect(() => {
        // Only open when forceOpen transitions from false to true (not when it stays true)
        if (forceOpen && !prevForceOpenRef.current) {
            setOpened(true);
            // Trigger validation when opening due to forceOpen
            // Use setTimeout to ensure the component is fully rendered
            setTimeout(() => {
                triggerValidation();
            }, 100);
        }
        prevForceOpenRef.current = forceOpen;
    }, [forceOpen]);

    const getInitialTab = () => {
        const availableTabs = getTabsByType(callback?.type);
        return availableTabs[0]?.slug || null;
    };

    const [activeTab, setActiveTab] = useState(getInitialTab);

    const tabs = useMemo(() => getTabsByType(callback?.type), [callback?.type]);

    useEffect(() => {
        if (!tabs.some(tab => tab.slug === activeTab)) {
            setActiveTab(tabs[0]?.slug || null);
        }
    }, [tabs, activeTab]);

    const handleRemove = async () => {
        if (await confirm(__("Are you sure you want to delete this handler?", 'limb-chatbot'))) {
            // If callback has a real ID (not a temporary one), delete via API
            if (callback.id && typeof callback.id === 'number' && !newCallbackIds.includes(callback.id)) {
                if (onDeleteCallback && actionId) {
                    try {
                        await onDeleteCallback(actionId, callback.id);
                        remove(index);
                    } catch (e) {
                        // Error already handled in onDeleteCallback
                    }
                } else {
                    remove(index);
                }
            } else {
                // Temporary callback, just remove from local state
                remove(index);
            }
        }
    };

    const updateField = (field, value) => {
        update(index, field, value);
    };

    const typeConfig = getTypeConfig(callback?.type);

    const isNewCallback = newCallbackIds?.includes(callback.id);

    const tabContent = useMemo(() => {
        if (typeConfig?.getPanels) {
            return typeConfig.getPanels({
                callback,
                updateField,
                notifications,
                allParameters,
                allCallbacks,
                isNewCallback,
                validationRef: configurationRef,
            });
        }

        return {
            'configuration': (
                <>
                    <div className="lbaic-settings-column">
                        <div className="lbaic-settings-column-in">
                            <p>{__("Configuration content will be here", 'limb-chatbot')}</p>
                        </div>
                    </div>
                </>
            ),
            'data-access': (
                <>
                    <div className="lbaic-settings-column">
                        <div className="lbaic-settings-column-in">
                            <p>{__("Data access content will be here", 'limb-chatbot')}</p>
                        </div>
                    </div>
                </>
            ),
        };
    }, [typeConfig, callback, updateField, notifications]);

    const currentActiveTab = activeTab || tabs[0]?.slug || DEFAULT_TABS[0].slug;

    return (
        <div className='lbaic-settings-table-accordion-body'>
            <div
                className={`lbaic-settings-table-accordion-body-in lbaic-settings-table-accordion-summary lbaic-settings-actions-ci-table-summary lbaic-settings-cb-pw-table-summary${opened ? ' active' : ''}`}>
                <div
                    className="lbaic-settings-table-accordion-body-item lbaic-settings-cb-pw-table-number"
                    onClick={() => setOpened(!opened)}
                >
                    <div className="lbaic-settings-cb-pw-table-actions-in">
                        <span
                            className="lbaic-settings-table-accordion-body-label lbaic-settings-cb-pw-table-accordion-body-label">{index + 1}</span>
                    </div>
                </div>
                <div
                    className="lbaic-settings-table-accordion-body-item lbaic-settings-cb-pw-table-item"
                    onClick={() => setOpened(!opened)}
                >
                    <div className="lbaic-settings-actions-ci-table-title-wrapper">
                        <span
                            className={`lbaic-settings-table-accordion-body-label lbaic-settings-cb-pw-table-accordion-body-label${!callback.name ? ' lbaic-settings-cb-pw-table-card-body-label-null' : ''}`}
                            dangerouslySetInnerHTML={{__html: callback.name || __("no label", 'limb-chatbot')}}/>
                        {callback.type && (
                            <Badge label={CALLBACK_TYPES.find(t => t.type === callback.type)?.label || callback.type}
                                   isSmall={true} className='lbaic-settings-badge-gray'/>
                        )}
                    </div>
                    <button
                        className="lbaic-settings-cb-pw-table-actions-item lbaic-settings-cb-pw-button-primary lbaic-settings-button-reset"
                        onClick={(e) => {
                            e.stopPropagation();
                            setOpened(!opened);
                        }}
                    >
                        <svg className="lbaic-settings-cb-pw-table-accordion-body-i"
                             xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                            <use href="#lbaic-settings-edit"/>
                        </svg>
                    </button>
                </div>
                <div
                    className="lbaic-settings-table-accordion-body-item lbaic-settings-cb-pw-table-actions">
                    <div className="lbaic-settings-cb-pw-table-actions-in">
                        <ToggleButton
                            className='lbaic-settings-toggle-sm'
                            isActive={callback.enabled !== false}
                            onClick={() => updateField('enabled', callback.enabled === false)}/>
                        <button
                            className='lbaic-settings-cb-pw-table-actions-item lbaic-settings-cb-pw-button-primary lbaic-settings-button-reset'
                            onClick={handleRemove}>
                            <svg className="lbaic-settings-cb-pw-table-accordion-body-i"
                                 xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                                <use href="#lbaic-settings-delete"/>
                            </svg>
                        </button>
                    </div>
                </div>
            </div>
            <div
                className={`lbaic-settings-table-accordion-body-in lbaic-settings-table-accordion-details lbaic-settings-cb-pw-table-accordion-details${opened ? ' opened' : ''}`}>
                <div className="lbaic-settings-table-accordion-body-item lbaic-settings-table-accordion-details-in">
                    <div
                        className="lbaic-settings-table-accordion-content lbaic-settings-cb-pw-table-accordion-content">
                        <NestedTabs
                            tabs={tabs}
                            activeTab={currentActiveTab}
                            onTabChange={setActiveTab}
                            className="lbaic-settings-divider-no-pi"
                        >
                            {tabContent}
                        </NestedTabs>
                    </div>
                </div>
            </div>
        </div>
    );
}