/**
 * Shois Chat Button — Design Tab (Editor)
 *
 * Color pickers with custom gradient builder, icon selector, sizing controls,
 * position selector, border radius, and reset-to-defaults.
 *
 * @package ShoisChatButton
 */
import { useState, useRef, useEffect } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
 * Default config values for reset.
 */
const DEFAULTS = {
    primary_color: '#5170ff',
    header_bg_color: '#330066',
    header_text_color: '#ffffff',
    text_color: '#1e293b',
    bg_color: '#ffffff',
    position: 'bottom-right',
    btn_size: 60,
    popup_width: 360,
    offset_x: 24,
    offset_y: 24,
    radius_btn: 50,
    radius_popup: 16,
    trigger_icon: 'whatsapp',
    agent_bg_color: '#f8faf9',
    agent_text_color: '#1e293b',
    platform_radius: 0,
    platform_padding: 10,
    platform_margin: 0,
};

/**
 * Gradient presets.
 */
const GRADIENT_PRESETS = [
    { label: 'Sunset', value: 'linear-gradient(135deg, #f97316, #ec4899)' },
    { label: 'Ocean', value: 'linear-gradient(135deg, #06b6d4, #3b82f6)' },
    { label: 'Forest', value: 'linear-gradient(135deg, #22c55e, #14b8a6)' },
    { label: 'Purple', value: 'linear-gradient(135deg, #8b5cf6, #ec4899)' },
    { label: 'Fire', value: 'linear-gradient(135deg, #ef4444, #f97316)' },
    { label: 'Night', value: 'linear-gradient(135deg, #1e293b, #7c3aed)' },
    { label: 'Gold', value: 'linear-gradient(135deg, #f59e0b, #eab308)' },
    { label: 'Teal', value: 'linear-gradient(135deg, #14b8a6, #0ea5e9)' },
    { label: 'Rose', value: 'linear-gradient(135deg, #f43f5e, #a855f7)' },
    { label: 'Sky', value: 'linear-gradient(135deg, #38bdf8, #818cf8)' },
];

/**
 * SVG icon markup for trigger button options.
 * Using inline SVG so icons inherit currentColor and can be styled.
 */
