/**
 * @since Last modified: 2024/04/16 16:13:53
 * @namespace theme
 * @description The tools of theme.
 * @see {@link https://codepen.io/axui/pen/YzMXzKQ|demo @ codepen}
 */
'use strict';
import prefix from "../global/prefix";
import getDataType from "./getDataType";
import isEmpty from "./isEmpty";
import storage from "./storage";
let theme = {
    /**
     * @memberOf theme
     * @description Setting theme colors.
     * @param {string|array} value  - The value to be set.
     * @param {string} [name='']  - The local storage name.
     * @returns {null} .
     * @see {@link https://codepen.io/axui/pen/YzMXzKQ|demo @ codepen}
     * @example
     * ax.theme.set('#0000');
     */
    set: function (value, name = '') {
        if (isEmpty(value)) {
            return;
        }
        let hexToRgbArr = (val) => {
            val = val.trim();
            let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/, colorStr = val.toLowerCase(), result = [];
            if (reg.test(colorStr)) {
                if (colorStr.length === 4) {
                    let temp = '#';
                    for (let k = 1; k < 4; k += 1) {
                        temp += colorStr.slice(k, k + 1).concat(colorStr.slice(k, k + 1));
                    }
                    colorStr = temp;
                }
                for (let k = 1; k < 7; k += 2) {
                    result.push(parseInt("0x" + colorStr.slice(k, k + 2)));
                }
            }
            return result;
        }, rgbToHsl = (arr) => {
            let r = arr[0] / 255, g = arr[1] / 255, b = arr[2] / 255, min = Math.min(r, g, b), max = Math.max(r, g, b), h = 0, s, l = (min + max) / 2, diff = max - min;
            if (max === min) {
                h = 0;
                s = 0;
            }
            else {
                s = l > 0.5 ? diff / (2 - max - min) : diff / (max + min);
                switch (max) {
                    case r:
                        h = (g - b) / diff + (g < b ? 6 : 0);
                        break;
                    case g:
                        h = 2 + (b - r) / diff;
                        break;
                    case b:
                        h = 4 + (r - g) / diff;
                        break;
                }
                h = Math.round(h * 60);
            }
            s = Math.round(s * 100);
            l = Math.round(l * 100);
            return arr.length === 4 ? [h, s, l, arr[3]] : [h, s, l, 1];
        }, getHslaArr = (val) => {
            let valType = getDataType(val), result = [];
            if (!isEmpty(val)) {
                if (valType === 'String') {
                    val = val.trim().toLowerCase();
                    if (val.startsWith('hsl')) {
                        result = val.replace(/^(hsl|hsla)\(/, '').replace(/\)$/, '').replace(/\s/g, '').split(',');
                    }
                    else {
                        let temp = [];
                        if (val.startsWith('#')) {
                            temp = hexToRgbArr(val);
                        }
                        else if (val.startsWith('rgb')) {
                            temp = val.replace(/^(rgb|rgba)\(/, '').replace(/\)$/, '').replace(/\s/g, '').split(',').map(Number);
                        }
                        result = rgbToHsl(temp);
                    }
                }
                else if (valType === 'Array') {
                    result = val;
                }
            }
            result.length === 3 ? result.push(1) : null;
            return result;
        }, valueType = getDataType(value);
        let hslaObj = { prim: [], text: [], error: [], succ: [], info: [], warn: [], issue: [] };
        if (valueType === 'Object') {
            for (let k in value) {
                if (value.hasOwnProperty(k) && value[k].length > 2) {
                    hslaObj[k] = getHslaArr(value[k]);
                }
            }
        }
        else {
            hslaObj.prim = getHslaArr(value);
        }
        if (isEmpty(storage.get('AxThemeRaw'))) {
            storage.set('AxThemeRaw', this.get());
        }
        let rootDom = document.querySelector(":root");
        for (let k in hslaObj) {
            if (hslaObj.hasOwnProperty(k) && hslaObj[k].length > 2) {
                rootDom.style.setProperty(`--${prefix}h-${k}`, hslaObj[k][0]);
                rootDom.style.setProperty(`--${prefix}s-${k}`, typeof hslaObj[k][1] === 'string' && hslaObj[k][1].includes('%') ? hslaObj[k][1] : hslaObj[k][1] + '%');
                rootDom.style.setProperty(`--${prefix}l-${k}`, typeof hslaObj[k][2] === 'string' && hslaObj[k][2].includes('%') ? hslaObj[k][2] : hslaObj[k][2] + '%');
                rootDom.style.setProperty(`--${prefix}a-${k}`, hslaObj[k][3]);
            }
        }
        name ? storage.set(name, hslaObj) : null;
    },
    get: function () {
        let style = getComputedStyle(document.documentElement), getValue = (type) => {
            return [
                style.getPropertyValue(`--${prefix}h-${type}`),
                style.getPropertyValue(`--${prefix}s-${type}`),
                style.getPropertyValue(`--${prefix}l-${type}`),
                style.getPropertyValue(`--${prefix}a-${type}`)
            ].map(k => {
                let val = k.trim();
                return val.includes('%') ? val : Number(val);
            });
        };
        return {
            prim: getValue('prim'),
            text: getValue('text'),
            succ: getValue('succ'),
            error: getValue('error'),
            info: getValue('info'),
            warn: getValue('warn'),
            issue: getValue('issue'),
        };
    },
    reset: function () {
        let themeRaw = storage.get('AxThemeRaw');
        this.set(themeRaw);
    }
};
export default theme;
