import * as i0 from '@angular/core';
import { inject, viewChild, input, signal, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { ZButtonComponent } from '@shival99/z-ui/components/z-button';
import { ZIconComponent } from '@shival99/z-ui/components/z-icon';
import { ZToastService } from '@shival99/z-ui/components/z-toast';
import { ZThemeService, ZTranslateService } from '@shival99/z-ui/services';
import { zMergeClasses } from '@shival99/z-ui/utils';
import { createBundledHighlighter } from 'shiki/core';

const Z_CODE_LANGS = [
    'typescript',
    'javascript',
    'html',
    'css',
    'scss',
    'json',
    'bash',
    'shell',
    'markdown',
    'yaml',
    'python',
    'java',
    'sql',
    'xml',
    'angular-ts',
    'angular-html',
];
const Z_CODE_THEMES = ['github-dark', 'github-light', 'vitesse-dark', 'one-dark-pro'];
const createZCodeHighlighter = createBundledHighlighter({
    langs: {
        typescript: () => import('shiki/dist/langs/typescript.mjs'),
        javascript: () => import('shiki/dist/langs/javascript.mjs'),
        html: () => import('shiki/dist/langs/html.mjs'),
        css: () => import('shiki/dist/langs/css.mjs'),
        scss: () => import('shiki/dist/langs/scss.mjs'),
        json: () => import('shiki/dist/langs/json.mjs'),
        bash: () => import('shiki/dist/langs/bash.mjs'),
        shell: () => import('shiki/dist/langs/shell.mjs'),
        markdown: () => import('shiki/dist/langs/markdown.mjs'),
        yaml: () => import('shiki/dist/langs/yaml.mjs'),
        python: () => import('shiki/dist/langs/python.mjs'),
        java: () => import('shiki/dist/langs/java.mjs'),
        sql: () => import('shiki/dist/langs/sql.mjs'),
        xml: () => import('shiki/dist/langs/xml.mjs'),
        'angular-ts': () => import('shiki/dist/langs/angular-ts.mjs'),
        'angular-html': () => import('shiki/dist/langs/angular-html.mjs'),
    },
    themes: {
        'github-dark': () => import('shiki/dist/themes/github-dark.mjs'),
        'github-light': () => import('shiki/dist/themes/github-light.mjs'),
        'vitesse-dark': () => import('shiki/dist/themes/vitesse-dark.mjs'),
        'one-dark-pro': () => import('shiki/dist/themes/one-dark-pro.mjs'),
    },
    engine: () => import('shiki/engine/javascript').then(m => m.createJavaScriptRegexEngine()),
});
const getHighlighter = (() => {
    let cache = null;
    return async () => {
        if (cache) {
            return cache;
        }
        cache = createZCodeHighlighter({
            themes: [...Z_CODE_THEMES],
            langs: [...Z_CODE_LANGS],
        });
        return cache;
    };
})();
function escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
}

