import {useState, useEffect} from "@wordpress/element";
import {__, sprintf} from "@wordpress/i18n";
import Input from "../../../../../../fields/input";
import Emoji from "../../../../../../button/emoji";
import Copilot from "../../../../../../button/copilot";
import Radio from "../../../../../../fields/radio";
import {AVATARS, COLORS, ICONS, SHAPES, SIZES, THEMES} from "../../../../../../../constants/chatbot/appearance";
import ColorPicker from "../../../../../../fields/color-picker";
import Container from "../../../../containers/content/container";
import TabSettings from "../../../../../components/tab-settings";
import WPObjectsGroupsMultiSelect from "../../../../../../fields/specific-fields/wp-objects-groups-multi-select";
import Description from "../../../../../../sections/description";
import Dropdown from "../../../../../../fields/dropdown";
import Toggle from "../../../../../../fields/toggle";
import {APPEAR_AFTER} from "../settings/data";
import CustomDelay from "../settings/custom-delay";
import {validate} from "../../../../../../../../validations";
import Label from "../../../../../../sections/label";

// Constants
const TAB_NAME = 'settings.chatbot.appearance';

export default function Appearance({notifications, setChatbotPreview}) {
    // Actions states
    const [isDataFetched, setIsDataFetched] = useState(false);
    const [showInFetched, setShowInFetched] = useState(false);
    const [hideInFetched, setHideInFetched] = useState(false);
    const [showAddNewAppearAfterOptionPopup, setShowAddNewAppearAfterOptionPopup] = useState(false);

    // Settings
    const settings = {
        'title': useState(''),
        'greeting_text': useState(''),
        'greeting_tagline': useState(''),
        'theme': useState('system'),
        'color': useState('#458cf5'),
        'custom_colors': useState([]),
        'size': useState('md'),
        'icon_bg_shape': useState('squircle'),
        'show_in_side': useState('right'),
        'show_in': useState(['all']),
        'hide_in': useState([]),
        'appear_after': useState(0),
        'clean': useState(false),
        'reload': useState(true),
        'sound': useState(true),
        'avatar_visibility': useState(false),
        'show_unseen_messages_badge': useState(true),
        'show_unseen_messages_count': useState(true),
        'avatar': useState(AVATARS.find(item => item.default).value),
        'custom_icons': useState([]),
        'icon': useState(ICONS.find(item => item.default).value),
    };

    // Errors
    const errors = {
        'title': useState(false),
        'greeting_text': useState(false),
        'greeting_tagline': useState(false),
        'show_in': useState(false),
        'hide_in': useState(false),
    };

    /**
     * Validate field
     *
     * @param {string} name Field name
     * @param {any} value Field value
     * @return {boolean}
     */
    const validateField = (name, value) => {
        try {
            let validations = [];

            switch (name) {
                default:
                    return true;
            }

            const res = validate(value, validations);
            // Update field errors state
            errors[name][1](!res.valid ? res.message : false);
            return res.valid;
        } catch (e) {
            return false;
        }
    }

    // Handle show_in and hide_in conditional logic
    useEffect(() => {
        const showInValue = settings['show_in'][0];
        const hasAllValue = showInValue?.includes('all');

        // If show_in doesn't have 'all', clear hide_in field
        if (!hasAllValue && showInValue?.length > 0) {
            settings['hide_in'][1]([]);
        }
    }, [settings['show_in'][0]]);

    // Determine if hide_in field should be shown
    const shouldShowHideIn = isDataFetched && settings['show_in'][0]?.includes('all');

    /**
     * Add custom delay
     *
     * @param {number} value Custom value
     */
    const addCustomDelay = (value) => {
        const customAppearAfter = JSON.parse(localStorage.getItem('lbaic.settings.chatbot.settings.appear_after') || '[]');
        if (APPEAR_AFTER.findIndex(item => item.value === value) === -1 && customAppearAfter.findIndex(item => item.value === value) === -1) {
            customAppearAfter.push({
                label: sprintf(__('%d sec', 'limb-chatbot'), value),
                value: value,
            });
            APPEAR_AFTER.push({
                label: sprintf(__('%d sec', 'limb-chatbot'), value),
                value: value,
            });
            localStorage.setItem('lbaic.settings.chatbot.settings.appear_after', JSON.stringify(customAppearAfter));
        }
        settings['appear_after'][1](value);
        setShowAddNewAppearAfterOptionPopup(false);
    }

    /**
     * Render color value component
     *
     * @param {object} item Color value object
     * @param {number} i Index
     * @param {boolean} custom Is the color value custom or not
     * @return {JSX.Element}
     */
    const renderColorValue = (item, i, custom = false) => {
        const isActive = settings['color'][0] === item.value;

        return <div key={i} className='lbaic-settings-cb-a-row-in'>
            <button
                className={`lbaic-settings-radio-m lbaic-settings-radio-m-color lbaic-settings-radio-m-h-40 lbaic-settings-radio-m-pi-8${isActive ? ' active' : ''}`}
                onClick={() => settings['color'][1](item.value)}>
                {custom &&
                    <button className="lbaic-settings-cb-a-icon"
                            onClick={(e) => {
                                e.stopPropagation();
                                // Remove color
                                settings['custom_colors'][1](prevState => prevState.filter((_, index) => index !== i));
                                // Reset chatbot color
                                if (isActive) {
                                    settings['color'][1](COLORS[0].value);
                                }
                            }}>
                        <svg className='lbaic-settings-cb-a-i'
                             xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'>
                            <use href='#lbaic-settings-close'/>
                        </svg>
                    </button>}
                <i className='lbaic-settings-radio-m-color-in'
                   style={{'--lbaic-settings-radio-m-color-bg': item.value}}/>
            </button>
        </div>
    }

    /**
     * Color picked
     *
     * @param {Event} e Event
     */
    const onColorPick = (e) => {
        const newColor = e.target.value;

        // Update main color
        settings['color'][1](newColor);

        // If there's a custom color being edited, update it
        if (settings['custom_colors'][0].length) {
            const last = settings['custom_colors'][0].length - 1;
            settings['custom_colors'][1](prevState => prevState.map((item, i) => {
                if (i === last) {
                    return {
                        ...item,
                        value: newColor,
                    }
                }
                return item;
            }));
        }
    }

    /**
     * Add new custom color value when color picker opened
     */
    const onOpenColorPicker = () => {
        settings['custom_colors'][1]((prev) => [...prev, {
            value: '#000000',
        }]);
    }

    const showContent = isDataFetched && showInFetched;

    return <>
        <TabSettings name={TAB_NAME}
                     settings={settings}
                     notifications={notifications}
                     keysPrefix='lbaic.utilities.chatbot'
                     contentLoading={!showContent}
                     setChatbotPreview={setChatbotPreview}
                     dataFetched={value => setIsDataFetched(value)}
                     validateField={validateField}
                     shouldUpdatePreviewData
                     previewDataSpecialKeys={['title', 'greeting_text', 'greeting_tagline']}>
            <Container className="lbaic-settings-cb-a">
                <div className="lbaic-settings-column">
                    <div className="lbaic-settings-column-in">
                        <div className="lbaic-settings-cb-a-column-header">
                            <Label>{__("Theme", 'limb-chatbot')}</Label>
                        </div>
                        <div className="lbaic-settings-cb-a-column-body">
                            <div className='lbaic-settings-cb-a-row'>
                                {THEMES.map(item =>
                                    <div key={item.value}
                                         className='lbaic-settings-cb-a-row-in lbaic-settings-cb-a-row-gap-8'>
                                        <button
                                            className={`lbaic-settings-radio-m lbaic-settings-radio-m-h-40 lbaic-settings-radio-m-pi-16${settings['theme'][0] === item.value ? ' active' : ''}`}
                                            onClick={() => settings['theme'][1](item.value)}>
                                            <svg className='lbaic-settings-radio-m-i' xmlns='http://www.w3.org/2000/svg'
                                                 fill='none' viewBox='0 0 24 24'>
                                                <use href={`#lbaic-settings-theme-${item.icon}`}/>
                                            </svg>
                                            <span className='lbaic-settings-radio-m-label'>{item.label}</span>
                                        </button>
                                    </div>)}
                            </div>
                            <Description>{__("Choose your chatbot's light/dark mode preference", "limb-chatbot")}</Description>
                        </div>
                    </div>
                    <div className="lbaic-settings-column-in">
                        <div className="lbaic-settings-cb-a-column-header">
                            <Label>{__("Color", 'limb-chatbot')}</Label>
                        </div>
                        <div className="lbaic-settings-cb-a-column-body">
                            <div className='lbaic-settings-cb-a-row'>
                                <div className='lbaic-settings-cb-a-row-in'>
                                    <ColorPicker
                                        pickerOpened={onOpenColorPicker}
                                        colorPicked={onColorPick}
                                    />
                                </div>
                                {COLORS.map((item, i) => renderColorValue(item, i))}
                                {settings['custom_colors'][0].map((item, i) => renderColorValue(item, i, true))}
                            </div>
                            <Description>{__("Customize your chatbot's primary color to match your brand", "limb-chatbot")}</Description>
                        </div>
                    </div>
                </div>
                <div className="lbaic-settings-column">
                    <div className="lbaic-settings-column-in">
                        <div className="lbaic-settings-cb-a-column-header">
                            <Label>{__("Chat box size", 'limb-chatbot')}</Label>
                        </div>
                        <div className="lbaic-settings-cb-a-column-body">
                            <div className='lbaic-settings-cb-a-row'>
                                {SIZES.map((item) =>
                                    <div key={item.value}
                                         className='lbaic-settings-cb-a-row-in lbaic-settings-cb-a-row-gap-8'>
                                        <button
                                            className={`lbaic-settings-radio-m lbaic-settings-radio-m-h-44 lbaic-settings-radio-m-pi-24 lbaic-settings-radio-m-iw-22${settings['size'][0] === item.value ? ' active' : ''}`}
                                            onClick={() => settings['size'][1](item.value)}>
                                            <svg className='lbaic-settings-radio-m-i' xmlns='http://www.w3.org/2000/svg'
                                                 fill='none' viewBox='0 0 24 24'>
                                                <use href={`#lbaic-settings-size-${item.icon}`}/>
                                            </svg>
                                        </button>
                                    </div>)}
                            </div>
                            <Description>{__("Adjust the default size of your chatbot window", "limb-chatbot")}</Description>
                        </div>
                        <div className='lbaic-settings-cb-a-column-footer'>
                            <div className='lbaic-settings-cb-a-column-footer-in'>
                                <div className='lbaic-settings-cb-a-column-footer-item'>
                                    <Radio label={__("Show in the left bottom", 'limb-chatbot')}
                                           isChecked={settings['show_in_side'][0] === 'left'}
                                           setValue={() => settings['show_in_side'][1]('left')}/>
                                </div>
                                <div className='lbaic-settings-cb-a-column-footer-item'>
                                    <Radio label={__("Show in the right bottom", 'limb-chatbot')}
                                           isChecked={settings['show_in_side'][0] === 'right'}
                                           setValue={() => settings['show_in_side'][1]('right')}/>
                                </div>
                            </div>
                        </div>
                        <Description>{__("Control where the chatbot icon appears on your website", "limb-chatbot")}</Description>
                    </div>
                    <div className="lbaic-settings-column-in">
                        <div className="lbaic-settings-cb-a-column-header">
                            <Label>{__("Chatbot icon shape", 'limb-chatbot')}</Label>
                        </div>
                        <div className="lbaic-settings-cb-a-column-body">
                            <div className='lbaic-settings-cb-a-row'>
                                {SHAPES.map((item) =>
                                    <div key={item.value}
                                         className='lbaic-settings-cb-a-row-in lbaic-settings-cb-a-row-gap-8'>
                                        <button
                                            className={`lbaic-settings-radio-m lbaic-settings-radio-m-h-44 lbaic-settings-radio-m-iw-70${settings['icon_bg_shape'][0] === item.value ? ' active' : ''}`}
                                            onClick={() => settings['icon_bg_shape'][1](item.value)}>
                                            <svg className='lbaic-settings-radio-m-i' xmlns='http://www.w3.org/2000/svg'
                                                 fill='none' viewBox='0 0 70 40'>
                                                <use href={`#lbaic-settings-shape-${item.icon}`}/>
                                            </svg>
                                        </button>
                                    </div>)}
                            </div>
                            <Description>{__("Select the background shape for your chatbot icon", "limb-chatbot")}</Description>
                        </div>
                    </div>
                </div>
                <div className="lbaic-settings-column">
                    <div className="lbaic-settings-column-in">
                        <WPObjectsGroupsMultiSelect
                            value={settings['show_in'][0]}
                            setValue={settings['show_in'][1]}
                            placeholder={__("Show in location", 'limb-chatbot')}
                            errorMessage={errors['show_in'][0]}
                            validate={value => validateField('show_in', value)}
                            addNotification={notifications.set}
                            isDataReady={isDataFetched}
                            setFetched={setShowInFetched}
                        />
                        <Description>{__("Select the WordPress public locations where your chatbot will be shown", 'limb-chatbot')}</Description>
                    </div>
                    <div className="lbaic-settings-column-in">
                        {shouldShowHideIn && (
                            <>
                                <WPObjectsGroupsMultiSelect
                                    value={settings['hide_in'][0]}
                                    setValue={settings['hide_in'][1]}
                                    placeholder={__("Hide in location", 'limb-chatbot')}
                                    errorMessage={errors['hide_in'][0]}
                                    validate={value => validateField('hide_in', value)}
                                    addNotification={notifications.set}
                                    showAllOption={false}
                                    isDataReady={isDataFetched}
                                    setFetched={setHideInFetched}
                                />
                                <Description>{__("Select locations where the chatbot will be hidden", 'limb-chatbot')}</Description>
                            </>
                        )}
                    </div>
                </div>
                <div className="lbaic-settings-column">
                    <div className="lbaic-settings-column-in">
                        <Input value={settings['title'][0]} setValue={settings['title'][1]}
                               placeholder={__("Agent name", 'limb-chatbot')}/>
                        <Description>{__('Display name for your AI agent (e.g., "Limb", "Lucy", "Support Assistant")', 'limb-chatbot')}</Description>
                    </div>
                    <div className="lbaic-settings-column-in">
                        <Toggle
                            label={__("Show AI agent avatar", 'limb-chatbot')}
                            isActive={settings['avatar_visibility'][0]}
                            onClick={() => settings['avatar_visibility'][1](!settings['avatar_visibility'][0])}
                        />
                        <Description>{__("Show or hide the AI agent's avatar", 'limb-chatbot')}</Description>
                    </div>
                </div>
                {settings['avatar_visibility'][0] && (
                    <div className="lbaic-settings-column">
                        <div className="lbaic-settings-column-in">
                            <div className="lbaic-settings-cb-a-column-header">
                                <Label>{__("AI Agent avatar", 'limb-chatbot')}</Label>
                            </div>
                            <div className="lbaic-settings-cb-a-column-body">
                                <div className='lbaic-settings-cb-a-row'>
                                    {AVATARS.map(item =>
                                        <div key={item.value}
                                             className='lbaic-settings-cb-a-row-in lbaic-settings-cb-a-row-gap-8'>
                                            <button
                                                className={`lbaic-settings-radio-m lbaic-settings-radio-m-h-34 lbaic-settings-radio-m-pi-16${+settings['avatar'][0] === item.value ? ' active' : ''}`}
                                                onClick={() => settings['avatar'][1](item.value)}>
                                                <svg className='lbaic-settings-radio-m-i' xmlns='http://www.w3.org/2000/svg'
                                                     fill='none' viewBox='0 0 16 16'>
                                                    <use href={`#lbaic-settings-chatbot-avatar-${item.icon}`}/>
                                                </svg>
                                            </button>
                                        </div>)}
                                </div>
                                <Description>{__("Select an avatar to represent your AI agent in conversations", "limb-chatbot")}</Description>
                            </div>
                        </div>
                    </div>
                )}
                <div className="lbaic-settings-column">
                    <div className="lbaic-settings-column-in">
                        <div className="lbaic-settings-cb-a-column-header">
                            <Label>{__("Chatbot icon", 'limb-chatbot')}</Label>
                        </div>
                        <div className="lbaic-settings-cb-a-column-body">
                            <div className='lbaic-settings-cb-a-row'>
                                {ICONS.map(item =>
                                    <div key={item.value}
                                         className='lbaic-settings-cb-a-row-in lbaic-settings-cb-a-row-gap-8'>
                                        <button
                                            className={`lbaic-settings-radio-m lbaic-settings-radio-m-h-34 lbaic-settings-radio-m-pi-16${+settings['icon'][0] === item.value ? ' active' : ''}`}
                                            onClick={() => settings['icon'][1](item.value)}>
                                            <svg className='lbaic-settings-radio-m-i' xmlns='http://www.w3.org/2000/svg'
                                                 fill='none' viewBox='0 0 16 16'>
                                                <use href={`#lbaic-settings-chatbot-icon-${item.icon}`}/>
                                            </svg>
                                        </button>
                                    </div>)}
                            </div>
                            <Description>{__("Choose the icon that appears in the corner of your website to open the chatbot", "limb-chatbot")}</Description>
                        </div>
                    </div>
                </div>
                <div className="lbaic-settings-column">
                    <div className="lbaic-settings-column-in">
                        <Dropdown value={settings['appear_after'][0]} setValue={settings['appear_after'][1]}
                                  options={APPEAR_AFTER} defaultIcon="schedule"
                                  addNew={() => setShowAddNewAppearAfterOptionPopup(true)}
                                  placeholder={__("Appear after", 'limb-chatbot')}/>
                        <Description>{__("Delay in seconds before the chatbot icon appears", 'limb-chatbot')}</Description>
                    </div>
                    <div className="lbaic-settings-column-in">
                        <Toggle label={__("Chat clean button", 'limb-chatbot')} isActive={settings['clean'][0]}
                                onClick={() => settings['clean'][1](!settings['clean'][0])}/>
                        <Description>{__("Users can clear conversation history from the three-dot menu", 'limb-chatbot')}</Description>
                    </div>
                </div>
                <div className="lbaic-settings-column">
                    <div className="lbaic-settings-column-in">
                        <Toggle
                            label={__("Message reload button", 'limb-chatbot')}
                            isActive={settings['reload'][0]}
                            onClick={() => settings['reload'][1](!settings['reload'][0])}
                        />
                        <Description>{__("Users can regenerate the last AI response by clicking the reload button", 'limb-chatbot')}</Description>
                    </div>
                    <div className="lbaic-settings-column-in">
                        <Toggle
                            label={__("Sound controls", 'limb-chatbot')}
                            isActive={settings['sound'][0]}
                            onClick={() => settings['sound'][1](!settings['sound'][0])}
                        />
                        <Description>{__("Users can toggle sound notifications from the three-dot menu", 'limb-chatbot')}</Description>
                    </div>
                </div>
                <div className="lbaic-settings-column">
                    <div className="lbaic-settings-column-in">
                        <Toggle
                            label={__("Show unseen messages badge", 'limb-chatbot')}
                            isActive={settings['show_unseen_messages_badge'][0]}
                            onClick={() => settings['show_unseen_messages_badge'][1](!settings['show_unseen_messages_badge'][0])}
                        />
                        <Description>{__("Display a badge indicator when there are unseen messages", 'limb-chatbot')}</Description>
                    </div>
                    <div className="lbaic-settings-column-in">
                        <Toggle
                            label={__("Show unseen messages count in the badge", 'limb-chatbot')}
                            isActive={settings['show_unseen_messages_count'][0]}
                            onClick={() => settings['show_unseen_messages_count'][1](!settings['show_unseen_messages_count'][0])}
                        />
                        <Description>{__("Display the number of unseen messages in the badge", 'limb-chatbot')}</Description>
                    </div>
                </div>
                <div className="lbaic-settings-column">
                    <div className="lbaic-settings-column-in">
                        <Input value={settings['greeting_text'][0]} setValue={settings['greeting_text'][1]}
                               placeholder={__("Greeting text", 'limb-chatbot')}
                               actions={[
                                   {
                                       component: Emoji,
                                       props: {
                                           chosen: obj => settings['greeting_text'][1](prevState => prevState + obj.emoji),
                                       }
                                   },
                                   {
                                       component: Copilot,
                                       props: {
                                           text: settings['greeting_text'][0],
                                           generated: settings['greeting_text'][1],
                                           notifications: notifications
                                       }
                                   },
                               ]}/>
                        <Description>{__("The main welcome message on the AI agent's homepage", 'limb-chatbot')}</Description>
                    </div>
                    <div className="lbaic-settings-column-in">
                        <Input
                            value={settings['greeting_tagline'][0]}
                            setValue={settings['greeting_tagline'][1]}
                            placeholder={__("Greeting tagline", 'limb-chatbot')}
                            actions={[
                                {
                                    component: Emoji,
                                    props: {
                                        chosen: obj => settings['greeting_tagline'][1](prevState => prevState + obj.emoji)
                                    },
                                },
                                {
                                    component: Copilot,
                                    props: {
                                        text: settings['greeting_tagline'][0],
                                        generated: settings['greeting_tagline'][1],
                                        notifications: notifications
                                    },
                                },
                            ]}
                        />
                        <Description>{__("A brief tagline shown with the greeting on the homepage", 'limb-chatbot')}</Description>
                    </div>
                </div>
            </Container>
        </TabSettings>
        {showAddNewAppearAfterOptionPopup &&
            <CustomDelay setValue={addCustomDelay} close={() => setShowAddNewAppearAfterOptionPopup(false)}
                         notifications={notifications}/>}
    </>
}