/* eslint-disable @typescript-eslint/no-explicit-any */
import { h } from "@stencil/core";
import { CodeExampleVariation } from "./code-example-variation.enum";
import { CodeExampleLanguage } from "./code-example-language.enum";
import { ButtonSize } from "../../_button/button/button-size.enum";
import { ButtonVariation } from "../../_button/button/button-variation.enum";
import { CodeBlockVariation } from "../code-block/code-block-variation.enum";
import { _t } from "../../../text";
import { randomIdGenerator } from "../../../global/utils/randomIdGenerator";
/**
 * @private internal use only
 * @enums CodeExampleLanguage - code-example-language.enum.ts
 * @enums CodeExampleVariation - code-example-variation.enum.ts
 * @swedishName Kodexempel
 */
export class CodeExample {
    constructor() {
        this._id = randomIdGenerator('code');
        this.isActive = true;
        this.codeLanguage = undefined;
        this.hasControls = undefined;
        this.showMoreButton = undefined;
        this.containerElement = undefined;
        this.afCode = undefined;
        this.afCodeBlockVariation = CodeBlockVariation.DARK;
        this.afExampleVariation = CodeExampleVariation.LIGHT;
        this.afLanguage = CodeExampleLanguage.HTML;
        this.afHideControls = undefined;
        this.afHideCode = undefined;
    }
    /**
     * Försöker parsa afCode som ett objekt.
     * Returnerar antingen codeExample som sträng - antingen direkt om afCode var en sträng, annars det valda kodspråket.
     */
    get codeExample() {
        let codeString;
        if (typeof this._codeExample === 'object') {
            this.codeLanguage ||
                (this.codeLanguage = this
                    .codeExampleLanguages[0]);
            codeString = this._codeExample[this.codeLanguage];
        }
        else
            codeString = this._codeExample;
        return codeString;
    }
    set codeExample(code) {
        try {
            this._codeExample = JSON.parse(code);
        }
        catch (e) {
            // code är antagligen en sträng och inte objekt.
            this._codeExample = code;
        }
    }
    /**
     * Returnerar tomt om inget kodspråk har skickats med i afCode.
     * Dock returnerar en lista av kodspråk (t.ex. ts eller js) om detta är angett.
     */
    get codeExampleLanguages() {
        return (typeof this._codeExample === 'object' && Object.keys(this._codeExample));
    }
    /**
     * Spara kodexemplet från afCode vid uppdatering av attributet.
     * @en Save the code example from afCode on update of the attribute.
     */
    codeExampleUpdate() {
        this.codeExample = this.afCode;
    }
    componentWillLoad() {
        this.codeExampleUpdate();
        this.hasControls =
            !!this.hostElement.querySelector('[slot="controls"]') ||
                !!this.codeExampleLanguages;
    }
    componentWillUpdate() {
        this.hasControls =
            !!this.hostElement.querySelector('[slot="controls"]') ||
                !!this.codeExampleLanguages;
    }
    componentDidLoad() {
        this.updateShowMoreButton();
    }
    toggleButtonClickHandler() {
        this.isActive = !this.isActive;
    }
    copyButtonClickHandler() {
        navigator.clipboard.writeText(this.codeExample).then(() => {
            // console.log('hurra!');
        }, (err) => {
            // console.log('åh nej!', err);
            console.error(err);
        });
    }
    /**
     * Ändrar kodspråk vid val av radioknapp
     * @param e Event object of the change event.
     */
    codeLanguageChangeHandler(e) {
        this.codeLanguage = e.target.value;
        this.codeExampleUpdate();
    }
    /**
     * Visar "Visa mer" när kodblocket är högre än 180px.
     * @en Show "Visa mer" when code block is higher than 180px.
     */
    updateShowMoreButton() {
        const codeblock = this.containerElement.querySelector('.digi-code-example__codeblock');
        const controls = this.containerElement.querySelector('.digi-code-example__controls > span');
        const example = this.containerElement.querySelector('.digi-code-example__example');
        if (!this._codeHeightObserver && codeblock) {
            this._codeHeightObserver = new ResizeObserver((observable) => {
                const initSetActive = this.showMoreButton == undefined;
                this.showMoreButton =
                    observable[0].target.scrollHeight >=
                        (controls ? controls.scrollHeight - example.scrollHeight + 35 : 64);
                if (initSetActive) {
                    this.isActive = this.showMoreButton ? false : true;
                }
            });
            this._codeHeightObserver.observe(codeblock);
        }
    }
    get cssModifiers() {
        return {
            'digi-code-example--active': this.isActive,
            'digi-code-example--inactive': !this.isActive,
            [`digi-code-example--hide-controls-${!!this.afHideControls}`]: true,
            'digi-code-example--light': this.afExampleVariation === CodeExampleVariation.LIGHT,
            'digi-code-example--dark': this.afExampleVariation === CodeExampleVariation.DARK,
            'digi-code-example--no-controls': !this.hasControls && !this.codeExampleLanguages
        };
    }
    capitalize(word) {
        return word
            .toLowerCase()
            .replace(/\w/, (firstLetter) => firstLetter.toUpperCase());
    }
    render() {
        return (h("div", { key: '2ef6570a3577fc8e68971f09151dec2bd86bdc18', class: Object.assign({ 'digi-code-example': true }, this.cssModifiers), ref: (el) => (this.containerElement = el) }, h("div", { key: '94e1dfbf94a1b7b90a770c86c4c309c02a5d682a', class: {
                'digi-code-example__container': true
            } }, h("div", { key: '2a56800cc263782d8bbbf3962eaacaa1df341067', class: "digi-code-example__example" }, h("slot", { key: 'c11c6a395e412c64291261fc9c849b22960e685b' })), !this.afHideCode && (h("div", { key: 'd230e73ee09938b258675aae499eb5d0f20cb6da', class: "digi-code-example__code" }, this.showMoreButton && (h("button", { key: 'bc334ed8052f21302dc1abd9402974938d3b11ae', class: "digi-code-example__code-expand", "aria-label": this.isActive ? _t.code.show_less : _t.code.show_more, "aria-expanded": this.isActive ? `true` : `false`, onClick: () => this.toggleButtonClickHandler() }, this.isActive ? _t.code.show_less : _t.code.show_more, ' ', h("digi-icon-chevron-down", { key: 'e1d2f3d0908f13abffdda78f83fa008af09f0cb8', class: {
                'digi-code-example__code-expand-icon': true,
                'digi-code-example__code-expand-icon--open': this.isActive
            }, "aria-hidden": "true" }))), h("div", { key: 'a7fe982261026080d861cda236a555a50aee199d', class: {
                'digi-code-example__codeblock': true,
                'digi-code-example__codeblock--light': this.afCodeBlockVariation === 'light',
                'digi-code-example__codeblock--dark': this.afCodeBlockVariation === 'dark',
                'digi-code-example__codeblock--fade': !this.isActive && this.showMoreButton
            } }, h("digi-code-block", { key: '35e29b95fbe734f9823b39d34e91b78e338189b0', afCode: this.codeExample || '', afLanguage: this.afLanguage.toLowerCase(), afVariation: this.afCodeBlockVariation, "af-hide-toolbar": true }), !this.isActive ? (h("div", { class: {
                'digi-code-example__fade': true,
                'digi-code-example__fade--dark': this.afCodeBlockVariation === 'dark',
                'digi-code-example__fade--light': this.afCodeBlockVariation === 'light'
            }, onClick: () => this.toggleButtonClickHandler() })) : (''))))), this.hasControls || !!this.codeExampleLanguages ? (h("div", { class: {
                'digi-code-example__controls': true
            }, hidden: !!this.afHideControls }, h("span", null, h("slot", { name: "controls" }), h("div", { class: "slot__controls" }, this.codeExampleLanguages && (h("digi-form-fieldset", { "af-legend": _t.code.language, "af-name": 'Code-Language-' + this._id, onChange: (e) => this.codeLanguageChangeHandler(e) }, this.codeExampleLanguages.map((codeLang) => (h("digi-form-radiobutton", { afName: 'Code-Language-' + this._id, afChecked: this.codeLanguage === codeLang, afValue: codeLang, afLabel: codeLang }))))))), h("digi-button", { class: "digi-code-example__copy-button", onAfOnClick: () => this.copyButtonClickHandler(), "af-variation": ButtonVariation.FUNCTION, "af-size": ButtonSize.MEDIUM }, h("digi-icon-copy", { class: "digi-code-example__icon", "aria-hidden": "true", slot: "icon" }), _t.code.copy))) : (!this.afHideControls && (h("digi-button", { class: {
                'digi-code-example__copy-button': true,
                'digi-code-example__copy-button--dark': this.afCodeBlockVariation === 'dark'
            }, onAfOnClick: () => this.copyButtonClickHandler(), "af-variation": ButtonVariation.FUNCTION, "af-size": ButtonSize.MEDIUM }, h("digi-icon-copy", { class: "digi-code-example__icon", "aria-hidden": "true", slot: "icon" }), _t.code.copy)))));
    }
    static get is() { return "digi-code-example"; }
    static get encapsulation() { return "scoped"; }
    static get originalStyleUrls() {
        return {
            "$": ["code-example.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["code-example.css"]
        };
    }
    static get properties() {
        return {
            "afCode": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "| string\n    | {\n        [codeLang in CodeExampleLanguage]: string;\n      }",
                    "resolved": "string | { JSON: string; CSS: string; SCSS: string; Typescript: string; Javascript: string; Bash: string; HTML: string; Git: string; Angular: string; React: string; }",
                    "references": {
                        "CodeExampleLanguage": {
                            "location": "import",
                            "path": "./code-example-language.enum",
                            "id": "src/components/_code/code-example/code-example-language.enum.ts::CodeExampleLanguage"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "A string, or object of strings, of code to use in the code block."
                        }],
                    "text": "En str\u00E4ng, eller objekt med str\u00E4ngar, med den kod som du vill visa upp."
                },
                "getter": false,
                "setter": false,
                "attribute": "af-code",
                "reflect": false
            },
            "afCodeBlockVariation": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "CodeBlockVariation",
                    "resolved": "CodeBlockVariation.DARK | CodeBlockVariation.LIGHT",
                    "references": {
                        "CodeBlockVariation": {
                            "location": "import",
                            "path": "../code-block/code-block-variation.enum",
                            "id": "src/components/_code/code-block/code-block-variation.enum.ts::CodeBlockVariation"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "Set code block variation. This defines the syntax highlighting and can be either light or dark."
                        }],
                    "text": "S\u00E4tt f\u00E4rgtemat p\u00E5 kodblocket. Kan vara ljust eller m\u00F6rkt."
                },
                "getter": false,
                "setter": false,
                "attribute": "af-code-block-variation",
                "reflect": false,
                "defaultValue": "CodeBlockVariation.DARK"
            },
            "afExampleVariation": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "CodeExampleVariation",
                    "resolved": "CodeExampleVariation.DARK | CodeExampleVariation.LIGHT",
                    "references": {
                        "CodeExampleVariation": {
                            "location": "import",
                            "path": "./code-example-variation.enum",
                            "id": "src/components/_code/code-example/code-example-variation.enum.ts::CodeExampleVariation"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "Set example background. This defines the syntax highlighting and can be either light or dark."
                        }],
                    "text": "S\u00E4tt f\u00E4rgtemat p\u00E5 exemplets bakgrund. Kan vara ljust eller m\u00F6rkt."
                },
                "getter": false,
                "setter": false,
                "attribute": "af-example-variation",
                "reflect": false,
                "defaultValue": "CodeExampleVariation.LIGHT"
            },
            "afLanguage": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "CodeExampleLanguage",
                    "resolved": "CodeExampleLanguage.ANGULAR | CodeExampleLanguage.BASH | CodeExampleLanguage.CSS | CodeExampleLanguage.GIT | CodeExampleLanguage.HTML | CodeExampleLanguage.JAVASCRIPT | CodeExampleLanguage.JSON | CodeExampleLanguage.REACT | CodeExampleLanguage.SCSS | CodeExampleLanguage.TYPESCRIPT",
                    "references": {
                        "CodeExampleLanguage": {
                            "location": "import",
                            "path": "./code-example-language.enum",
                            "id": "src/components/_code/code-example/code-example-language.enum.ts::CodeExampleLanguage"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "en",
                            "text": "Set code language. Defaults to html."
                        }],
                    "text": "S\u00E4tt programmeringsspr\u00E5k. 'html' \u00E4r f\u00F6rvalt."
                },
                "getter": false,
                "setter": false,
                "attribute": "af-language",
                "reflect": false,
                "defaultValue": "CodeExampleLanguage.HTML"
            },
            "afHideControls": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "attribute": "af-hide-controls",
                "reflect": false
            },
            "afHideCode": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "attribute": "af-hide-code",
                "reflect": false
            }
        };
    }
    static get states() {
        return {
            "isActive": {},
            "codeLanguage": {},
            "hasControls": {},
            "showMoreButton": {},
            "containerElement": {}
        };
    }
    static get elementRef() { return "hostElement"; }
    static get watchers() {
        return [{
                "propName": "afCode",
                "methodName": "codeExampleUpdate"
            }];
    }
}