const ICON_SVG = {
    // Chat & support icons.
    chat: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',
    chat_dots: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><circle cx="8" cy="10" r="1"/><circle cx="12" cy="10" r="1"/><circle cx="16" cy="10" r="1"/></svg>',
    headset: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 1a9 9 0 0 0-9 9v7c0 1.66 1.34 3 3 3h3v-8H5v-2a7 7 0 0 1 14 0v2h-4v8h3c1.66 0 3-1.34 3-3v-7a9 9 0 0 0-9-9z"/></svg>',
    help: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z"/></svg>',
    phone: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M6.62 10.79c1.44 2.83 3.76 5.14 6.59 6.59l2.2-2.2c.27-.27.67-.36 1.02-.24 1.12.37 2.33.57 3.57.57.55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17 0-.55.45-1 1-1h3.5c.55 0 1 .45 1 1 0 1.25.2 2.45.57 3.57.11.35.03.74-.25 1.02l-2.2 2.2z"/></svg>',
    mail: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg>',
    // Social / platform icons.
    whatsapp: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"/></svg>',
    telegram: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M11.944 0A12 12 0 000 12a12 12 0 0012 12 12 12 0 0012-12A12 12 0 0012 0 12 12 0 0011.944 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 01.171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.479.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z"/></svg>',
    messenger: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M.001 11.639C.001 4.949 5.241 0 12.001 0S24 4.95 24 11.639c0 6.689-5.24 11.638-12 11.638-1.21 0-2.38-.16-3.47-.46a.96.96 0 00-.64.05l-2.39 1.05a.96.96 0 01-1.35-.85l-.07-2.14a.97.97 0 00-.32-.68A11.39 11.389 0 01.002 11.64zm8.32-2.19l-3.52 5.6c-.35.53.32 1.139.82.75l3.79-2.87c.29-.21.69-.21.97 0l2.8 2.1c.86.64 2.09.4 2.65-.5l3.52-5.6c.35-.53-.32-1.13-.82-.75l-3.79 2.87c-.29.21-.69.21-.97 0l-2.8-2.1c-.86-.64-2.09-.4-2.65.5z"/></svg>',
    instagram: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C8.74 0 8.333.015 7.053.072 5.775.132 4.905.333 4.14.63c-.789.306-1.459.717-2.126 1.384S.935 3.35.63 4.14C.333 4.905.131 5.775.072 7.053.012 8.333 0 8.74 0 12s.015 3.667.072 4.947c.06 1.277.261 2.148.558 2.913.306.788.717 1.459 1.384 2.126.667.666 1.336 1.079 2.126 1.384.766.296 1.636.499 2.913.558C8.333 23.988 8.74 24 12 24s3.667-.015 4.947-.072c1.277-.06 2.148-.262 2.913-.558.788-.306 1.459-.718 2.126-1.384.666-.667 1.079-1.335 1.384-2.126.296-.765.499-1.636.558-2.913.06-1.28.072-1.687.072-4.947s-.015-3.667-.072-4.947c-.06-1.277-.262-2.149-.558-2.913-.306-.789-.718-1.459-1.384-2.126C21.319 1.347 20.651.935 19.86.63c-.765-.297-1.636-.499-2.913-.558C15.667.012 15.26 0 12 0zm0 2.16c3.203 0 3.585.016 4.85.071 1.17.055 1.805.249 2.227.415.562.217.96.477 1.382.896.419.42.679.819.896 1.381.164.422.36 1.057.413 2.227.057 1.266.07 1.646.07 4.85s-.015 3.585-.074 4.85c-.061 1.17-.256 1.805-.421 2.227-.224.562-.479.96-.899 1.382-.419.419-.824.679-1.38.896-.42.164-1.065.36-2.235.413-1.274.057-1.649.07-4.859.07-3.211 0-3.586-.015-4.859-.074-1.171-.061-1.816-.256-2.236-.421-.569-.224-.96-.479-1.379-.899-.421-.419-.69-.824-.9-1.38-.165-.42-.359-1.065-.42-2.235-.045-1.26-.061-1.649-.061-4.844 0-3.196.016-3.586.061-4.861.061-1.17.255-1.814.42-2.234.21-.57.479-.96.9-1.381.419-.419.81-.689 1.379-.898.42-.166 1.051-.361 2.221-.421 1.275-.045 1.65-.06 4.859-.06l.045.03zm0 3.678a6.162 6.162 0 100 12.324 6.162 6.162 0 100-12.324zM12 16c-2.21 0-4-1.79-4-4s1.79-4 4-4 4 1.79 4 4-1.79 4-4 4zm7.846-10.405a1.441 1.441 0 11-2.88 0 1.441 1.441 0 012.88 0z"/></svg>',
    viber: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M11.398.002C9.473.028 5.331.344 3.014 2.467 1.294 4.177.518 6.769.399 9.932c-.12 3.163-.27 9.098 5.575 10.702l.007.003v2.43s-.038.976.606 1.175c.778.24 1.236-.5 1.98-1.303.408-.44.97-1.088 1.394-1.583 3.84.322 6.8-.414 7.139-.525.778-.255 5.186-.818 5.907-6.677.743-6.034-.354-9.835-2.354-11.553-.6-.55-3.004-2.318-8.568-2.572 0 0-.427-.022-.961-.026l.269-.001zm.27 1.534c.455 0 .832.02.832.02 4.775.22 6.818 1.628 7.34 2.098 1.72 1.478 2.611 4.864 1.96 10.093-.62 5.04-4.347 5.353-5.013 5.57-.283.091-2.856.732-6.148.533 0 0-2.435 2.941-3.197 3.707-.12.12-.26.167-.352.144-.13-.032-.166-.186-.164-.413l.022-4.013c-5.001-1.378-4.704-6.478-4.6-9.21.104-2.733.753-4.98 2.2-6.404 1.997-1.83 5.603-2.129 7.12-2.126z"/></svg>',
    discord: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189z"/></svg>',
    line: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M24 10.382C24 4.644 18.614.2 12 .2S0 4.644 0 10.382c0 5.043 4.474 9.27 10.52 10.068.41.088.966.27 1.107.62.127.317.083.812.04 1.131 0 0-.147.89-.18 1.078-.054.318-.25 1.246 1.092.68C13.915 23.392 18.978 20.2 21.12 17.64c1.484-1.628 2.878-3.848 2.878-7.258"/></svg>',
    skype: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12.069 18.874c-4.023 0-5.82-1.979-5.82-3.464 0-.765.561-1.296 1.333-1.296 1.723 0 1.273 2.477 4.487 2.477 1.641 0 2.55-.895 2.55-1.811 0-.551-.269-1.16-1.354-1.429l-3.576-.895c-2.88-.724-3.403-2.286-3.403-3.751 0-3.047 2.861-4.191 5.549-4.191 2.471 0 5.393 1.373 5.393 3.199 0 .784-.688 1.24-1.453 1.24-1.469 0-1.198-2.037-4.164-2.037-1.469 0-2.292.664-2.292 1.617s1.153 1.258 2.157 1.487l2.637.587c2.891.649 3.624 2.346 3.624 3.944 0 2.476-1.902 4.414-5.722 4.414M24 12.073a11.89 11.89 0 01-.657 3.92 6.017 6.017 0 01.131 1.262c0 3.303-2.686 5.98-5.997 5.98-.682 0-1.341-.115-1.954-.326A11.93 11.93 0 0112.07 24C5.424 24 .001 18.579.001 11.934c0-1.35.224-2.647.633-3.863A6.004 6.004 0 01.459 6.795c0-3.303 2.686-5.98 5.997-5.98.691 0 1.355.118 1.973.334A11.917 11.917 0 0112.07 0c6.645 0 12.068 5.421 12.068 12.073"/></svg>',
    tiktok: '<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12.525.02c1.31-.02 2.61-.01 3.91-.02.08 1.53.63 3.09 1.75 4.17 1.12 1.11 2.7 1.62 4.24 1.79v4.03c-1.44-.05-2.89-.35-4.2-.97-.57-.26-1.1-.59-1.62-.93-.01 2.92.01 5.84-.02 8.75-.08 1.4-.54 2.79-1.35 3.94-1.31 1.92-3.58 3.17-5.91 3.21-1.43.08-2.86-.31-4.08-1.03-2.02-1.19-3.44-3.37-3.65-5.71-.02-.5-.03-1-.01-1.49.18-1.9 1.12-3.72 2.58-4.96 1.66-1.44 3.98-2.13 6.15-1.72.02 1.48-.04 2.96-.04 4.44-.99-.32-2.15-.23-3.02.37-.63.41-1.11 1.04-1.36 1.75-.21.51-.15 1.07-.14 1.61.24 1.64 1.82 3.02 3.5 2.87 1.12-.01 2.19-.66 2.77-1.61.19-.33.4-.67.41-1.06.1-1.79.06-3.57.07-5.36.01-4.03-.01-8.05.02-12.07z"/></svg>',
};

