import { jsx, jsxs } from 'react/jsx-runtime';
import React__default, { createContext, useMemo, useState, useRef, useEffect, useCallback } from 'react';
import { cn } from '../../../utils/cn.js';
import { FormLabel } from '../FormLabel/FormLabel.js';
import { colorPickerTheme } from './ColorPicker.theme.js';
import { ColorPicker2DCanvas } from './ColorPicker2DCanvas.js';
import { ColorPickerBody } from './ColorPickerBody.js';
import { ColorPickerEyeDropper } from './ColorPickerEyeDropper.js';
import { ColorPickerFormatSelector } from './ColorPickerFormatSelector.js';
import { ColorPickerInput } from './ColorPickerInput.js';
import { ColorPickerPresets } from './ColorPickerPresets.js';
import { ColorPickerSliders } from './ColorPickerSliders.js';
import { ColorPickerSwatch } from './ColorPickerSwatch.js';
import { ColorPickerTrigger } from './ColorPickerTrigger.js';
import { parseColor, formatHex, formatRgb, formatHsl } from './colorUtils.js';

/**
 * ColorPicker Context
 */
const ColorPickerContext = createContext(undefined);
/**
 * Hook to access ColorPicker context
 */
const useColorPicker = () => {
    const context = React__default.useContext(ColorPickerContext);
    if (!context) {
        throw new Error('useColorPicker must be used within a ColorPicker component');
    }
    return context;
};
/**
 * ColorPicker Root Component
 * Follows Flikkui compound component pattern (similar to Accordion, Tabs, Popover)
 */
const ColorPickerRoot = React__default.forwardRef(({ value, defaultValue = '#000000', onChange, format: initialFormat = 'hex', showAlpha = true, showEyeDropper = true, presetColors, size = 'md', state = 'default', disabled = false, label, helperText, required = false, theme, className, children, ...props }, ref) => {
    // Parse initial color value
    const initialColor = useMemo(() => {
        const parsed = parseColor(value || defaultValue);
        return parsed || { h: 0, s: 0, l: 0, a: 1 };
    }, [value, defaultValue]);
    const [color, setColor] = useState(initialColor);
    const [format, setFormat] = useState(initialFormat);
    const [isOpen, setIsOpen] = useState(false);
    // Refs for positioning (like Dropdown)
    const triggerRef = useRef(null);
    // Update color when controlled value changes
    useEffect(() => {
        if (value !== undefined) {
            const parsed = parseColor(value);
            if (parsed) {
                setColor(parsed);
            }
        }
    }, [value]);
    // Individual channel setters
    const setHue = useCallback((h) => {
        setColor((prev) => ({ ...prev, h }));
    }, []);
    const setSaturation = useCallback((s) => {
        setColor((prev) => ({ ...prev, s }));
    }, []);
    const setLightness = useCallback((l) => {
        setColor((prev) => ({ ...prev, l }));
    }, []);
    const setAlpha = useCallback((a) => {
        setColor((prev) => ({ ...prev, a }));
    }, []);
    // Utility functions to get color in different formats
    const getHexValue = useCallback(() => {
        return formatHex(color.h, color.s, color.l);
    }, [color]);
    const getRgbValue = useCallback(() => {
        return formatRgb(color.h, color.s, color.l, color.a);
    }, [color]);
    const getHslValue = useCallback(() => {
        return formatHsl(color.h, color.s, color.l, color.a);
    }, [color]);
    const getFormattedValue = useCallback(() => {
        switch (format) {
            case 'hex':
                return getHexValue();
            case 'rgb':
                return getRgbValue();
            case 'hsl':
                return getHslValue();
            default:
                return getHexValue();
        }
    }, [format, getHexValue, getRgbValue, getHslValue]);
    // Notify parent of color changes
    const prevFormattedRef = useRef(undefined);
    useEffect(() => {
        const formatted = getFormattedValue();
        if (onChange && !disabled && formatted !== prevFormattedRef.current) {
            prevFormattedRef.current = formatted;
            onChange(formatted);
        }
    }, [color, format, onChange, disabled, getFormattedValue]);
    // Merge theme
    const mergedTheme = useMemo(() => ({
        ...colorPickerTheme,
        ...theme,
    }), [theme]);
    // Context value
    const contextValue = useMemo(() => ({
        color,
        setColor,
        setHue,
        setSaturation,
        setLightness,
        setAlpha,
        format,
        setFormat,
        isOpen,
        setIsOpen,
        triggerRef,
        placement: 'bottom-start',
        offset: 4,
        showAlpha,
        showEyeDropper,
        presetColors,
        size,
        state,
        disabled,
        theme: mergedTheme,
        getHexValue,
        getRgbValue,
        getHslValue,
        getFormattedValue,
        onChange,
    }), [
        color,
        setColor,
        setHue,
        setSaturation,
        setLightness,
        setAlpha,
        format,
        setFormat,
        isOpen,
        setIsOpen,
        showAlpha,
        showEyeDropper,
        presetColors,
        size,
        state,
        disabled,
        mergedTheme,
        getHexValue,
        getRgbValue,
        getHslValue,
        getFormattedValue,
        onChange,
    ]);
    return (jsx(ColorPickerContext.Provider, { value: contextValue, children: jsxs("div", { ref: ref, className: cn(mergedTheme.baseStyle, className), ...props, children: [label && (jsx(FormLabel, { htmlFor: "color-picker", required: required, state: state, children: label })), children, helperText && (jsx("div", { className: cn('mt-1.5 text-sm text-[var(--color-text-secondary)]', state === 'invalid' && 'text-[var(--color-danger)]'), children: helperText }))] }) }));
});
ColorPickerRoot.displayName = 'ColorPicker';
/**
 * Export compound component with sub-components
 * Following Flikkui pattern (like Accordion, Tabs, Table)
 */
const ColorPicker = Object.assign(ColorPickerRoot, {
    Trigger: ColorPickerTrigger,
    Body: ColorPickerBody,
    Canvas: ColorPicker2DCanvas,
    Swatch: ColorPickerSwatch,
    Sliders: ColorPickerSliders,
    Input: ColorPickerInput,
    FormatSelector: ColorPickerFormatSelector,
    EyeDropper: ColorPickerEyeDropper,
    Presets: ColorPickerPresets,
});

export { ColorPicker, ColorPickerContext, useColorPicker };
