"use client";
import { jsx, jsxs } from "react/jsx-runtime";
import "./color-picker.css";
import { useEffect, useMemo, useRef, useState } from "react";
import text_input from "./text-input.js";
const basicColors = [
    '#d0021b',
    '#f5a623',
    '#f8e71c',
    '#8b572a',
    '#7ed321',
    '#417505',
    '#bd10e0',
    '#9013fe',
    '#4a90e2',
    '#50e3c2',
    '#b8e986',
    '#000000',
    '#4a4a4a',
    '#9b9b9b',
    '#ffffff'
];
const WIDTH = 214;
const HEIGHT = 150;
function ColorPicker({ color, onChange }) {
    const [selfColor, setSelfColor] = useState(transformColor('hex', color));
    const [inputColor, setInputColor] = useState(color);
    const innerDivRef = useRef(null);
    const saturationPosition = useMemo(()=>({
            x: selfColor.hsv.s / 100 * WIDTH,
            y: (100 - selfColor.hsv.v) / 100 * HEIGHT
        }), [
        selfColor.hsv.s,
        selfColor.hsv.v
    ]);
    const huePosition = useMemo(()=>({
            x: selfColor.hsv.h / 360 * WIDTH
        }), [
        selfColor.hsv
    ]);
    const onSetHex = (hex)=>{
        setInputColor(hex);
        if (/^#[0-9A-Fa-f]{6}$/i.test(hex)) {
            const newColor = transformColor('hex', hex);
            setSelfColor(newColor);
        }
    };
    const onMoveSaturation = ({ x, y })=>{
        const newHsv = {
            ...selfColor.hsv,
            s: x / WIDTH * 100,
            v: 100 - y / HEIGHT * 100
        };
        const newColor = transformColor('hsv', newHsv);
        setSelfColor(newColor);
        setInputColor(newColor.hex);
    };
    const onMoveHue = ({ x })=>{
        const newHsv = {
            ...selfColor.hsv,
            h: x / WIDTH * 360
        };
        const newColor = transformColor('hsv', newHsv);
        setSelfColor(newColor);
        setInputColor(newColor.hex);
    };
    useEffect(()=>{
        if (null !== innerDivRef.current && null != onChange) {
            onChange(selfColor.hex);
            setInputColor(selfColor.hex);
        }
    }, [
        selfColor,
        onChange
    ]);
    useEffect(()=>{
        if (void 0 === color) return;
        const newColor = transformColor('hex', color);
        setSelfColor(newColor);
        setInputColor(newColor.hex);
    }, [
        color
    ]);
    return /*#__PURE__*/ jsxs("div", {
        className: "color-picker-wrapper",
        style: {
            width: WIDTH
        },
        ref: innerDivRef,
        children: [
            /*#__PURE__*/ jsx(text_input, {
                label: "Hex",
                onChange: onSetHex,
                value: inputColor
            }),
            /*#__PURE__*/ jsx("div", {
                className: "color-picker-basic-color",
                children: basicColors.map((basicColor)=>/*#__PURE__*/ jsx("button", {
                        type: "button",
                        className: basicColor === selfColor.hex ? ' active' : '',
                        style: {
                            backgroundColor: basicColor
                        },
                        onClick: ()=>{
                            setInputColor(basicColor);
                            setSelfColor(transformColor('hex', basicColor));
                        }
                    }, basicColor))
            }),
            /*#__PURE__*/ jsx(MoveWrapper, {
                className: "color-picker-saturation",
                style: {
                    backgroundColor: `hsl(${selfColor.hsv.h}, 100%, 50%)`
                },
                onChange: onMoveSaturation,
                ariaLabel: "Saturation and value",
                children: /*#__PURE__*/ jsx("div", {
                    className: "color-picker-saturation_cursor",
                    style: {
                        backgroundColor: selfColor.hex,
                        left: saturationPosition.x,
                        top: saturationPosition.y
                    }
                })
            }),
            /*#__PURE__*/ jsx(MoveWrapper, {
                className: "color-picker-hue",
                onChange: onMoveHue,
                ariaLabel: "Hue",
                children: /*#__PURE__*/ jsx("div", {
                    className: "color-picker-hue_cursor",
                    style: {
                        backgroundColor: `hsl(${selfColor.hsv.h}, 100%, 50%)`,
                        left: huePosition.x
                    }
                })
            }),
            /*#__PURE__*/ jsx("div", {
                className: "color-picker-color",
                style: {
                    backgroundColor: selfColor.hex
                }
            })
        ]
    });
}
function MoveWrapper({ className, style, onChange, children, ariaLabel }) {
    const divRef = useRef(null);
    const lastPositionRef = useRef({
        x: WIDTH / 2,
        y: HEIGHT / 2
    });
    const applyPosition = (position)=>{
        lastPositionRef.current = position;
        onChange(position);
    };
    const move = (e)=>{
        if (null != divRef.current) {
            const { current: div } = divRef;
            const { width, height, left, top } = div.getBoundingClientRect();
            const x = clamp(e.clientX - left, width, 0);
            const y = clamp(e.clientY - top, height, 0);
            applyPosition({
                x,
                y
            });
        }
    };
    const onMouseDown = (e)=>{
        if (0 !== e.button) return;
        move(e);
        const onMouseMove = (_e)=>{
            move(_e);
        };
        const onMouseUp = (_e)=>{
            document.removeEventListener('mousemove', onMouseMove, false);
            document.removeEventListener('mouseup', onMouseUp, false);
            move(_e);
        };
        document.addEventListener('mousemove', onMouseMove, false);
        document.addEventListener('mouseup', onMouseUp, false);
    };
    const onKeyDown = (e)=>{
        if (null == divRef.current) return;
        const { width, height } = divRef.current.getBoundingClientRect();
        const stepX = Math.max(1, width / 50);
        const stepY = Math.max(1, height / 50);
        const current = lastPositionRef.current;
        let next = null;
        switch(e.key){
            case 'ArrowLeft':
                next = {
                    x: clamp(current.x - stepX, width, 0),
                    y: current.y
                };
                break;
            case 'ArrowRight':
                next = {
                    x: clamp(current.x + stepX, width, 0),
                    y: current.y
                };
                break;
            case 'ArrowUp':
                next = {
                    x: current.x,
                    y: clamp(current.y - stepY, height, 0)
                };
                break;
            case 'ArrowDown':
                next = {
                    x: current.x,
                    y: clamp(current.y + stepY, height, 0)
                };
                break;
            case 'Home':
                next = {
                    x: 0,
                    y: 0
                };
                break;
            case 'End':
                next = {
                    x: width,
                    y: height
                };
                break;
            default:
                break;
        }
        if (null != next) {
            e.preventDefault();
            applyPosition(next);
        }
    };
    return /*#__PURE__*/ jsx("div", {
        ref: divRef,
        className: className,
        style: style,
        onMouseDown: onMouseDown,
        role: "button",
        tabIndex: 0,
        "aria-label": ariaLabel,
        onKeyDown: onKeyDown,
        children: children
    });
}
function clamp(value, max, min) {
    return value > max ? max : value < min ? min : value;
}
function toHex(value) {
    if (value.startsWith('#')) {
        if (4 === value.length || 5 === value.length) {
            value = value.split('').map((v, i)=>Number.isNaN(i) ? '#' : v + v).join('');
            return value;
        } else if (7 === value.length || 9 === value.length) return value;
    } else {
        const ctx = document.createElement('canvas').getContext('2d');
        if (null == ctx) throw new Error('2d context not supported or canvas already initialized');
        ctx.fillStyle = value;
        return ctx.fillStyle;
    }
    return '#000000';
}
function hex2rgb(hex) {
    const rbgArr = (hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, (_m, r, g, b)=>`#${r}${r}${g}${g}${b}${b}`).substring(1).match(/.{2}/g) ?? []).map((x)=>parseInt(x, 16));
    return {
        b: rbgArr[2],
        g: rbgArr[1],
        r: rbgArr[0]
    };
}
function rgb2hsv({ r, g, b }) {
    r /= 255;
    g /= 255;
    b /= 255;
    const max = Math.max(r, g, b);
    const d = max - Math.min(r, g, b);
    const h = Number.isNaN(d) ? 0 : (max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? 2 + (b - r) / d : 4 + (r - g) / d) * 60;
    const s = Number.isNaN(max) ? 0 : d / max * 100;
    const v = 100 * max;
    return {
        h,
        s,
        v
    };
}
function hsv2rgb({ h, s, v }) {
    s /= 100;
    v /= 100;
    const i = ~~(h / 60);
    const f = h / 60 - i;
    const p = v * (1 - s);
    const q = v * (1 - s * f);
    const t = v * (1 - s * (1 - f));
    const index = i % 6;
    const r = Math.round(255 * [
        v,
        q,
        p,
        p,
        t,
        v
    ][index]);
    const g = Math.round(255 * [
        t,
        v,
        v,
        q,
        p,
        p
    ][index]);
    const b = Math.round(255 * [
        p,
        p,
        t,
        v,
        v,
        q
    ][index]);
    return {
        b,
        g,
        r
    };
}
function rgb2hex({ b, g, r }) {
    return `#${[
        r,
        g,
        b
    ].map((x)=>x.toString(16).padStart(2, '0')).join('')}`;
}
function transformColor(format, color) {
    let hex = toHex('#121212');
    let rgb = hex2rgb(hex);
    let hsv = rgb2hsv(rgb);
    if ('hex' === format) {
        const value = color;
        hex = toHex(value);
        rgb = hex2rgb(hex);
        hsv = rgb2hsv(rgb);
    } else if ('rgb' === format) {
        const value = color;
        rgb = value;
        hex = rgb2hex(rgb);
        hsv = rgb2hsv(rgb);
    } else if ('hsv' === format) {
        const value = color;
        hsv = value;
        rgb = hsv2rgb(hsv);
        hex = rgb2hex(rgb);
    }
    return {
        hex,
        hsv,
        rgb
    };
}
export default ColorPicker;
export { toHex };
