/** @type {Gale.CreateSheet} */
globalThis.Gale = (sheet, hash="")=>
{
    const KeyQuery = "@";
    const KeyState = ":";
    const KeyChild = ".";
    const KeyGroup = "^";
    
    /** @type {Gale.Tier} */
    const Tier=(selector, obj, suffix)=>
    {
        const styles = Object.keys(obj).map((key)=>
        {
            const value = obj[key];
            switch(key[0])
            {
                case KeyQuery :
                    return Tier(`@media(max-width:${key.substring(KeyQuery.length)})`, value, suffix);
                case KeyState :
                    return Tier(`&${key}`, value, suffix);
                case KeyChild :
                    return Tier(`${key}${suffix}`, value, suffix);
                case KeyGroup :
                    return Tier(`&:hover .${key.substring(KeyGroup.length)}${suffix}`, value, suffix);
            }
            return `${ key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() }: ${value};`
        });
    
        return `${selector}{${styles.join("\n")}}`;
    }

    /** @type {(needle:string, str:string)=>string} */
    const extractLast =(needle, str)=>{
        const ind = str.lastIndexOf(needle)+needle.length;
        return ind ? str.substring(ind) : str;
    }

    const collect =(tagName)=>
    {
        const pending = van.tags[tagName];
        let mentioned = [];
        const collector = new Proxy(
            (...args)=>
            {
                const element = pending(...args);
                element.className = mentioned.join(id+" ")+id + " " + element.className;
                mentioned = [];
                return element;
            },
            {
                get(_, prop)
                {
                    mentioned.push(prop.substring(prop.lastIndexOf(".")+1));
                    return collector;
                }
            }
        );
        return collector;
    }

    const id = hash ? "_"+hash : "";
    const css = Object.keys(sheet).map(key=>Tier("."+key+id, sheet[key], id)).join(`\n`);
    const style = document.createElement('style');
    style.setAttribute("data-sheet", id);
    style.textContent = css + `*{margin:0;padding:0;box-sizing:border-box;}html, :host{height:100%;width:100%;font-family:Arial, sans-serif;line-height:1.6;}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}img, video{max-width:100%;height:auto;}a{text-decoration:none;color:inherit;}ul, ol{list-style:none;}button, input, textarea{font-family:inherit;font-size:inherit;line-height:inherit;border:none;background:none;padding:0;margin:0;outline:none;}table{border-collapse:collapse;width:100%;}`;
    globalThis.document?.head.appendChild(style);

    return {
        Tag(...args){
            return args.map((arg)=>extractLast(KeyGroup, extractLast(KeyChild, arg))).join(id+" ")+id;
        },
        CSS: css,
        App(selector, ...elements){
            const sr = document.querySelector(selector).attachShadow({ mode: 'open' });
            sr.appendChild(style);
            van.add(sr, ...elements);
            return sr;
        },
        DOM: new Proxy(
            {},
            {
                get(_, prop)
                {
                    return collect(prop)
                }
            }
        ),
        H: new Proxy(
            {},
            {
                get(_, prop)
                {
                    return collect("div")[prop]
                }
            }
        )
    }
}