/**
 * Reusable color-picker popover.
 *
 * Usage:
 *   import { createColorPicker } from '../core/color-picker.ts';
 *   const html = createColorPicker({
 *       id: 'my-picker',
 *       currentColor: '#4CAF50',
 *       onPick: 'myCallback',      // global function name: window[onPick](hex)
 *       anchor: 'left',            // 'left' | 'right' (default 'right')
 *   });
 *
 * The returned HTML contains:
 *   - A small swatch dot (click to toggle popover)
 *   - A popover with 9 preset colors + custom native picker
 *
 * Call `closeAllColorPickers()` to dismiss any open popover.
 */

import { t } from './i18n.ts';

const PRESETS = [
    '#4CAF50', '#7C4DFF', '#FF6D00',
    '#E91E63', '#00BCD4', '#FF5252',
    '#26A69A', '#2196F3', '#FFC107',
];

/**
 * Build the HTML string for a color-picker widget.
 */
export function createColorPicker({ id, currentColor, onPick, anchor = 'right', showReset = false, resetColor = '#808080' }: { id: string; currentColor: string; onPick?: string; anchor?: string; showReset?: boolean; resetColor?: string }) {
    const dots = PRESETS.map(c => {
        const active = c.toLowerCase() === currentColor.toLowerCase() ? ' active' : '';
        return `<button class="color-picker-dot${active}" style="background:${c}" aria-label="${c}" onclick="event.stopPropagation(); window._cpPick('${id}','${c}')"></button>`;
    }).join('');

    const resetBtn = showReset
        ? `<div class="color-picker-reset" onclick="event.stopPropagation(); window._cpReset('${id}','${resetColor}')"><span>${t('accent.reset')}</span></div>`
        : '';

    return `<span class="color-picker-wrapper" id="cp-wrap-${id}">` +
        `<span class="color-picker-swatch" id="cp-swatch-${id}" style="background:${currentColor}" onclick="event.stopPropagation(); window._cpToggle('${id}')"></span>` +
        `<div class="color-picker-popover anchor-${anchor}" id="cp-pop-${id}" style="display:none" onclick="event.stopPropagation()">` +
            `<div class="color-picker-grid">${dots}</div>` +
            `<div class="color-picker-custom" onclick="this.querySelector('input').click()">` +
                `<input type="color" id="cp-native-${id}" value="${currentColor}" ` +
                    `oninput="event.stopPropagation(); window._cpPick('${id}',this.value)" ` +
                    `onchange="event.stopPropagation(); window._cpPick('${id}',this.value)">` +
                `<span>${t('accent.custom')}</span>` +
            `</div>` +
            resetBtn +
        `</div>` +
    `</span>`;
}

// -- Global helpers called from onclick attributes --

// Merge any callbacks pre-registered before this module loaded (e.g. accent picker in index.html)
const _callbacks: Record<string, (hex: string) => void> = Object.assign({}, window._cpCallbacks || {});

/** Register the callback for a picker id. */
export function registerColorPicker(id: string, callback: (hex: string) => void) {
    _callbacks[id] = callback;
}

function _rgbToHex(rgb: string) {
    const m = rgb.match(/\d+/g);
    if (!m || m.length < 3) return rgb;
    return '#' + m.slice(0, 3).map(n => parseInt(n).toString(16).padStart(2, '0')).join('');
}