/**
 * Icon option groups for the selector.
 */
const ICON_GROUPS = [
    {
        label: 'Chat & Support',
        icons: [
            { id: 'chat', label: 'Chat' },
            { id: 'chat_dots', label: 'Chat Dots' },
            { id: 'headset', label: 'Support' },
            { id: 'help', label: 'Help' },
            { id: 'phone', label: 'Phone' },
            { id: 'mail', label: 'Email' },
        ],
    },
    {
        label: 'Social',
        icons: [
            { id: 'whatsapp', label: 'WhatsApp' },
            { id: 'telegram', label: 'Telegram' },
            { id: 'messenger', label: 'Messenger' },
            { id: 'instagram', label: 'Instagram' },
            { id: 'viber', label: 'Viber' },
            { id: 'discord', label: 'Discord' },
            { id: 'line', label: 'Line' },
            { id: 'skype', label: 'Skype' },
            { id: 'tiktok', label: 'TikTok' },
        ],
    },
];

/**
 * Parse a gradient string into color stops.
 *
 * @param {string} val Gradient CSS or hex.
 * @return {Object} { isGradient, color1, color2, angle }
 */
function parseGradient(val) {
    if (!val || !val.includes('gradient')) {
        return { isGradient: false, color1: '#f97316', color2: '#ec4899', angle: 135 };
    }
    const match = val.match(/linear-gradient\((\d+)deg,\s*(#[a-fA-F0-9]{6}),\s*(#[a-fA-F0-9]{6})\)/);
    if (match) {
        return { isGradient: true, color1: match[2], color2: match[3], angle: parseInt(match[1], 10) };
    }
    return { isGradient: true, color1: '#f97316', color2: '#ec4899', angle: 135 };
}

/**
 * Build gradient CSS string.
 */
function buildGradient(angle, c1, c2) {
    return `linear-gradient(${angle}deg, ${c1}, ${c2})`;
}

/**
 * Preset color swatches.
 */
const SOLID_SWATCHES = [
    '#5170ff', '#330066', '#3b82f6', '#8b5cf6',
    '#ec4899', '#ef4444', '#f97316', '#1e293b',
];

const GRADIENT_SWATCHES_START = [
    '#330066', '#5170ff', '#000000', '#5170ff', '#3b82f6', '#f97316',
];

const GRADIENT_SWATCHES_END = [
    '#5170ff', '#330066', '#0ea5e9', '#22c55e', '#06b6d4', '#a855f7',
];

/**
 * HexColorPicker — a spectrum picker + hex input + swatches panel.
 */
function HexColorPicker({ value, onChange, swatches, label }) {
    const [isOpen, setIsOpen] = useState(false);
    const [hue, setHue] = useState(() => hexToHue(value));
    const [localHex, setLocalHex] = useState(value ? value.replace('#', '') : '');
    const spectrumRef = useRef(null);

    // Sync local state when value changes externally
    useEffect(() => {
        if (value && value.startsWith('#') && value !== '#' + localHex) {
            setLocalHex(value.replace('#', ''));
            setHue(hexToHue(value));
        }
    }, [value]);

    const updateFromPosition = (e) => {
        if (!spectrumRef.current) return;
        const rect = spectrumRef.current.getBoundingClientRect();
        const x = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
        const y = Math.max(0, Math.min(1, (e.clientY - rect.top) / rect.height));

        // Simplified HSB to Hex conversion
        // S = x, V = 1 - y
        const s = x * 100;
        const v = (1 - y) * 100;
        const hex = hsvToHex(hue, s, v);
        onChange(hex);
    };

    const handleMouseDown = (e) => {
        updateFromPosition(e);
        const onMouseMove = (moveEvent) => updateFromPosition(moveEvent);
        const onMouseUp = () => {
            window.removeEventListener('mousemove', onMouseMove);
            window.removeEventListener('mouseup', onMouseUp);
        };
        window.addEventListener('mousemove', onMouseMove);
        window.addEventListener('mouseup', onMouseUp);
    };

    const handleHexChange = (e) => {
        const v = e.target.value.replace(/[^0-9a-fA-F]/g, '').slice(0, 6);
        setLocalHex(v);
        if (v.length === 3 || v.length === 6) {
            const fullHex = v.length === 3 ? `#${v[0]}${v[0]}${v[1]}${v[1]}${v[2]}${v[2]}` : `#${v}`;
            onChange(fullHex);
            setHue(hexToHue(fullHex));
        }
    };

    return (
        <div className="shcb-color-panel">
            <div className="shcb-color-panel-header">
                {label && <div className="shcb-color-panel-label">{label}</div>}
                <button
                    type="button"
                    className={`shcb-color-trigger-btn ${isOpen ? 'active' : ''}`}
                    onClick={() => setIsOpen(!isOpen)}
                >
                    <span className="shcb-trigger-color-preview" style={{ background: value }} />
                    {__('Custom Color', 'shois-chat-button')}
                    <svg className="shcb-trigger-chevron" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3">
                        <polyline points="6 9 12 15 18 9"></polyline>
                    </svg>
                </button>
            </div>

            {isOpen && (
                <div className="shcb-color-picker-dropdown">
                    <div
                        ref={spectrumRef}
                        className="shcb-color-spectrum"
                        style={{ background: `hsl(${hue}, 100%, 50%)` }}
                        onMouseDown={handleMouseDown}
                    >
                        <div className="shcb-spectrum-overlay-white" />
                        <div className="shcb-spectrum-overlay-black" />
                        <div className="shcb-spectrum-handle" style={{
                            left: value ? `${hexToHSV(value).s}%` : '100%',
                            top: value ? `${100 - hexToHSV(value).v}%` : '0%'
                        }} />
                    </div>

                    <div className="shcb-hue-slider-row">
                        <input
                            type="range"
                            min="0"
                            max="360"
                            value={hue}
                            className="shcb-hue-slider"
                            onChange={(e) => {
                                const newHue = parseInt(e.target.value, 10);
                                setHue(newHue);
                                const hsv = hexToHSV(value);
                                onChange(hsvToHex(newHue, hsv.s, hsv.v));
                            }}
                        />
                    </div>
                    <div className="shcb-color-hex-row">
                        <span className="shcb-color-hash">#</span>
                        <input
                            type="text"
                            className="shcb-color-hex-input"
                            value={localHex}
                            onChange={handleHexChange}
                            onBlur={(e) => {
                                // Ensure valid hex on blur
                                if (localHex.length !== 3 && localHex.length !== 6) {
                                    setLocalHex(value.replace('#', ''));
                                }
                            }}
                            maxLength={6}
                            spellCheck={false}
                        />
                        <input
                            type="color"
                            className="shcb-color-native"
                            value={value || '#000000'}
                            onChange={(e) => onChange(e.target.value)}
                            tabIndex={-1}
                        />
                    </div>
                </div>
            )}

            <div className="shcb-color-swatches">
                {swatches.map((c) => (
                    <button
                        key={c}
                        type="button"
                        className={`shcb-color-swatch ${value === c ? 'shcb-color-swatch-active' : ''}`}
                        style={{ background: c }}
                        onClick={() => onChange(c)}
                        title={c}
                    />
                ))}
            </div>
        </div>
    );
}

/**
 * Convert hex to approximate hue (0-360) for spectrum display.
 */
function hexToHue(hex) {
    if (!hex || typeof hex !== 'string' || hex.includes('gradient')) return 120;
    const h = hex.startsWith('#') ? hex : '#' + hex;
    if (h.length !== 7 && h.length !== 4) return 120;
    
    // Simple RGB to HSV
    const r = parseInt(h.length === 7 ? h.slice(1, 3) : h[1] + h[1], 16) / 255;
    const g = parseInt(h.length === 7 ? h.slice(3, 5) : h[2] + h[2], 16) / 255;
    const b = parseInt(h.length === 7 ? h.slice(5, 7) : h[3] + h[3], 16) / 255;
    
    const max = Math.max(r, g, b), min = Math.min(r, g, b);
    const d = max - min;
    if (d === 0) return 0;
    let hue = max === r ? ((g - b) / d) % 6 : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
    return Math.round(hue * 60 + (hue < 0 ? 360 : 0));
}

function hexToHSV(hex) {
    if (!hex || typeof hex !== 'string' || hex.includes('gradient')) return { h: 120, s: 100, v: 100 };
    const h = hex.startsWith('#') ? hex : '#' + hex;
    const r = parseInt(h.length === 7 ? h.slice(1, 3) : h[1] + h[1], 16) / 255;
    const g = parseInt(h.length === 7 ? h.slice(3, 5) : h[2] + h[2], 16) / 255;
    const b = parseInt(h.length === 7 ? h.slice(5, 7) : h[3] + h[3], 16) / 255;
    const max = Math.max(r, g, b), min = Math.min(r, g, b);
    const d = max - min;
    const s = max === 0 ? 0 : d / max;
    const v = max;
    return { h: hexToHue(h), s: s * 100, v: v * 100 };
}

function hsvToHex(h, s, v) {
    s /= 100;
    v /= 100;
    const i = Math.floor(h / 60);
    const f = h / 60 - i;
    const p = v * (1 - s);
    const q = v * (1 - f * s);
    const t = v * (1 - (1 - f) * s);
    let r, g, b;
    switch (i % 6) {
        case 0: r = v, g = t, b = p; break;
        case 1: r = q, g = v, b = p; break;
        case 2: r = p, g = v, b = t; break;
        case 3: r = p, g = q, b = v; break;
        case 4: r = t, g = p, b = v; break;
        case 5: r = v, g = p, b = q; break;
    }
    const toHex = (x) => Math.round(x * 255).toString(16).padStart(2, '0');
    return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
}

/**
 * Color picker field with Solid/Gradient tabs matching the reference design.
 */
function ColorField({ label, value, onChange, showGradients, fallbackColor = '#5170ff' }) {
    const [mode, setMode] = useState(value && value.includes('gradient') ? 'gradient' : 'solid');
    const [gradState, setGradState] = useState(() => parseGradient(value));

    const solidValue = value && !value.includes('gradient') ? value : fallbackColor;

    const updateGrad = (updates) => {
        const next = { ...gradState, ...updates };
        setGradState(next);
        onChange(buildGradient(next.angle, next.color1, next.color2));
    };

    return (
        <div className="shcb-field-group shcb-field-color">
            <label className="shcb-field-label">{label}</label>

            {showGradients && (
                <div className="shcb-color-mode-tabs">
                    <button
                        type="button"
                        className={`shcb-color-mode-tab ${mode === 'solid' ? 'active' : ''}`}
                        onClick={() => {
                            setMode('solid');
                            if (value && value.includes('gradient')) onChange(fallbackColor);
                        }}
                    >
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
                            <rect x="2" y="2" width="20" height="20" rx="3" />
                        </svg>
                        {__('Solid', 'shois-chat-button')}
                    </button>
                    <button
                        type="button"
                        className={`shcb-color-mode-tab ${mode === 'gradient' ? 'active' : ''}`}
                        onClick={() => {
                            setMode('gradient');
                            if (!value || !value.includes('gradient')) {
                                onChange(buildGradient(gradState.angle, gradState.color1, gradState.color2));
                            }
                        }}
                    >
                        <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
                            <defs>
                                <linearGradient id="gt" x1="0" y1="0" x2="1" y2="0">
                                    <stop offset="0%" stopColor="#8b5cf6" />
                                    <stop offset="100%" stopColor="#5170ff" />
                                </linearGradient>
                            </defs>
                            <rect x="2" y="2" width="20" height="20" rx="3" fill="url(#gt)" />
                        </svg>
                        {__('Gradient', 'shois-chat-button')}
                    </button>
                </div>
            )}

            {mode === 'solid' && (
                <div className="shcb-solid-picker">
                    <HexColorPicker
                        value={solidValue}
                        onChange={onChange}
                        swatches={SOLID_SWATCHES}
                    />
                </div>
            )}

            {mode === 'gradient' && (
                <div className="shcb-gradient-builder-v2">
                    <div className="shcb-gradient-panels">
                        <HexColorPicker
                            label={__('START COLOR', 'shois-chat-button')}
                            value={gradState.color1}
                            onChange={(v) => updateGrad({ color1: v })}
                            swatches={GRADIENT_SWATCHES_START}
                        />
                        <HexColorPicker
                            label={__('END COLOR', 'shois-chat-button')}
                            value={gradState.color2}
                            onChange={(v) => updateGrad({ color2: v })}
                            swatches={GRADIENT_SWATCHES_END}
                        />
                    </div>

                    <div className="shcb-gradient-direction-row">
                        <div className="shcb-gradient-direction-info">
                            <span className="shcb-gradient-direction-title">{__('Gradient Direction', 'shois-chat-button')}</span>
                            <span className="shcb-gradient-direction-sub">{__('Adjust the linear flow of colors', 'shois-chat-button')}</span>
                        </div>
                        <div className="shcb-gradient-angle-badge">{gradState.angle}°</div>
                    </div>

                    <div className="shcb-gradient-dial-row">
                        <div className="shcb-gradient-dial-wrap">
                            <input
                                type="range"
                                className="shcb-gradient-dial"
                                min={0}
                                max={360}
                                value={gradState.angle}
                                onChange={(e) => updateGrad({ angle: parseInt(e.target.value, 10) })}
                            />
                        </div>
                        <div className="shcb-gradient-preview-bar">
                            <span className="shcb-gradient-preview-label">{__('START', 'shois-chat-button')}</span>
                            <div
                                className="shcb-gradient-preview-track"
                                style={{ background: buildGradient(gradState.angle, gradState.color1, gradState.color2) }}
                            />
                            <span className="shcb-gradient-preview-label">{__('END', 'shois-chat-button')}</span>
                        </div>
                    </div>
                </div>
            )}
        </div>
    );
}


/**
 * Range slider field.
 */
function RangeField({ label, value, min, max, unit, onChange }) {
    return (
        <div className="shcb-field-group">
            <label className="shcb-field-label">
                {label}
                <span className="shcb-field-value">{value}{unit || 'px'}</span>
            </label>
            <input
                type="range"
                className="shcb-range-input"
                value={value}
                min={min}
                max={max}
                onChange={(e) => onChange(parseInt(e.target.value, 10))}
            />
        </div>
    );
}

/**
 * Position selector.
 */
function PositionSelector({ value, onChange }) {
    const positions = [
        { id: 'bottom-right', label: __('Bottom Right', 'shois-chat-button') },
        { id: 'bottom-left', label: __('Bottom Left', 'shois-chat-button') },
        { id: 'top-right', label: __('Top Right', 'shois-chat-button') },
        { id: 'top-left', label: __('Top Left', 'shois-chat-button') },
    ];

    return (
        <div className="shcb-field-group">
            <label className="shcb-field-label">{__('Widget Position', 'shois-chat-button')}</label>
            <div className="shcb-position-grid">
                {positions.map((p) => (
                    <button
                        key={p.id}
                        className={`shcb-position-btn ${value === p.id ? 'shcb-position-btn-active' : ''}`}
                        onClick={() => onChange(p.id)}
                        type="button"
                    >
                        {p.label}
                    </button>
                ))}
            </div>
        </div>
    );
}

/**
 * Icon selector for trigger button with SVG icons.
 */
function IconSelector({ value, onChange }) {
    return (
        <div className="shcb-field-group">
            {ICON_GROUPS.map((group) => (
                <div key={group.label} className="shcb-icon-group">
                    <span className="shcb-icon-group-label">{group.label}</span>
                    <div className="shcb-icon-grid">
                        {group.icons.map((icon) => (
                            <button
                                key={icon.id}
                                type="button"
                                className={`shcb-icon-option ${value === icon.id ? 'shcb-icon-option-active' : ''}`}
                                onClick={() => onChange(icon.id)}
                                title={icon.label}
                            >
                                <span
                                    className="shcb-icon-svg"
                                    dangerouslySetInnerHTML={{ __html: ICON_SVG[icon.id] }}
                                />
                                <span className="shcb-icon-label">{icon.label}</span>
                            </button>
                        ))}
                    </div>
                </div>
            ))}
        </div>
    );
}

/**
 * DesignTab — visual design controls.
 */
export default function DesignTab({ config, onChange, templateDefaults = {} }) {
    const handleReset = () => {
        if (window.confirm(__('Reset all design settings to defaults?', 'shois-chat-button'))) {
            onChange({ ...DEFAULTS, ...templateDefaults });
        }
    };

    return (
        <div className="shcb-editor-tab-content">
            <div className="shcb-section-header-row">
                <h4 className="shcb-section-title">{__('Colors', 'shois-chat-button')}</h4>
                <button
                    type="button"
                    className="shcb-btn shcb-btn-sm shcb-btn-danger"
                    onClick={handleReset}
                >
                    🔄 {__('Reset Defaults', 'shois-chat-button')}
                </button>
            </div>

            <ColorField
                label={__('Primary Color', 'shois-chat-button')}
                value={config.primary_color}
                onChange={(v) => onChange({ primary_color: v })}
                fallbackColor={templateDefaults.primary_color || DEFAULTS.primary_color}
                showGradients
            />
            <ColorField
                label={__('Header Background', 'shois-chat-button')}
                value={config.header_bg_color}
                onChange={(v) => onChange({ header_bg_color: v })}
                fallbackColor={templateDefaults.header_bg_color || DEFAULTS.header_bg_color}
                showGradients
            />
            <ColorField
                label={__('Header Text Color', 'shois-chat-button')}
                value={config.header_text_color}
                onChange={(v) => onChange({ header_text_color: v })}
                fallbackColor={templateDefaults.header_text_color || DEFAULTS.header_text_color}
            />
            <ColorField
                label={__('Text Color', 'shois-chat-button')}
                value={config.text_color}
                onChange={(v) => onChange({ text_color: v })}
                fallbackColor={templateDefaults.text_color || DEFAULTS.text_color}
            />
            <ColorField
                label={__('Background Color', 'shois-chat-button')}
                value={config.bg_color}
                onChange={(v) => onChange({ bg_color: v })}
                fallbackColor={templateDefaults.bg_color || DEFAULTS.bg_color}
            />

            <h4 className="shcb-section-title">{__('Agent Card & Chat Icon', 'shois-chat-button')}</h4>

            <ColorField
                label={__('Agent Background Color', 'shois-chat-button')}
                value={config.agent_bg_color}
                onChange={(v) => onChange({ agent_bg_color: v })}
                fallbackColor={templateDefaults.agent_bg_color || DEFAULTS.agent_bg_color}
            />

            <ColorField
                label={__('Agent Text Color', 'shois-chat-button')}
                value={config.agent_text_color}
                onChange={(v) => onChange({ agent_text_color: v })}
                fallbackColor={templateDefaults.agent_text_color || DEFAULTS.agent_text_color}
            />

            <RangeField
                label={__('Chat Icon Radius', 'shois-chat-button')}
                value={config.platform_radius !== undefined ? config.platform_radius : 0}
                min={0}
                max={50}
                unit="%"
                onChange={(v) => onChange({ platform_radius: v })}
            />

            <h4 className="shcb-section-title">{__('Trigger Icon', 'shois-chat-button')}</h4>

            <IconSelector
                value={config.trigger_icon || 'whatsapp'}
                onChange={(v) => onChange({ trigger_icon: v })}
            />

            <RangeField
                label={__('Icon Size', 'shois-chat-button')}
                value={config.icon_size || 24}
                min={16}
                max={48}
                onChange={(v) => onChange({ icon_size: v })}
            />

            <ColorField
                label={__('Icon Color', 'shois-chat-button')}
                value={config.icon_color}
                onChange={(v) => onChange({ icon_color: v })}
                fallbackColor="#ffffff"
            />

            <h4 className="shcb-section-title">{__('Position & Size', 'shois-chat-button')}</h4>

            <PositionSelector
                value={config.position || 'bottom-right'}
                onChange={(v) => onChange({ position: v })}
            />

            <RangeField
                label={__('Button Size', 'shois-chat-button')}
                value={config.btn_size || 60}
                min={40}
                max={80}
                onChange={(v) => onChange({ btn_size: v })}
            />

            <RangeField
                label={__('Popup Width', 'shois-chat-button')}
                value={config.popup_width || 360}
                min={280}
                max={480}
                onChange={(v) => onChange({ popup_width: v })}
            />

            <RangeField
                label={__('Offset X', 'shois-chat-button')}
                value={config.offset_x || 24}
                min={0}
                max={80}
                onChange={(v) => onChange({ offset_x: v })}
            />

            <RangeField
                label={__('Offset Y', 'shois-chat-button')}
                value={config.offset_y || 24}
                min={0}
                max={80}
                onChange={(v) => onChange({ offset_y: v })}
            />

            <h4 className="shcb-section-title">{__('Border Radius', 'shois-chat-button')}</h4>

            <RangeField
                label={__('Button Radius', 'shois-chat-button')}
                value={config.radius_btn || 50}
                min={0}
                max={50}
                unit="%"
                onChange={(v) => onChange({ radius_btn: v })}
            />

            <RangeField
                label={__('Popup Radius', 'shois-chat-button')}
                value={config.radius_popup || 16}
                min={0}
                max={32}
                onChange={(v) => onChange({ radius_popup: v })}
            />


        </div>
    );
}