class ZCodeComponent {
    _toast = inject(ZToastService);
    _sanitizer = inject(DomSanitizer);
    _themeService = inject(ZThemeService);
    _zTranslate = inject(ZTranslateService);
    codeEl = viewChild('codeEl', ...(ngDevMode ? [{ debugName: "codeEl" }] : []));
    class = input('', ...(ngDevMode ? [{ debugName: "class" }] : []));
    zTitle = input('', ...(ngDevMode ? [{ debugName: "zTitle" }] : []));
    zLanguage = input('typescript', ...(ngDevMode ? [{ debugName: "zLanguage" }] : []));
    zCode = input('', ...(ngDevMode ? [{ debugName: "zCode" }] : []));
    zTheme = input('', ...(ngDevMode ? [{ debugName: "zTheme" }] : []));
    zShowLineNumbers = input(true, ...(ngDevMode ? [{ debugName: "zShowLineNumbers" }] : []));
    copied = signal(false, ...(ngDevMode ? [{ debugName: "copied" }] : []));
    highlightedCode = signal('', ...(ngDevMode ? [{ debugName: "highlightedCode" }] : []));
    isHighlighting = signal(true, ...(ngDevMode ? [{ debugName: "isHighlighting" }] : []));
    _rawCode = '';
    _effectiveTheme = computed(() => {
        const inputTheme = this.zTheme();
        if (inputTheme) {
            return inputTheme;
        }
        return this._themeService.isDark() ? 'github-dark' : 'github-light';
    }, ...(ngDevMode ? [{ debugName: "_effectiveTheme" }] : []));
    wrapperClasses = computed(() => zMergeClasses('border-border bg-card overflow-hidden rounded-lg border', this.class()), ...(ngDevMode ? [{ debugName: "wrapperClasses" }] : []));
    contentClasses = computed(() => zMergeClasses('overflow-x-auto p-4', this.zTitle() ? '' : 'pt-10'), ...(ngDevMode ? [{ debugName: "contentClasses" }] : []));
    constructor() {
        effect(() => {
            const code = this.zCode();
            const lang = this.zLanguage();
            const theme = this._effectiveTheme();
            if (!code) {
                return;
            }
            this._rawCode = code;
            void this._highlightCode(code, lang, theme);
        });
    }
    ngAfterViewInit() {
        if (this.zCode()) {
            return;
        }
        const codeEl = this.codeEl()?.nativeElement;
        if (!codeEl) {
            return;
        }
        const preEl = codeEl.querySelector('pre');
        const codeContent = preEl?.querySelector('code');
        const rawText = codeContent?.textContent ?? preEl?.textContent ?? codeEl.textContent ?? '';
        if (!rawText.trim()) {
            return;
        }
        this._rawCode = rawText.trim();
        void this._highlightCode(this._rawCode, this.zLanguage(), this._effectiveTheme());
    }
    async _highlightCode(code, lang, theme) {
        this.isHighlighting.set(true);
        try {
            const highlighter = await getHighlighter();
            const html = highlighter.codeToHtml(code, { lang, theme });
            const safeHtml = this._sanitizer.bypassSecurityTrustHtml(html);
            this.highlightedCode.set(safeHtml);
        }
        catch (error) {
            console.warn('Shiki highlighting failed, falling back to plain text:', error);
            const escapedHtml = `<pre class="shiki"><code>${escapeHtml(code)}</code></pre>`;
            this.highlightedCode.set(this._sanitizer.bypassSecurityTrustHtml(escapedHtml));
        }
        finally {
            this.isHighlighting.set(false);
        }
    }
    copyCode() {
        const code = this._rawCode.trim();
        void navigator.clipboard.writeText(code).then(() => {
            this.copied.set(true);
            this._toast.success(this._zTranslate.instant('i18n_z_ui_code_copied'));
            setTimeout(() => {
                this.copied.set(false);
            }, 2000);
        });
    }
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZCodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.9", type: ZCodeComponent, isStandalone: true, selector: "z-code", inputs: { class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, zTitle: { classPropertyName: "zTitle", publicName: "zTitle", isSignal: true, isRequired: false, transformFunction: null }, zLanguage: { classPropertyName: "zLanguage", publicName: "zLanguage", isSignal: true, isRequired: false, transformFunction: null }, zCode: { classPropertyName: "zCode", publicName: "zCode", isSignal: true, isRequired: false, transformFunction: null }, zTheme: { classPropertyName: "zTheme", publicName: "zTheme", isSignal: true, isRequired: false, transformFunction: null }, zShowLineNumbers: { classPropertyName: "zShowLineNumbers", publicName: "zShowLineNumbers", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "codeEl", first: true, predicate: ["codeEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div [class]=\"wrapperClasses()\">\n  @if (zTitle()) {\n    <div class=\"z-code-header border-border flex items-center justify-between border-b px-4 py-2\">\n      <span class=\"text-muted-foreground text-xs font-medium\">{{ zTitle() }}</span>\n      <button z-button zType=\"outline\" zSize=\"xs\" [zWave]=\"false\" (click)=\"copyCode()\">\n        @if (copied()) {\n          <z-icon zType=\"lucideCheck\" zSize=\"14\" class=\"text-green-500\" />\n          <span class=\"text-green-500\">Copied!</span>\n        } @else {\n          <z-icon zType=\"lucideCopy\" zSize=\"14\" />\n          <span>Copy</span>\n        }\n      </button>\n    </div>\n  }\n  <div class=\"relative\">\n    @if (!zTitle()) {\n      <button\n        z-button\n        zType=\"outline\"\n        zSize=\"xs\"\n        [zWave]=\"false\"\n        class=\"absolute top-2 right-2 z-10 backdrop-blur-sm\"\n        (click)=\"copyCode()\">\n        @if (copied()) {\n          <z-icon zType=\"lucideCheck\" zSize=\"14\" class=\"text-green-500\" />\n          <span class=\"text-green-500\">Copied!</span>\n        } @else {\n          <z-icon zType=\"lucideCopy\" zSize=\"14\" />\n          <span>Copy</span>\n        }\n      </button>\n    }\n    @if (isHighlighting()) {\n      <div class=\"p-4\">\n        <div class=\"bg-muted h-4 w-3/4 animate-pulse rounded\"></div>\n        <div class=\"bg-muted mt-2 h-4 w-1/2 animate-pulse rounded\"></div>\n        <div class=\"bg-muted mt-2 h-4 w-2/3 animate-pulse rounded\"></div>\n      </div>\n    } @else {\n      <div #codeEl [class]=\"contentClasses()\" [innerHTML]=\"highlightedCode()\"></div>\n    }\n  </div>\n</div>\n", styles: [":host{display:block}:host ::ng-deep .shiki{margin:0;padding:0;overflow-x:auto;background:transparent!important;background-color:transparent!important}:host ::ng-deep .shiki code{font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;font-size:.875rem;line-height:1.7;display:block;counter-reset:line}:host ::ng-deep .shiki .line{display:inline-block;width:100%}:host ::ng-deep .shiki .line:before{counter-increment:line;content:counter(line);display:inline-block;width:2rem;margin-right:1rem;text-align:right;color:var(--muted-foreground);opacity:.5;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "component", type: ZIconComponent, selector: "z-icon, [z-icon]", inputs: ["class", "zType", "zAnimatedType", "zAnimate", "zAnimationTrigger", "zSize", "zStrokeWidth", "zSvg"] }, { kind: "component", type: ZButtonComponent, selector: "z-button, button[z-button], a[z-button]", inputs: ["class", "zType", "zSize", "zShape", "zLabel", "zLoading", "zDisabled", "zTypeIcon", "zAnimatedTypeIcon", "zAnimateIcon", "zAnimationTriggerIcon", "zSizeIcon", "zStrokeWidthIcon", "zWave"], exportAs: ["zButton"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.9", ngImport: i0, type: ZCodeComponent, decorators: [{
            type: Component,
            args: [{ selector: 'z-code', imports: [ZIconComponent, ZButtonComponent], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [class]=\"wrapperClasses()\">\n  @if (zTitle()) {\n    <div class=\"z-code-header border-border flex items-center justify-between border-b px-4 py-2\">\n      <span class=\"text-muted-foreground text-xs font-medium\">{{ zTitle() }}</span>\n      <button z-button zType=\"outline\" zSize=\"xs\" [zWave]=\"false\" (click)=\"copyCode()\">\n        @if (copied()) {\n          <z-icon zType=\"lucideCheck\" zSize=\"14\" class=\"text-green-500\" />\n          <span class=\"text-green-500\">Copied!</span>\n        } @else {\n          <z-icon zType=\"lucideCopy\" zSize=\"14\" />\n          <span>Copy</span>\n        }\n      </button>\n    </div>\n  }\n  <div class=\"relative\">\n    @if (!zTitle()) {\n      <button\n        z-button\n        zType=\"outline\"\n        zSize=\"xs\"\n        [zWave]=\"false\"\n        class=\"absolute top-2 right-2 z-10 backdrop-blur-sm\"\n        (click)=\"copyCode()\">\n        @if (copied()) {\n          <z-icon zType=\"lucideCheck\" zSize=\"14\" class=\"text-green-500\" />\n          <span class=\"text-green-500\">Copied!</span>\n        } @else {\n          <z-icon zType=\"lucideCopy\" zSize=\"14\" />\n          <span>Copy</span>\n        }\n      </button>\n    }\n    @if (isHighlighting()) {\n      <div class=\"p-4\">\n        <div class=\"bg-muted h-4 w-3/4 animate-pulse rounded\"></div>\n        <div class=\"bg-muted mt-2 h-4 w-1/2 animate-pulse rounded\"></div>\n        <div class=\"bg-muted mt-2 h-4 w-2/3 animate-pulse rounded\"></div>\n      </div>\n    } @else {\n      <div #codeEl [class]=\"contentClasses()\" [innerHTML]=\"highlightedCode()\"></div>\n    }\n  </div>\n</div>\n", styles: [":host{display:block}:host ::ng-deep .shiki{margin:0;padding:0;overflow-x:auto;background:transparent!important;background-color:transparent!important}:host ::ng-deep .shiki code{font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,Liberation Mono,monospace;font-size:.875rem;line-height:1.7;display:block;counter-reset:line}:host ::ng-deep .shiki .line{display:inline-block;width:100%}:host ::ng-deep .shiki .line:before{counter-increment:line;content:counter(line);display:inline-block;width:2rem;margin-right:1rem;text-align:right;color:var(--muted-foreground);opacity:.5;-webkit-user-select:none;user-select:none}\n"] }]
        }], ctorParameters: () => [], propDecorators: { codeEl: [{ type: i0.ViewChild, args: ['codeEl', { isSignal: true }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], zTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "zTitle", required: false }] }], zLanguage: [{ type: i0.Input, args: [{ isSignal: true, alias: "zLanguage", required: false }] }], zCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "zCode", required: false }] }], zTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "zTheme", required: false }] }], zShowLineNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "zShowLineNumbers", required: false }] }] } });

/**
 * Generated bundle index. Do not edit.
 */

export { ZCodeComponent };
//# sourceMappingURL=shival99-z-ui-components-z-code.mjs.map