window._cpToggle = function (id) {
    // Close all other pickers first (and drop their card elevation)
    document.querySelectorAll('.color-picker-popover').forEach((p: Element) => {
        if (p.id !== `cp-pop-${id}`) {
            _cpClosePopover(p as HTMLElement);
        }
    });
    const pop = document.getElementById(`cp-pop-${id}`);
    if (!pop) return;
    const show = pop.style.display === 'none';
    if (!show) {
        _cpClosePopover(pop);
        return;
    }
    pop.style.display = '';
    // Elevate the card so the popover isn't clipped by sibling cards
    const card = pop.closest('.card, .template-card');
    if (card) card.classList.toggle('cp-elevated', true);

    // On small/touch screens, move popover to body as a centered bottom-sheet
    // to avoid any parent overflow/containment/positioning issues.
    const isMobile = window.innerWidth <= 768 || ('ontouchstart' in window);
    if (isMobile && pop.parentElement !== document.body) {
        (pop as any)._cpOrigParent = pop.parentElement;
        (pop as any)._cpOrigNext = pop.nextSibling;
        document.body.appendChild(pop);
    }
    if (isMobile) {
        pop.style.position = 'fixed';
        pop.style.left = '0';
        pop.style.right = '0';
        pop.style.top = 'auto';
        pop.style.bottom = '70px';
        pop.style.margin = '0 auto';
        pop.style.width = 'fit-content';
        pop.style.transform = 'none';
        pop.style.animation = 'none';
        pop.style.zIndex = '10000';
        pop.classList.add('cp-fixed');
    }

    // Mark active dot
    const swatch = document.getElementById(`cp-swatch-${id}`);
    const cur = swatch ? (_rgbToHex(swatch.style.backgroundColor) || swatch.style.background) : '';
    pop.querySelectorAll('.color-picker-dot').forEach((d: Element) => {
        const el = d as HTMLElement;
        const dHex = _rgbToHex(el.style.backgroundColor || el.style.background);
        el.classList.toggle('active', dHex.toLowerCase() === cur.toLowerCase());
    });
};

/** Reset popover positioning and close. */
function _cpClosePopover(pop: HTMLElement) {
    pop.style.display = 'none';
    if (pop.classList.contains('cp-fixed')) {
        pop.classList.remove('cp-fixed');
        pop.style.position = '';
        pop.style.top = '';
        pop.style.right = '';
        pop.style.left = '';
        pop.style.bottom = '';
        pop.style.transform = '';
        pop.style.animation = '';
        pop.style.margin = '';
        pop.style.width = '';
        pop.style.zIndex = '';
        // Return popover to its original parent
        if ((pop as any)._cpOrigParent) {
            (pop as any)._cpOrigParent.insertBefore(pop, (pop as any)._cpOrigNext || null);
            delete (pop as any)._cpOrigParent;
            delete (pop as any)._cpOrigNext;
        }
    }
    const card = pop.closest('.card, .template-card');
    if (card) card.classList.remove('cp-elevated');
    // Remove graph color picker overlay (swatch + popover wrapper)
    const graphOverlay = pop.closest('.graph-cp-overlay');
    if (graphOverlay) graphOverlay.remove();
}

window._cpPick = function (id, hex) {
    // Update swatch
    const swatch = document.getElementById(`cp-swatch-${id}`);
    if (swatch) swatch.style.background = hex;
    // Update native input
    const native = document.getElementById(`cp-native-${id}`) as HTMLInputElement | null;
    if (native) native.value = hex;
    // Mark active dot and close
    const pop = document.getElementById(`cp-pop-${id}`);
    if (pop) {
        pop.querySelectorAll('.color-picker-dot').forEach((d: Element) => {
            const el = d as HTMLElement;
            const dHex = _rgbToHex(el.style.backgroundColor || el.style.background);
            el.classList.toggle('active', dHex.toLowerCase() === hex.toLowerCase());
        });
        _cpClosePopover(pop);
    }
    // Fire callback
    if (_callbacks[id]) _callbacks[id](hex);
};

window._cpReset = function (id: string, resetColor: string) {
    // Reset swatch to neutral color
    const swatch = document.getElementById(`cp-swatch-${id}`);
    if (swatch) swatch.style.background = resetColor;
    // Clear active dots and close popover
    const pop = document.getElementById(`cp-pop-${id}`);
    if (pop) {
        pop.querySelectorAll('.color-picker-dot').forEach(d => d.classList.remove('active'));
        _cpClosePopover(pop);
    }
    // Fire callback with empty string to signal removal
    if (_callbacks[id]) _callbacks[id]('');
};

export function closeAllColorPickers() {
    document.querySelectorAll('.color-picker-popover').forEach(p => _cpClosePopover(p as HTMLElement));
}

// Close on outside click
document.addEventListener('click', () => closeAllColorPickers());
