import { Component, Input } from '@angular/core';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@progress/kendo-angular-inputs";
import * as i3 from "@memberjunction/ng-code-editor";
const _forTrack0 = ($index, $item) => $item.id;
function ChatMessageViewerComponent_Conditional_18_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 9);
    i0.ɵɵelement(1, "i", 10);
    i0.ɵɵelementStart(2, "p");
    i0.ɵɵtext(3, "No messages to display");
    i0.ɵɵelementEnd()();
} }
function ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Conditional_20_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 24);
    i0.ɵɵelement(1, "mj-code-editor", 26);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const item_r4 = i0.ɵɵnextContext(3).$implicit;
    const ctx_r2 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵproperty("value", ctx_r2.getContentString(item_r4.message.content))("readonly", true)("language", ctx_r2.getContentLanguage(item_r4.message.content));
} }
function ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Conditional_20_Conditional_2_For_2_Conditional_7_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 33);
    i0.ɵɵelement(1, "mj-code-editor", 34);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const part_r6 = i0.ɵɵnextContext().$implicit;
    i0.ɵɵadvance();
    i0.ɵɵproperty("value", part_r6.value)("readonly", true)("language", part_r6.language);
} }
function ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Conditional_20_Conditional_2_For_2_Template(rf, ctx) { if (rf & 1) {
    const _r5 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 28)(1, "div", 29);
    i0.ɵɵlistener("click", function ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Conditional_20_Conditional_2_For_2_Template_div_click_1_listener() { const part_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r2 = i0.ɵɵnextContext(6); return i0.ɵɵresetView(ctx_r2.toggleContentPart(part_r6.id)); });
    i0.ɵɵelementStart(2, "div", 30);
    i0.ɵɵelement(3, "i", 31);
    i0.ɵɵtext(4);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "button", 32);
    i0.ɵɵelement(6, "i");
    i0.ɵɵelementEnd()();
    i0.ɵɵtemplate(7, ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Conditional_20_Conditional_2_For_2_Conditional_7_Template, 2, 3, "div", 33);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const part_r6 = ctx.$implicit;
    i0.ɵɵclassProp("collapsed", !part_r6.expanded);
    i0.ɵɵadvance(4);
    i0.ɵɵtextInterpolate1(" ", part_r6.key, " ");
    i0.ɵɵadvance(2);
    i0.ɵɵclassMap(part_r6.expanded ? "fa-solid fa-chevron-up" : "fa-solid fa-chevron-down");
    i0.ɵɵadvance();
    i0.ɵɵconditional(part_r6.expanded ? 7 : -1);
} }
function ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Conditional_20_Conditional_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 25);
    i0.ɵɵrepeaterCreate(1, ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Conditional_20_Conditional_2_For_2_Template, 8, 6, "div", 27, _forTrack0);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r6 = i0.ɵɵnextContext(3);
    const item_r4 = ctx_r6.$implicit;
    const ɵ$index_43_r2 = ctx_r6.$index;
    const ctx_r2 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r2.getContentParts(item_r4.message.content, ɵ$index_43_r2));
} }
function ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Conditional_20_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 23);
    i0.ɵɵtemplate(1, ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Conditional_20_Conditional_1_Template, 2, 3, "div", 24)(2, ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Conditional_20_Conditional_2_Template, 3, 0, "div", 25);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const item_r4 = i0.ɵɵnextContext(2).$implicit;
    const ctx_r2 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r2.isStringContent(item_r4.message.content) ? 1 : 2);
} }
function ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    const _r1 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 11)(1, "div", 12);
    i0.ɵɵlistener("click", function ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Template_div_click_1_listener() { i0.ɵɵrestoreView(_r1); const ɵ$index_43_r2 = i0.ɵɵnextContext().$index; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.toggleMessage(ɵ$index_43_r2)); });
    i0.ɵɵelementStart(2, "div", 13)(3, "span", 14);
    i0.ɵɵtext(4);
    i0.ɵɵelementEnd();
    i0.ɵɵelement(5, "i");
    i0.ɵɵelementStart(6, "span", 15);
    i0.ɵɵtext(7);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(8, "span", 16)(9, "span", 17);
    i0.ɵɵtext(10);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(11, "span", 18);
    i0.ɵɵtext(12, "\u2022");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(13, "span", 17);
    i0.ɵɵtext(14);
    i0.ɵɵelementEnd()()();
    i0.ɵɵelementStart(15, "div", 19)(16, "button", 20);
    i0.ɵɵlistener("click", function ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Template_button_click_16_listener($event) { i0.ɵɵrestoreView(_r1); const item_r4 = i0.ɵɵnextContext().$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.copyMessageContent(item_r4.message.content); return i0.ɵɵresetView($event.stopPropagation()); });
    i0.ɵɵelement(17, "i", 21);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(18, "button", 22);
    i0.ɵɵelement(19, "i");
    i0.ɵɵelementEnd()()();
    i0.ɵɵtemplate(20, ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Conditional_20_Template, 3, 1, "div", 23);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const item_r4 = i0.ɵɵnextContext().$implicit;
    const ctx_r2 = i0.ɵɵnextContext(2);
    i0.ɵɵattribute("data-role", item_r4.message.role);
    i0.ɵɵadvance(4);
    i0.ɵɵtextInterpolate1("#", item_r4.sequenceNumber, "");
    i0.ɵɵadvance();
    i0.ɵɵclassMap("fa-solid " + ctx_r2.getRoleIcon(item_r4.message.role));
    i0.ɵɵstyleProp("color", ctx_r2.getRoleColor(item_r4.message.role));
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(ctx_r2.getRoleLabel(item_r4.message.role));
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate1("", ctx_r2.getContentStats(item_r4.message.content).chars.toLocaleString(), " chars");
    i0.ɵɵadvance(4);
    i0.ɵɵtextInterpolate1("~", ctx_r2.getContentStats(item_r4.message.content).approxTokens.toLocaleString(), " tokens");
    i0.ɵɵadvance(5);
    i0.ɵɵclassMap(item_r4.expanded ? "fa-solid fa-chevron-up" : "fa-solid fa-chevron-down");
    i0.ɵɵadvance();
    i0.ɵɵconditional(item_r4.expanded ? 20 : -1);
} }
function ChatMessageViewerComponent_Conditional_19_For_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵtemplate(0, ChatMessageViewerComponent_Conditional_19_For_1_Conditional_0_Template, 21, 12, "div", 11);
} if (rf & 2) {
    const item_r4 = ctx.$implicit;
    i0.ɵɵconditional(item_r4.visible ? 0 : -1);
} }
function ChatMessageViewerComponent_Conditional_19_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵrepeaterCreate(0, ChatMessageViewerComponent_Conditional_19_For_1_Template, 1, 1, null, null, i0.ɵɵrepeaterTrackByIndex);
} if (rf & 2) {
    const ctx_r2 = i0.ɵɵnextContext();
    i0.ɵɵrepeater(ctx_r2.displayMessages);
} }
export class ChatMessageViewerComponent {
    constructor() {
        this.messages = [];
        this.displayMessages = [];
        this.showSystem = true;
        this.showUser = true;
        this.showAssistant = true;
        // Track expanded state for content parts
        this.contentPartStates = new Map();
    }
    ngOnInit() {
        this.processMessages();
    }
    ngOnChanges() {
        this.processMessages();
    }
    processMessages() {
        this.displayMessages = this.messages.map((msg, index) => ({
            message: msg,
            visible: this.isMessageVisible(msg),
            expanded: true,
            sequenceNumber: index + 1
        }));
    }
    isMessageVisible(message) {
        switch (message.role) {
            case 'system':
                return this.showSystem;
            case 'user':
                return this.showUser;
            case 'assistant':
                return this.showAssistant;
            default:
                return true;
        }
    }
    onFilterChange() {
        this.displayMessages.forEach(dm => {
            dm.visible = this.isMessageVisible(dm.message);
        });
    }
    getRoleIcon(role) {
        switch (role) {
            case 'system':
                return 'fa-cog';
            case 'user':
                return 'fa-user';
            case 'assistant':
                return 'fa-robot';
            default:
                return 'fa-comment';
        }
    }
    getRoleColor(role) {
        switch (role) {
            case 'system':
                return '#2563eb'; // blue
            case 'user':
                return '#059669'; // green
            case 'assistant':
                return '#7c3aed'; // purple
            default:
                return '#6b7280'; // gray
        }
    }
    getRoleLabel(role) {
        return role.charAt(0).toUpperCase() + role.slice(1);
    }
    toggleMessage(index) {
        this.displayMessages[index].expanded = !this.displayMessages[index].expanded;
    }
    getContentString(content) {
        if (typeof content === 'string') {
            return content;
        }
        else {
            const contentAny = content;
            // check to see if we have a text sub-property and if so
            if (contentAny.text?.trim().length > 0) {
                // we should return this 
                return contentAny.text;
            }
            else {
                return JSON.stringify(content, null, 2);
            }
        }
    }
    getContentLanguage(content) {
        const text = this.getContentString(content);
        // Try to detect language based on content
        if (text.trim().startsWith('{') || text.trim().startsWith('[')) {
            return 'json';
        }
        else if (text.includes('```') || text.includes('# ') || text.includes('**')) {
            return 'markdown';
        }
        else if (text.includes('function') || text.includes('const') || text.includes('let')) {
            return 'javascript';
        }
        else if (text.includes('SELECT') || text.includes('FROM') || text.includes('WHERE')) {
            return 'sql';
        }
        return 'markdown'; // default to markdown for formatting
    }
    getContentBlockIcon(type) {
        switch (type) {
            case 'image_url':
                return 'fa-image';
            case 'video_url':
                return 'fa-video';
            case 'audio_url':
                return 'fa-music';
            case 'file_url':
                return 'fa-file';
            default:
                return 'fa-paperclip';
        }
    }
    isStringContent(content) {
        return typeof content === 'string';
    }
    getContentJSON(content) {
        if (typeof content === 'string') {
            return content; // Shouldn't happen but just in case
        }
        // check to see if we have a text sub-property and if so
        // check to see if there are any other sub-properties that have non-empty values or non-empty-arrays/non-empty-object values
        const contentAny = content;
        if (contentAny.text?.trim().length > 0) {
            // check to see if there is just one more property called json, if that is the case, append that with a ```json block to the text
            // and return that
            if (contentAny.json) {
                return contentAny.text + '\n\n```json\n' + JSON.stringify(contentAny.json, null, 2) + '\n```';
            }
            else {
                // now check to see if there are any other sub-properties that have non-empty values or non-empty-arrays/non-empty-object values
                const hasNonEmptySubProps = Object.keys(contentAny).some(key => {
                    if (key === 'text')
                        return false; // skip text property
                    const value = contentAny[key];
                    if (typeof value === 'string' && value.trim().length > 0)
                        return true;
                    if (Array.isArray(value) && value.length > 0)
                        return true;
                    if (typeof value === 'object' && value !== null && Object.keys(value).length > 0)
                        return true;
                    return false;
                });
                if (hasNonEmptySubProps) {
                    // return the full JSON with text included
                    return JSON.stringify(contentAny, null, 2);
                }
                else {
                    // if there are no other non-empty sub-properties, just return the text
                    return contentAny.text;
                }
            }
        }
        else {
            // if there is no text property, just return the full JSON
            return JSON.stringify(content, null, 2);
        }
    }
    getContentStats(content) {
        let totalChars = 0;
        let totalWords = 0;
        if (typeof content === 'string') {
            // For string content, use the content directly
            totalChars = content.length;
            totalWords = content.trim() ? content.trim().split(/\s+/).filter(word => word.length > 0).length : 0;
        }
        else {
            // For non-string content, calculate stats from all non-empty parts
            const contentAny = content;
            Object.keys(contentAny).forEach(key => {
                const value = contentAny[key];
                // Skip empty values
                if (value === null || value === undefined)
                    return;
                let partText;
                if (typeof value === 'string') {
                    partText = value;
                }
                else if (Array.isArray(value) && value.length > 0) {
                    partText = JSON.stringify(value, null, 2);
                }
                else if (typeof value === 'object' && Object.keys(value).length > 0) {
                    partText = JSON.stringify(value, null, 2);
                }
                else {
                    return; // Skip empty arrays/objects
                }
                totalChars += partText.length;
                const partWords = partText.trim().split(/\s+/).filter(word => word.length > 0).length;
                totalWords += partWords;
            });
        }
        const approxTokens = Math.round(totalWords * 1.25); // Average 1.25 tokens per word
        return { chars: totalChars, words: totalWords, approxTokens };
    }
    copyMessageContent(content) {
        const text = this.getContentString(content);
        navigator.clipboard.writeText(text).then(() => {
            console.log('Message content copied to clipboard');
        }).catch(err => {
            console.error('Failed to copy message:', err);
        });
    }
    /**
     * Get content parts for multi-part content display
     * Returns an array of {id, key, value, language, expanded} objects for each content part
     */
    getContentParts(content, messageIndex) {
        if (typeof content === 'string') {
            const id = `msg-${messageIndex}-part-content`;
            return [{
                    id: id,
                    key: 'content',
                    value: content,
                    language: 'markdown',
                    expanded: this.isPartExpanded(id)
                }];
        }
        const contentAny = content;
        const parts = [];
        // Process each key in the content object
        Object.keys(contentAny).forEach((key, index) => {
            const value = contentAny[key];
            // Skip empty values
            if (value === null || value === undefined)
                return;
            if (typeof value === 'string' && value.trim().length === 0)
                return;
            if (Array.isArray(value) && value.length === 0)
                return;
            if (typeof value === 'object' && Object.keys(value).length === 0)
                return;
            // Determine the display value and language
            let displayValue;
            let language;
            if (typeof value === 'string') {
                displayValue = value;
                language = this.detectLanguageForKey(key, value);
            }
            else {
                // For objects/arrays, stringify them
                displayValue = JSON.stringify(value, null, 2);
                language = 'json';
            }
            const id = `msg-${messageIndex}-part-${key}`;
            parts.push({
                id: id,
                key: this.formatKeyLabel(key),
                value: displayValue,
                language: language,
                expanded: this.isPartExpanded(id)
            });
        });
        return parts;
    }
    /**
     * Detect language based on key name and content
     */
    detectLanguageForKey(key, value) {
        // Check key-based hints first
        const keyLower = key.toLowerCase();
        if (keyLower.includes('json') || keyLower.includes('data'))
            return 'json';
        if (keyLower.includes('sql') || keyLower.includes('query'))
            return 'sql';
        if (keyLower.includes('code') || keyLower.includes('script'))
            return 'javascript';
        if (keyLower.includes('markdown') || keyLower.includes('md'))
            return 'markdown';
        if (keyLower.includes('html'))
            return 'html';
        if (keyLower.includes('css'))
            return 'css';
        if (keyLower.includes('xml'))
            return 'xml';
        if (keyLower.includes('yaml') || keyLower.includes('yml'))
            return 'yaml';
        // Fall back to content detection
        return this.getContentLanguage({ text: value });
    }
    /**
     * Format key name for display label
     */
    formatKeyLabel(key) {
        // Convert camelCase or snake_case to Title Case
        return key
            .replace(/([A-Z])/g, ' $1') // Add space before capitals
            .replace(/_/g, ' ') // Replace underscores with spaces
            .replace(/\b\w/g, l => l.toUpperCase()) // Capitalize first letter of each word
            .trim();
    }
    /**
     * Check if content has multiple parts (for non-string content)
     */
    hasMultipleParts(content) {
        if (typeof content === 'string')
            return false;
        const contentAny = content;
        const nonEmptyKeys = Object.keys(contentAny).filter(key => {
            const value = contentAny[key];
            if (value === null || value === undefined)
                return false;
            if (typeof value === 'string' && value.trim().length === 0)
                return false;
            if (Array.isArray(value) && value.length === 0)
                return false;
            if (typeof value === 'object' && Object.keys(value).length === 0)
                return false;
            return true;
        });
        return nonEmptyKeys.length > 1;
    }
    /**
     * Check if a content part is expanded
     */
    isPartExpanded(partId) {
        // Default to expanded for all parts initially
        if (!this.contentPartStates.has(partId)) {
            this.contentPartStates.set(partId, true);
        }
        return this.contentPartStates.get(partId) || false;
    }
    /**
     * Toggle the expanded state of a content part
     */
    toggleContentPart(partId) {
        const currentState = this.contentPartStates.get(partId) || false;
        this.contentPartStates.set(partId, !currentState);
    }
    static { this.ɵfac = function ChatMessageViewerComponent_Factory(t) { return new (t || ChatMessageViewerComponent)(); }; }
    static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ChatMessageViewerComponent, selectors: [["mj-chat-message-viewer"]], inputs: { messages: "messages" }, features: [i0.ɵɵNgOnChangesFeature], decls: 20, vars: 10, consts: [[1, "chat-message-viewer"], [1, "filter-controls"], [1, "filter-checkbox"], ["type", "checkbox", "kendoCheckBox", "", 3, "ngModelChange", "ngModel"], [1, "filter-label"], [1, "fa-solid", "fa-cog"], [1, "fa-solid", "fa-user"], [1, "fa-solid", "fa-robot"], [1, "messages-container"], [1, "empty-state"], [1, "fa-solid", "fa-comments"], [1, "message-card"], [1, "message-header", 3, "click"], [1, "message-role"], [1, "sequence-number"], [1, "role-label"], [1, "content-stats"], [1, "stat-item"], [1, "stat-divider"], [1, "message-actions"], ["type", "button", "title", "Copy message content", 1, "action-button", 3, "click"], [1, "fa-solid", "fa-copy"], ["type", "button", 1, "toggle-button"], [1, "message-content"], [1, "text-content"], [1, "multi-part-content"], [2, "max-height", "600px", "overflow-y", "auto", 3, "value", "readonly", "language"], [1, "content-part", 3, "collapsed"], [1, "content-part"], [1, "content-part-label", 3, "click"], [1, "content-part-label-content"], [1, "fa-solid", "fa-tag"], ["type", "button", 1, "content-part-toggle"], [1, "content-part-editor"], [2, "max-height", "400px", "overflow-y", "auto", 3, "value", "readonly", "language"]], template: function ChatMessageViewerComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "label", 2)(3, "input", 3);
            i0.ɵɵtwoWayListener("ngModelChange", function ChatMessageViewerComponent_Template_input_ngModelChange_3_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.showSystem, $event) || (ctx.showSystem = $event); return $event; });
            i0.ɵɵlistener("ngModelChange", function ChatMessageViewerComponent_Template_input_ngModelChange_3_listener() { return ctx.onFilterChange(); });
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(4, "span", 4);
            i0.ɵɵelement(5, "i", 5);
            i0.ɵɵtext(6, " System ");
            i0.ɵɵelementEnd()();
            i0.ɵɵelementStart(7, "label", 2)(8, "input", 3);
            i0.ɵɵtwoWayListener("ngModelChange", function ChatMessageViewerComponent_Template_input_ngModelChange_8_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.showUser, $event) || (ctx.showUser = $event); return $event; });
            i0.ɵɵlistener("ngModelChange", function ChatMessageViewerComponent_Template_input_ngModelChange_8_listener() { return ctx.onFilterChange(); });
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(9, "span", 4);
            i0.ɵɵelement(10, "i", 6);
            i0.ɵɵtext(11, " User ");
            i0.ɵɵelementEnd()();
            i0.ɵɵelementStart(12, "label", 2)(13, "input", 3);
            i0.ɵɵtwoWayListener("ngModelChange", function ChatMessageViewerComponent_Template_input_ngModelChange_13_listener($event) { i0.ɵɵtwoWayBindingSet(ctx.showAssistant, $event) || (ctx.showAssistant = $event); return $event; });
            i0.ɵɵlistener("ngModelChange", function ChatMessageViewerComponent_Template_input_ngModelChange_13_listener() { return ctx.onFilterChange(); });
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(14, "span", 4);
            i0.ɵɵelement(15, "i", 7);
            i0.ɵɵtext(16, " Assistant ");
            i0.ɵɵelementEnd()()();
            i0.ɵɵelementStart(17, "div", 8);
            i0.ɵɵtemplate(18, ChatMessageViewerComponent_Conditional_18_Template, 4, 0, "div", 9)(19, ChatMessageViewerComponent_Conditional_19_Template, 2, 0);
            i0.ɵɵelementEnd()();
        } if (rf & 2) {
            i0.ɵɵadvance(3);
            i0.ɵɵtwoWayProperty("ngModel", ctx.showSystem);
            i0.ɵɵadvance(2);
            i0.ɵɵstyleProp("color", ctx.getRoleColor("system"));
            i0.ɵɵadvance(3);
            i0.ɵɵtwoWayProperty("ngModel", ctx.showUser);
            i0.ɵɵadvance(2);
            i0.ɵɵstyleProp("color", ctx.getRoleColor("user"));
            i0.ɵɵadvance(3);
            i0.ɵɵtwoWayProperty("ngModel", ctx.showAssistant);
            i0.ɵɵadvance(2);
            i0.ɵɵstyleProp("color", ctx.getRoleColor("assistant"));
            i0.ɵɵadvance(3);
            i0.ɵɵconditional(ctx.displayMessages.length === 0 ? 18 : 19);
        } }, dependencies: [i1.CheckboxControlValueAccessor, i1.NgControlStatus, i1.NgModel, i2.CheckBoxDirective, i3.CodeEditorComponent], styles: [".chat-message-viewer[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    height: 100%;\n    overflow: hidden; \n\n}\n\n\n\n\n.filter-controls[_ngcontent-%COMP%] {\n    display: flex;\n    gap: 1.5rem;\n    align-items: center;\n    padding: 0.75rem;\n    background-color: #f9fafb;\n    border-radius: 8px;\n    border: 1px solid #e5e7eb;\n    margin-bottom: 1rem;\n    flex-shrink: 0; \n\n}\n\n.filter-checkbox[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    cursor: pointer;\n    user-select: none;\n}\n\n.filter-checkbox[_ngcontent-%COMP%]   input[type=\"checkbox\"][_ngcontent-%COMP%] {\n    margin-right: 0.5rem;\n}\n\n.filter-label[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 0.5rem;\n    font-size: 0.875rem;\n    font-weight: 500;\n}\n\n.filter-label[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 1rem;\n}\n\n\n\n.messages-container[_ngcontent-%COMP%] {\n    flex: 1;\n    overflow-y: auto;\n    padding: 0.5rem;\n    padding-bottom: 1rem; \n\n    max-height: 800px;\n}\n\n.empty-state[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    padding: 3rem;\n    color: #9ca3af;\n}\n\n.empty-state[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 3rem;\n    margin-bottom: 1rem;\n}\n\n.empty-state[_ngcontent-%COMP%]   p[_ngcontent-%COMP%] {\n    font-size: 1rem;\n    margin: 0;\n}\n\n\n\n.message-card[_ngcontent-%COMP%] {\n    background: white;\n    border: 1px solid #e5e7eb;\n    border-radius: 8px;\n    margin-bottom: 0.75rem;\n    overflow: hidden;\n    transition: all 0.2s ease;\n}\n\n.message-card[_ngcontent-%COMP%]:hover {\n    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\n}\n\n.message-card[_ngcontent-%COMP%]:last-child {\n    margin-bottom: 2rem; \n\n}\n\n.message-card[data-role=\"system\"][_ngcontent-%COMP%] {\n    border-left: 3px solid #2563eb;\n}\n\n.message-card[data-role=\"user\"][_ngcontent-%COMP%] {\n    border-left: 3px solid #059669;\n}\n\n.message-card[data-role=\"assistant\"][_ngcontent-%COMP%] {\n    border-left: 3px solid #7c3aed;\n}\n\n\n\n.message-header[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 0.75rem 1rem;\n    background-color: #f9fafb;\n    cursor: pointer;\n    user-select: none;\n}\n\n.message-header[_ngcontent-%COMP%]:hover {\n    background-color: #f3f4f6;\n}\n\n.message-role[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 0.5rem;\n}\n\n.sequence-number[_ngcontent-%COMP%] {\n    color: #6c757d;\n    font-weight: 500;\n    font-size: 0.85rem;\n    margin-right: 4px;\n}\n\n.message-role[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 1.125rem;\n}\n\n.content-stats[_ngcontent-%COMP%] {\n    margin-left: auto;\n    display: flex;\n    align-items: center;\n    gap: 6px;\n    color: #6c757d;\n    font-size: 0.8rem;\n    font-weight: 400;\n}\n\n.stat-item[_ngcontent-%COMP%] {\n    white-space: nowrap;\n}\n\n.stat-divider[_ngcontent-%COMP%] {\n    color: #cbd5e0;\n}\n\n.role-label[_ngcontent-%COMP%] {\n    font-weight: 600;\n    font-size: 0.875rem;\n    text-transform: uppercase;\n    letter-spacing: 0.025em;\n}\n\n.message-actions[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n}\n\n.action-button[_ngcontent-%COMP%], \n.toggle-button[_ngcontent-%COMP%] {\n    background: none;\n    border: none;\n    padding: 0.25rem;\n    cursor: pointer;\n    color: #6b7280;\n    transition: color 0.2s ease;\n}\n\n.action-button[_ngcontent-%COMP%]:hover, \n.toggle-button[_ngcontent-%COMP%]:hover {\n    color: #374151;\n}\n\n.action-button[_ngcontent-%COMP%] {\n    padding: 0.25rem 0.5rem;\n}\n\n.action-button[_ngcontent-%COMP%]:hover {\n    color: #2563eb;\n}\n\n\n\n.message-content[_ngcontent-%COMP%] {\n    padding: 1rem;\n}\n\n.content-blocks[_ngcontent-%COMP%] {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 0.5rem;\n    margin-bottom: 1rem;\n}\n\n.content-block-indicator[_ngcontent-%COMP%] {\n    display: inline-flex;\n    align-items: center;\n    gap: 0.375rem;\n    padding: 0.25rem 0.75rem;\n    background-color: #eff6ff;\n    border: 1px solid #dbeafe;\n    border-radius: 9999px;\n    font-size: 0.75rem;\n    color: #1e40af;\n}\n\n.content-block-indicator[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 0.875rem;\n}\n\n\n\n.text-content[_ngcontent-%COMP%], \n.json-content[_ngcontent-%COMP%] {\n    border: 1px solid #e5e7eb;\n    border-radius: 6px;\n    overflow: hidden;\n}\n\n.json-content[_ngcontent-%COMP%] {\n    background-color: #f9fafb;\n}\n\n.text-content[_ngcontent-%COMP%]   mj-code-editor[_ngcontent-%COMP%], \n.json-content[_ngcontent-%COMP%]   mj-code-editor[_ngcontent-%COMP%] {\n    display: block;\n    min-height: 100px;\n}\n\n\n\n.multi-part-content[_ngcontent-%COMP%] {\n    display: flex;\n    flex-direction: column;\n    gap: 1rem;\n}\n\n.content-part[_ngcontent-%COMP%] {\n    border: 1px solid #e5e7eb;\n    border-radius: 6px;\n    overflow: hidden;\n}\n\n.content-part-label[_ngcontent-%COMP%] {\n    background-color: #f3f4f6;\n    padding: 0.5rem 1rem;\n    font-size: 0.875rem;\n    font-weight: 500;\n    color: #374151;\n    border-bottom: 1px solid #e5e7eb;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    cursor: pointer;\n    user-select: none;\n    transition: background-color 0.2s;\n}\n\n.content-part-label[_ngcontent-%COMP%]:hover {\n    background-color: #e5e7eb;\n}\n\n.content-part-label-content[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 0.5rem;\n}\n\n.content-part-label[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n    font-size: 0.75rem;\n    color: #6b7280;\n}\n\n.content-part-toggle[_ngcontent-%COMP%] {\n    background: none;\n    border: none;\n    padding: 0.25rem;\n    cursor: pointer;\n    color: #6b7280;\n    transition: color 0.2s;\n}\n\n.content-part-toggle[_ngcontent-%COMP%]:hover {\n    color: #374151;\n}\n\n.content-part.collapsed[_ngcontent-%COMP%]   .content-part-label[_ngcontent-%COMP%] {\n    border-bottom: none;\n}\n\n.content-part-editor[_ngcontent-%COMP%] {\n    background-color: #f9fafb;\n}\n\n.content-part-editor[_ngcontent-%COMP%]   mj-code-editor[_ngcontent-%COMP%] {\n    display: block;\n    min-height: 80px;\n}\n\n\n\n.chat-message-viewer[_ngcontent-%COMP%]   .cm-editor[_ngcontent-%COMP%] {\n    font-size: 0.875rem;\n}\n\n.chat-message-viewer[_ngcontent-%COMP%]   .cm-editor.cm-focused[_ngcontent-%COMP%] {\n    outline: none;\n}\n\n\n\n@media (max-width: 640px) {\n    .filter-controls[_ngcontent-%COMP%] {\n        flex-wrap: wrap;\n        gap: 0.75rem;\n    }\n    \n    .filter-checkbox[_ngcontent-%COMP%] {\n        min-width: calc(50% - 0.375rem);\n    }\n}"] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ChatMessageViewerComponent, [{
        type: Component,
        args: [{ selector: 'mj-chat-message-viewer', template: "<div class=\"chat-message-viewer\">\n    <!-- Filter Controls -->\n    <div class=\"filter-controls\">\n        <label class=\"filter-checkbox\">\n            <input type=\"checkbox\" \n                   [(ngModel)]=\"showSystem\" \n                   (ngModelChange)=\"onFilterChange()\"\n                   kendoCheckBox />\n            <span class=\"filter-label\">\n                <i class=\"fa-solid fa-cog\" [style.color]=\"getRoleColor('system')\"></i>\n                System\n            </span>\n        </label>\n        \n        <label class=\"filter-checkbox\">\n            <input type=\"checkbox\" \n                   [(ngModel)]=\"showUser\" \n                   (ngModelChange)=\"onFilterChange()\"\n                   kendoCheckBox />\n            <span class=\"filter-label\">\n                <i class=\"fa-solid fa-user\" [style.color]=\"getRoleColor('user')\"></i>\n                User\n            </span>\n        </label>\n        \n        <label class=\"filter-checkbox\">\n            <input type=\"checkbox\" \n                   [(ngModel)]=\"showAssistant\" \n                   (ngModelChange)=\"onFilterChange()\"\n                   kendoCheckBox />\n            <span class=\"filter-label\">\n                <i class=\"fa-solid fa-robot\" [style.color]=\"getRoleColor('assistant')\"></i>\n                Assistant\n            </span>\n        </label>\n    </div>\n    \n    <!-- Messages List -->\n    <div class=\"messages-container\">\n        @if (displayMessages.length === 0) {\n            <div class=\"empty-state\">\n                <i class=\"fa-solid fa-comments\"></i>\n                <p>No messages to display</p>\n            </div>\n        } @else {\n            @for (item of displayMessages; track $index; let i = $index) {\n                @if (item.visible) {\n                    <div class=\"message-card\" [attr.data-role]=\"item.message.role\">\n                        <!-- Message Header -->\n                        <div class=\"message-header\" (click)=\"toggleMessage(i)\">\n                            <div class=\"message-role\">\n                                <span class=\"sequence-number\">#{{ item.sequenceNumber }}</span>\n                                <i [class]=\"'fa-solid ' + getRoleIcon(item.message.role)\" \n                                   [style.color]=\"getRoleColor(item.message.role)\"></i>\n                                <span class=\"role-label\">{{ getRoleLabel(item.message.role) }}</span>\n                                <span class=\"content-stats\">\n                                    <span class=\"stat-item\">{{ getContentStats(item.message.content).chars.toLocaleString() }} chars</span>\n                                    <span class=\"stat-divider\">\u2022</span>\n                                    <span class=\"stat-item\">~{{ getContentStats(item.message.content).approxTokens.toLocaleString() }} tokens</span>\n                                </span>\n                            </div>\n                            <div class=\"message-actions\">\n                                <button class=\"action-button\" type=\"button\" \n                                        (click)=\"copyMessageContent(item.message.content); $event.stopPropagation()\"\n                                        title=\"Copy message content\">\n                                    <i class=\"fa-solid fa-copy\"></i>\n                                </button>\n                                <button class=\"toggle-button\" type=\"button\">\n                                    <i [class]=\"item.expanded ? 'fa-solid fa-chevron-up' : 'fa-solid fa-chevron-down'\"></i>\n                                </button>\n                            </div>\n                        </div>\n                        \n                        <!-- Message Content -->\n                        @if (item.expanded) {\n                            <div class=\"message-content\">\n                                <!-- Main content -->\n                                @if (isStringContent(item.message.content)) {\n                                    <div class=\"text-content\">\n                                        <mj-code-editor \n                                            [value]=\"getContentString(item.message.content)\"\n                                            [readonly]=\"true\"\n                                            [language]=\"getContentLanguage(item.message.content)\"\n                                            style=\"max-height: 600px; overflow-y: auto;\">\n                                        </mj-code-editor>\n                                    </div>\n                                } @else {\n                                    <!-- Non-string content with multiple parts -->\n                                    <div class=\"multi-part-content\">\n                                        @for (part of getContentParts(item.message.content, i); track part.id) {\n                                            <div class=\"content-part\" [class.collapsed]=\"!part.expanded\">\n                                                <div class=\"content-part-label\" (click)=\"toggleContentPart(part.id)\">\n                                                    <div class=\"content-part-label-content\">\n                                                        <i class=\"fa-solid fa-tag\"></i>\n                                                        {{ part.key }}\n                                                    </div>\n                                                    <button class=\"content-part-toggle\" type=\"button\">\n                                                        <i [class]=\"part.expanded ? 'fa-solid fa-chevron-up' : 'fa-solid fa-chevron-down'\"></i>\n                                                    </button>\n                                                </div>\n                                                @if (part.expanded) {\n                                                    <div class=\"content-part-editor\">\n                                                        <mj-code-editor \n                                                            [value]=\"part.value\"\n                                                            [readonly]=\"true\"\n                                                            [language]=\"part.language\"\n                                                            style=\"max-height: 400px; overflow-y: auto;\">\n                                                        </mj-code-editor>\n                                                    </div>\n                                                }\n                                            </div>\n                                        }\n                                    </div>\n                                }\n                            </div>\n                        }\n                    </div>\n                }\n            }\n        }\n    </div>\n</div>", styles: [".chat-message-viewer {\n    display: flex;\n    flex-direction: column;\n    height: 100%;\n    overflow: hidden; /* Prevent overflow from the parent */\n}\n\n\n/* Filter Controls */\n.filter-controls {\n    display: flex;\n    gap: 1.5rem;\n    align-items: center;\n    padding: 0.75rem;\n    background-color: #f9fafb;\n    border-radius: 8px;\n    border: 1px solid #e5e7eb;\n    margin-bottom: 1rem;\n    flex-shrink: 0; /* Prevent filter from shrinking */\n}\n\n.filter-checkbox {\n    display: flex;\n    align-items: center;\n    cursor: pointer;\n    user-select: none;\n}\n\n.filter-checkbox input[type=\"checkbox\"] {\n    margin-right: 0.5rem;\n}\n\n.filter-label {\n    display: flex;\n    align-items: center;\n    gap: 0.5rem;\n    font-size: 0.875rem;\n    font-weight: 500;\n}\n\n.filter-label i {\n    font-size: 1rem;\n}\n\n/* Messages Container */\n.messages-container {\n    flex: 1;\n    overflow-y: auto;\n    padding: 0.5rem;\n    padding-bottom: 1rem; /* Small padding at bottom */\n    max-height: 800px;\n}\n\n.empty-state {\n    display: flex;\n    flex-direction: column;\n    align-items: center;\n    justify-content: center;\n    padding: 3rem;\n    color: #9ca3af;\n}\n\n.empty-state i {\n    font-size: 3rem;\n    margin-bottom: 1rem;\n}\n\n.empty-state p {\n    font-size: 1rem;\n    margin: 0;\n}\n\n/* Message Card */\n.message-card {\n    background: white;\n    border: 1px solid #e5e7eb;\n    border-radius: 8px;\n    margin-bottom: 0.75rem;\n    overflow: hidden;\n    transition: all 0.2s ease;\n}\n\n.message-card:hover {\n    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);\n}\n\n.message-card:last-child {\n    margin-bottom: 2rem; /* Extra margin on last card to ensure it's fully visible */\n}\n\n.message-card[data-role=\"system\"] {\n    border-left: 3px solid #2563eb;\n}\n\n.message-card[data-role=\"user\"] {\n    border-left: 3px solid #059669;\n}\n\n.message-card[data-role=\"assistant\"] {\n    border-left: 3px solid #7c3aed;\n}\n\n/* Message Header */\n.message-header {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    padding: 0.75rem 1rem;\n    background-color: #f9fafb;\n    cursor: pointer;\n    user-select: none;\n}\n\n.message-header:hover {\n    background-color: #f3f4f6;\n}\n\n.message-role {\n    display: flex;\n    align-items: center;\n    gap: 0.5rem;\n}\n\n.sequence-number {\n    color: #6c757d;\n    font-weight: 500;\n    font-size: 0.85rem;\n    margin-right: 4px;\n}\n\n.message-role i {\n    font-size: 1.125rem;\n}\n\n.content-stats {\n    margin-left: auto;\n    display: flex;\n    align-items: center;\n    gap: 6px;\n    color: #6c757d;\n    font-size: 0.8rem;\n    font-weight: 400;\n}\n\n.stat-item {\n    white-space: nowrap;\n}\n\n.stat-divider {\n    color: #cbd5e0;\n}\n\n.role-label {\n    font-weight: 600;\n    font-size: 0.875rem;\n    text-transform: uppercase;\n    letter-spacing: 0.025em;\n}\n\n.message-actions {\n    display: flex;\n    align-items: center;\n    gap: 8px;\n}\n\n.action-button,\n.toggle-button {\n    background: none;\n    border: none;\n    padding: 0.25rem;\n    cursor: pointer;\n    color: #6b7280;\n    transition: color 0.2s ease;\n}\n\n.action-button:hover,\n.toggle-button:hover {\n    color: #374151;\n}\n\n.action-button {\n    padding: 0.25rem 0.5rem;\n}\n\n.action-button:hover {\n    color: #2563eb;\n}\n\n/* Message Content */\n.message-content {\n    padding: 1rem;\n}\n\n.content-blocks {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 0.5rem;\n    margin-bottom: 1rem;\n}\n\n.content-block-indicator {\n    display: inline-flex;\n    align-items: center;\n    gap: 0.375rem;\n    padding: 0.25rem 0.75rem;\n    background-color: #eff6ff;\n    border: 1px solid #dbeafe;\n    border-radius: 9999px;\n    font-size: 0.75rem;\n    color: #1e40af;\n}\n\n.content-block-indicator i {\n    font-size: 0.875rem;\n}\n\n/* Text Content */\n.text-content,\n.json-content {\n    border: 1px solid #e5e7eb;\n    border-radius: 6px;\n    overflow: hidden;\n}\n\n.json-content {\n    background-color: #f9fafb;\n}\n\n.text-content mj-code-editor,\n.json-content mj-code-editor {\n    display: block;\n    min-height: 100px;\n}\n\n/* Multi-part Content */\n.multi-part-content {\n    display: flex;\n    flex-direction: column;\n    gap: 1rem;\n}\n\n.content-part {\n    border: 1px solid #e5e7eb;\n    border-radius: 6px;\n    overflow: hidden;\n}\n\n.content-part-label {\n    background-color: #f3f4f6;\n    padding: 0.5rem 1rem;\n    font-size: 0.875rem;\n    font-weight: 500;\n    color: #374151;\n    border-bottom: 1px solid #e5e7eb;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    cursor: pointer;\n    user-select: none;\n    transition: background-color 0.2s;\n}\n\n.content-part-label:hover {\n    background-color: #e5e7eb;\n}\n\n.content-part-label-content {\n    display: flex;\n    align-items: center;\n    gap: 0.5rem;\n}\n\n.content-part-label i {\n    font-size: 0.75rem;\n    color: #6b7280;\n}\n\n.content-part-toggle {\n    background: none;\n    border: none;\n    padding: 0.25rem;\n    cursor: pointer;\n    color: #6b7280;\n    transition: color 0.2s;\n}\n\n.content-part-toggle:hover {\n    color: #374151;\n}\n\n.content-part.collapsed .content-part-label {\n    border-bottom: none;\n}\n\n.content-part-editor {\n    background-color: #f9fafb;\n}\n\n.content-part-editor mj-code-editor {\n    display: block;\n    min-height: 80px;\n}\n\n/* CodeMirror Overrides for this component */\n.chat-message-viewer .cm-editor {\n    font-size: 0.875rem;\n}\n\n.chat-message-viewer .cm-editor.cm-focused {\n    outline: none;\n}\n\n/* Responsive adjustments */\n@media (max-width: 640px) {\n    .filter-controls {\n        flex-wrap: wrap;\n        gap: 0.75rem;\n    }\n    \n    .filter-checkbox {\n        min-width: calc(50% - 0.375rem);\n    }\n}"] }]
    }], null, { messages: [{
            type: Input
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ChatMessageViewerComponent, { className: "ChatMessageViewerComponent", filePath: "src/lib/custom/AIPromptRuns/chat-message-viewer.component.ts", lineNumber: 16 }); })();
//# sourceMappingURL=chat-message-viewer.component.js.map