/**
 * @fileoverview Realtime Voice — sessions management grid.
 *
 * Every long-lived `MJ: AI Agent Sessions` row across the platform — live
 * calls, idle holds, and closed history — with the channels each session
 * opened and the agent runs it delegated. KPI strip up top, a filter bar
 * (search · status · target agent · user · host), the data grid (Agent →
 * Target, status pills incl. the persisted close cause — explicit / janitor /
 * shutdown / error / unknown-legacy, channel icons, run count, tokens / cost,
 * started, duration, host instance), and row drill-in to the session record.
 */
import { Component, Input, ChangeDetectorRef, inject } from '@angular/core';
import { CompositeKey } from '@memberjunction/core';
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
import { SharedService } from '@memberjunction/ng-shared';
import { LoadRealtimeSessionsDataset, FormatSessionDuration, FormatTokenCount, FormatSessionCost, FormatSessionStart, ChannelIconClass, BuildSessionStatusDisplay } from './realtime-session-data';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@memberjunction/ng-shared-generic";
import * as i3 from "../../widgets/kpi-card.component";
import * as i4 from "@memberjunction/ng-ui-components";
const _forTrack0 = ($index, $item) => $item.title;
const _forTrack1 = ($index, $item) => $item.Value;
const _forTrack2 = ($index, $item) => $item.ID;
const _forTrack3 = ($index, $item) => $item.Name;
function AnalyticsRealtimeSessionsComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 0);
    i0.ɵɵelement(1, "mj-loading", 1);
    i0.ɵɵelementEnd();
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_For_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "app-kpi-card", 3);
} if (rf & 2) {
    const kpi_r2 = ctx.$implicit;
    i0.ɵɵproperty("data", kpi_r2);
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_For_20_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "option", 13);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const opt_r4 = ctx.$implicit;
    i0.ɵɵproperty("value", opt_r4.Value);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(opt_r4.Label);
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_For_25_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "option", 13);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const opt_r5 = ctx.$implicit;
    i0.ɵɵproperty("value", opt_r5.Value);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(opt_r5.Label);
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_For_30_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "option", 13);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const opt_r6 = ctx.$implicit;
    i0.ɵɵproperty("value", opt_r6.Value);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(opt_r6.Label);
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_Conditional_62_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "tr")(1, "td", 25);
    i0.ɵɵtext(2, "No sessions match the current filters");
    i0.ɵɵelementEnd()();
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Conditional_7_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 30);
    i0.ɵɵelement(1, "i", 45);
    i0.ɵɵtext(2, " resumed ");
    i0.ɵɵelementEnd();
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Conditional_12_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "span", 33);
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Conditional_13_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i");
} if (rf & 2) {
    const row_r8 = i0.ɵɵnextContext().$implicit;
    i0.ɵɵclassMap(row_r8.StatusIcon);
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_For_18_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 46);
} if (rf & 2) {
    const chan_r9 = ctx.$implicit;
    i0.ɵɵclassMap(chan_r9.Icon);
    i0.ɵɵproperty("title", chan_r9.Name);
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Conditional_19_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 37);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const row_r8 = i0.ɵɵnextContext().$implicit;
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(row_r8.ChannelCount);
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Template(rf, ctx) { if (rf & 1) {
    const _r7 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "tr", 26);
    i0.ɵɵlistener("click", function AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Template_tr_click_0_listener() { const row_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.OpenSession(row_r8.ID)); });
    i0.ɵɵelementStart(1, "td")(2, "div", 27);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "div", 28);
    i0.ɵɵelement(5, "i", 29);
    i0.ɵɵtext(6);
    i0.ɵɵconditionalCreate(7, AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Conditional_7_Template, 3, 0, "span", 30);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(8, "td", 31);
    i0.ɵɵtext(9);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(10, "td")(11, "span", 32);
    i0.ɵɵconditionalCreate(12, AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Conditional_12_Template, 1, 0, "span", 33)(13, AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Conditional_13_Template, 1, 2, "i", 34);
    i0.ɵɵtext(14);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(15, "td")(16, "span", 35);
    i0.ɵɵrepeaterCreate(17, AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_For_18_Template, 1, 3, "i", 36, _forTrack3);
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(19, AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Conditional_19_Template, 2, 1, "span", 37);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(20, "td", 38);
    i0.ɵɵtext(21);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(22, "td", 39);
    i0.ɵɵtext(23);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(24, "td", 39);
    i0.ɵɵtext(25);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(26, "td", 40);
    i0.ɵɵtext(27);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(28, "td", 39);
    i0.ɵɵtext(29);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(30, "td", 41);
    i0.ɵɵtext(31);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(32, "td", 42)(33, "button", 43);
    i0.ɵɵlistener("click", function AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Template_button_click_33_listener($event) { const row_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r2 = i0.ɵɵnextContext(2); ctx_r2.OpenSession(row_r8.ID); return i0.ɵɵresetView($event.stopPropagation()); });
    i0.ɵɵelement(34, "i", 44);
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const row_r8 = ctx.$implicit;
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(row_r8.Agent);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate1(" ", row_r8.Target, " ");
    i0.ɵɵadvance();
    i0.ɵɵconditional(row_r8.IsResumed ? 7 : -1);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(row_r8.User);
    i0.ɵɵadvance(2);
    i0.ɵɵclassMap(row_r8.StatusClass);
    i0.ɵɵproperty("title", row_r8.StatusTitle);
    i0.ɵɵadvance();
    i0.ɵɵconditional(row_r8.Status === "Active" ? 12 : row_r8.StatusIcon ? 13 : -1);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1(" ", row_r8.StatusLabel, " ");
    i0.ɵɵadvance(3);
    i0.ɵɵrepeater(row_r8.ChannelIcons);
    i0.ɵɵadvance(2);
    i0.ɵɵconditional(row_r8.ChannelCount > 0 ? 19 : -1);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(row_r8.Runs);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(row_r8.Tokens);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(row_r8.Cost);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(row_r8.Started);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(row_r8.Duration);
    i0.ɵɵadvance();
    i0.ɵɵproperty("title", row_r8.Host);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(row_r8.Host);
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_Conditional_68_Template(rf, ctx) { if (rf & 1) {
    const _r10 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 24)(1, "button", 47);
    i0.ɵɵlistener("click", function AnalyticsRealtimeSessionsComponent_Conditional_1_Conditional_68_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.PrevPage()); });
    i0.ɵɵelement(2, "i", 48);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "span", 49);
    i0.ɵɵtext(4);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "button", 47);
    i0.ɵɵlistener("click", function AnalyticsRealtimeSessionsComponent_Conditional_1_Conditional_68_Template_button_click_5_listener() { i0.ɵɵrestoreView(_r10); const ctx_r2 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r2.NextPage()); });
    i0.ɵɵelement(6, "i", 50);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r2 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵproperty("disabled", ctx_r2.PageIndex === 0);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate2("Page ", ctx_r2.PageIndex + 1, " of ", ctx_r2.PageCount);
    i0.ɵɵadvance();
    i0.ɵɵproperty("disabled", ctx_r2.PageIndex >= ctx_r2.PageCount - 1);
} }
function AnalyticsRealtimeSessionsComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    const _r1 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 2);
    i0.ɵɵrepeaterCreate(1, AnalyticsRealtimeSessionsComponent_Conditional_1_For_2_Template, 1, 1, "app-kpi-card", 3, _forTrack0);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 4)(4, "div", 5);
    i0.ɵɵelement(5, "i", 6);
    i0.ɵɵelementStart(6, "input", 7);
    i0.ɵɵlistener("input", function AnalyticsRealtimeSessionsComponent_Conditional_1_Template_input_input_6_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnSearchChanged($event)); });
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(7, "select", 8);
    i0.ɵɵlistener("change", function AnalyticsRealtimeSessionsComponent_Conditional_1_Template_select_change_7_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnStatusFilterChanged($event)); });
    i0.ɵɵelementStart(8, "option", 9);
    i0.ɵɵtext(9, "Status: All");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(10, "option", 10);
    i0.ɵɵtext(11, "Active");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(12, "option", 11);
    i0.ɵɵtext(13, "Idle");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(14, "option", 12);
    i0.ɵɵtext(15, "Closed");
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(16, "select", 8);
    i0.ɵɵlistener("change", function AnalyticsRealtimeSessionsComponent_Conditional_1_Template_select_change_16_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnTargetFilterChanged($event)); });
    i0.ɵɵelementStart(17, "option", 9);
    i0.ɵɵtext(18, "Target: All");
    i0.ɵɵelementEnd();
    i0.ɵɵrepeaterCreate(19, AnalyticsRealtimeSessionsComponent_Conditional_1_For_20_Template, 2, 2, "option", 13, _forTrack1);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(21, "select", 8);
    i0.ɵɵlistener("change", function AnalyticsRealtimeSessionsComponent_Conditional_1_Template_select_change_21_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnUserFilterChanged($event)); });
    i0.ɵɵelementStart(22, "option", 9);
    i0.ɵɵtext(23, "User: All");
    i0.ɵɵelementEnd();
    i0.ɵɵrepeaterCreate(24, AnalyticsRealtimeSessionsComponent_Conditional_1_For_25_Template, 2, 2, "option", 13, _forTrack1);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(26, "select", 8);
    i0.ɵɵlistener("change", function AnalyticsRealtimeSessionsComponent_Conditional_1_Template_select_change_26_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnHostFilterChanged($event)); });
    i0.ɵɵelementStart(27, "option", 9);
    i0.ɵɵtext(28, "Host: All");
    i0.ɵɵelementEnd();
    i0.ɵɵrepeaterCreate(29, AnalyticsRealtimeSessionsComponent_Conditional_1_For_30_Template, 2, 2, "option", 13, _forTrack1);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(31, "span", 14);
    i0.ɵɵtext(32);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(33, "button", 15);
    i0.ɵɵlistener("click", function AnalyticsRealtimeSessionsComponent_Conditional_1_Template_button_click_33_listener() { i0.ɵɵrestoreView(_r1); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.LoadData()); });
    i0.ɵɵelement(34, "i", 16);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(35, "div", 17)(36, "div", 18)(37, "table", 19)(38, "thead")(39, "tr")(40, "th");
    i0.ɵɵtext(41, "Agent / Target");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(42, "th");
    i0.ɵɵtext(43, "User");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(44, "th");
    i0.ɵɵtext(45, "Status");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(46, "th");
    i0.ɵɵtext(47, "Channels");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(48, "th", 20);
    i0.ɵɵtext(49, "Runs");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(50, "th", 20);
    i0.ɵɵtext(51, "Tokens");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(52, "th", 20);
    i0.ɵɵtext(53, "Cost");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(54, "th");
    i0.ɵɵtext(55, "Started");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(56, "th", 20);
    i0.ɵɵtext(57, "Duration");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(58, "th");
    i0.ɵɵtext(59, "Host instance");
    i0.ɵɵelementEnd();
    i0.ɵɵelement(60, "th");
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(61, "tbody");
    i0.ɵɵconditionalCreate(62, AnalyticsRealtimeSessionsComponent_Conditional_1_Conditional_62_Template, 3, 0, "tr");
    i0.ɵɵrepeaterCreate(63, AnalyticsRealtimeSessionsComponent_Conditional_1_For_64_Template, 35, 17, "tr", 21, _forTrack2);
    i0.ɵɵelementEnd()()()();
    i0.ɵɵelementStart(65, "div", 22)(66, "span", 23);
    i0.ɵɵtext(67);
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(68, AnalyticsRealtimeSessionsComponent_Conditional_1_Conditional_68_Template, 7, 4, "div", 24);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r2 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r2.KPICards);
    i0.ɵɵadvance(5);
    i0.ɵɵproperty("value", ctx_r2.SearchTerm);
    i0.ɵɵadvance();
    i0.ɵɵproperty("value", ctx_r2.StatusFilter);
    i0.ɵɵadvance(9);
    i0.ɵɵproperty("value", ctx_r2.TargetFilter);
    i0.ɵɵadvance(3);
    i0.ɵɵrepeater(ctx_r2.TargetOptions);
    i0.ɵɵadvance(2);
    i0.ɵɵproperty("value", ctx_r2.UserFilter);
    i0.ɵɵadvance(3);
    i0.ɵɵrepeater(ctx_r2.UserOptions);
    i0.ɵɵadvance(2);
    i0.ɵɵproperty("value", ctx_r2.HostFilter);
    i0.ɵɵadvance(3);
    i0.ɵɵrepeater(ctx_r2.HostOptions);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate2("", ctx_r2.FilteredRows.length, " results \u00B7 ", ctx_r2.LiveCount, " live");
    i0.ɵɵadvance(30);
    i0.ɵɵconditional(ctx_r2.PagedRows.length === 0 ? 62 : -1);
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r2.PagedRows);
    i0.ɵɵadvance(4);
    i0.ɵɵtextInterpolate5(" Showing ", ctx_r2.PagedRows.length, " of ", ctx_r2.FilteredRows.length, " \u00B7 ", ctx_r2.LiveCount, " live \u00B7 ", ctx_r2.IdleCount, " idle \u00B7 ", ctx_r2.ClosedCount, " closed ");
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r2.PageCount > 1 ? 68 : -1);
} }
const PAGE_SIZE = 25;
export class AnalyticsRealtimeSessionsComponent extends BaseAngularComponent {
    _timeRange = '7d';
    set TimeRange(value) {
        const prev = this._timeRange;
        this._timeRange = value;
        if (prev !== value && this.initialized)
            this.LoadData();
    }
    get TimeRange() { return this._timeRange; }
    initialized = false;
    cdr = inject(ChangeDetectorRef);
    dataset = null;
    allRows = [];
    IsLoading = false;
    KPICards = [];
    FilteredRows = [];
    PagedRows = [];
    TargetOptions = [];
    UserOptions = [];
    HostOptions = [];
    SearchTerm = '';
    StatusFilter = '';
    TargetFilter = '';
    UserFilter = '';
    HostFilter = '';
    PageIndex = 0;
    get LiveCount() {
        return this.FilteredRows.filter(r => r.Status === 'Active').length;
    }
    get IdleCount() {
        return this.FilteredRows.filter(r => r.Status === 'Idle').length;
    }
    get ClosedCount() {
        return this.FilteredRows.filter(r => r.Status === 'Closed').length;
    }
    get PageCount() {
        return Math.max(1, Math.ceil(this.FilteredRows.length / PAGE_SIZE));
    }
    ngOnInit() {
        this.initialized = true;
        this.LoadData();
    }
    // ── Data loading ──
    /** Reloads everything for the current time range. */
    async LoadData() {
        this.IsLoading = true;
        this.cdr.detectChanges();
        try {
            this.dataset = await LoadRealtimeSessionsDataset(this.ProviderToUse, this.TimeRange);
            this.buildRows();
            this.buildKPICards();
            this.buildFilterOptions();
            this.applyFilters();
        }
        catch (e) {
            console.error('Realtime sessions load error:', e);
        }
        finally {
            this.IsLoading = false;
            this.cdr.detectChanges();
        }
    }
    // ── Drill-in ──
    /** Opens the AIAgentSession record via the shared Explorer record-open path. */
    OpenSession(sessionId) {
        const key = new CompositeKey();
        key.LoadFromSingleKeyValuePair('ID', sessionId);
        SharedService.Instance.OpenEntityRecord('MJ: AI Agent Sessions', key);
    }
    // ── Filter handlers ──
    OnSearchChanged(event) {
        this.SearchTerm = event.target.value;
        this.applyFilters();
    }
    OnStatusFilterChanged(event) {
        this.StatusFilter = event.target.value;
        this.applyFilters();
    }
    OnTargetFilterChanged(event) {
        this.TargetFilter = event.target.value;
        this.applyFilters();
    }
    OnUserFilterChanged(event) {
        this.UserFilter = event.target.value;
        this.applyFilters();
    }
    OnHostFilterChanged(event) {
        this.HostFilter = event.target.value;
        this.applyFilters();
    }
    PrevPage() {
        if (this.PageIndex > 0) {
            this.PageIndex--;
            this.applyPaging();
        }
    }
    NextPage() {
        if (this.PageIndex < this.PageCount - 1) {
            this.PageIndex++;
            this.applyPaging();
        }
    }
    // ── Builders ──
    buildRows() {
        const sessions = this.dataset?.Sessions ?? [];
        this.allRows = [...sessions]
            .sort((a, b) => b.StartedAt.getTime() - a.StartedAt.getTime())
            .map(s => this.toGridRow(s));
    }
    toGridRow(s) {
        const target = s.TargetAgentName ?? (s.TargetAgentID ? 'Unknown agent' : '—');
        const host = s.Record.HostInstanceID ?? '—';
        const user = s.Record.User;
        const agent = s.Record.Agent ?? 'Unknown';
        const statusDisplay = BuildSessionStatusDisplay(s.Record.Status, s.CloseReason);
        return {
            ID: s.Record.ID,
            Agent: agent,
            Target: target,
            User: user,
            Status: s.Record.Status,
            StatusLabel: statusDisplay.Label,
            StatusClass: 'status-pill status-' + s.Record.Status.toLowerCase(),
            StatusTitle: statusDisplay.Title,
            StatusIcon: statusDisplay.Icon,
            IsResumed: s.IsResumed,
            ChannelIcons: s.ChannelNames.map(name => ({ Icon: ChannelIconClass(name), Name: name })),
            ChannelCount: s.ChannelNames.length,
            Runs: s.DelegatedRunCount,
            Tokens: FormatTokenCount(s.TotalTokens),
            Cost: FormatSessionCost(s.TotalCost),
            Started: FormatSessionStart(s.StartedAt),
            StartedAt: s.StartedAt,
            Duration: FormatSessionDuration(s.DurationMs),
            Host: host,
            SearchText: [agent, target, user, host, s.Record.ID, s.Record.ConversationID ?? '']
                .join(' ').toLowerCase()
        };
    }
    buildKPICards() {
        const sessions = this.dataset?.Sessions ?? [];
        const all = this.dataset?.AllSessions ?? [];
        const activeCount = sessions.filter(s => s.Record.Status === 'Active').length;
        const idleCount = sessions.filter(s => s.Record.Status === 'Idle').length;
        const now = new Date();
        const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
        const startOfYesterday = new Date(startOfToday.getTime() - 86_400_000);
        const todaySessions = all.filter(s => s.StartedAt >= startOfToday);
        const yesterdaySessions = all.filter(s => s.StartedAt >= startOfYesterday && s.StartedAt < startOfToday);
        const todayCost = todaySessions.reduce((a, s) => a + s.TotalCost, 0);
        const delegatedTotal = sessions.reduce((a, s) => a + s.DelegatedRunCount, 0);
        const trendPct = yesterdaySessions.length > 0
            ? Math.round(((todaySessions.length - yesterdaySessions.length) / yesterdaySessions.length) * 100)
            : 0;
        this.KPICards = [
            {
                title: 'Active now',
                value: activeCount,
                subtitle: 'live duplex sessions',
                icon: 'fa-tower-broadcast',
                color: 'success'
            },
            {
                title: 'Idle (holding)',
                value: idleCount,
                subtitle: 'past idle threshold',
                icon: 'fa-pause',
                color: 'warning'
            },
            {
                title: 'Sessions today',
                value: todaySessions.length,
                icon: 'fa-clock',
                color: 'primary',
                trend: yesterdaySessions.length > 0 ? {
                    direction: trendPct > 0 ? 'up' : trendPct < 0 ? 'down' : 'stable',
                    percentage: Math.abs(trendPct),
                    period: 'vs yesterday'
                } : undefined,
                subtitle: yesterdaySessions.length > 0 ? undefined : 'no sessions yesterday'
            },
            {
                title: `Delegated runs (${this.TimeRange})`,
                value: delegatedTotal,
                subtitle: 'agent runs via AgentSessionID',
                icon: 'fa-diagram-project',
                color: 'info'
            },
            {
                title: 'Cost today',
                value: FormatSessionCost(todayCost),
                subtitle: 'co-agent + delegated',
                icon: 'fa-coins',
                color: 'danger'
            }
        ];
    }
    buildFilterOptions() {
        const targets = new Map();
        const users = new Map();
        const hosts = new Set();
        for (const row of this.allRows) {
            if (row.Target && row.Target !== '—')
                targets.set(row.Target, row.Target);
            if (row.User)
                users.set(row.User, row.User);
            if (row.Host && row.Host !== '—')
                hosts.add(row.Host);
        }
        const toOptions = (values) => Array.from(values).sort((a, b) => a.localeCompare(b)).map(v => ({ Value: v, Label: v }));
        this.TargetOptions = toOptions(targets.keys());
        this.UserOptions = toOptions(users.keys());
        this.HostOptions = toOptions(hosts);
    }
    applyFilters() {
        const search = this.SearchTerm.trim().toLowerCase();
        this.FilteredRows = this.allRows.filter(row => {
            if (this.StatusFilter && row.Status !== this.StatusFilter)
                return false;
            if (this.TargetFilter && row.Target !== this.TargetFilter)
                return false;
            if (this.UserFilter && row.User !== this.UserFilter)
                return false;
            if (this.HostFilter && row.Host !== this.HostFilter)
                return false;
            if (search && !row.SearchText.includes(search))
                return false;
            return true;
        });
        this.PageIndex = 0;
        this.applyPaging();
    }
    applyPaging() {
        const start = this.PageIndex * PAGE_SIZE;
        this.PagedRows = this.FilteredRows.slice(start, start + PAGE_SIZE);
        this.cdr.detectChanges();
    }
    static ɵfac = /*@__PURE__*/ (() => { let ɵAnalyticsRealtimeSessionsComponent_BaseFactory; return function AnalyticsRealtimeSessionsComponent_Factory(__ngFactoryType__) { return (ɵAnalyticsRealtimeSessionsComponent_BaseFactory || (ɵAnalyticsRealtimeSessionsComponent_BaseFactory = i0.ɵɵgetInheritedFactory(AnalyticsRealtimeSessionsComponent)))(__ngFactoryType__ || AnalyticsRealtimeSessionsComponent); }; })();
    static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AnalyticsRealtimeSessionsComponent, selectors: [["app-analytics-realtime-sessions"]], inputs: { TimeRange: "TimeRange" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "loading-container"], ["text", "Loading agent sessions..."], [1, "kpi-grid"], [3, "data"], [1, "filterbar"], [1, "search-input"], [1, "fa-solid", "fa-magnifying-glass"], ["type", "text", "placeholder", "Search sessions, users, hosts\u2026", 3, "input", "value"], [1, "filter-select", 3, "change", "value"], ["value", ""], ["value", "Active"], ["value", "Idle"], ["value", "Closed"], [3, "value"], [1, "result-pill"], ["mjButton", "", "variant", "secondary", "size", "sm", "title", "Refresh", 3, "click"], [1, "fa-solid", "fa-rotate"], [1, "panel"], [1, "table-wrapper"], [1, "data-table"], [1, "th-numeric"], [1, "session-row"], [1, "grid-footer"], [1, "grid-summary"], [1, "pager"], ["colspan", "11", 1, "empty-row"], [1, "session-row", 3, "click"], [1, "cell-strong"], [1, "cell-sub"], [1, "fa-solid", "fa-arrow-right-long"], ["title", "Resumed from a prior session", 1, "resumed-pill"], [1, "cell-user"], [1, "status-pill", 3, "title"], [1, "dot", "dot--live"], [3, "class"], [1, "chan-icons"], [3, "class", "title"], [1, "chan-count"], [1, "cell-numeric"], [1, "cell-numeric", "mono"], [1, "cell-time"], [1, "cell-host", "mono", 3, "title"], [1, "cell-action"], ["mjButton", "", "variant", "icon", "size", "sm", "title", "Open session record", 3, "click"], [1, "fa-solid", "fa-arrow-up-right-from-square"], [1, "fa-solid", "fa-link"], [3, "title"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-chevron-left"], [1, "pager-label"], [1, "fa-solid", "fa-chevron-right"]], template: function AnalyticsRealtimeSessionsComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵconditionalCreate(0, AnalyticsRealtimeSessionsComponent_Conditional_0_Template, 2, 0, "div", 0)(1, AnalyticsRealtimeSessionsComponent_Conditional_1_Template, 69, 14);
        } if (rf & 2) {
            i0.ɵɵconditional(ctx.IsLoading ? 0 : 1);
        } }, dependencies: [i1.NgSelectOption, i1.ɵNgSelectMultipleOption, i2.LoadingComponent, i3.KPICardComponent, i4.MJButtonDirective], styles: ["[_nghost-%COMP%] { display: block; }\n\n        .loading-container[_ngcontent-%COMP%] {\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            min-height: 300px;\n        }\n\n        \n\n        .kpi-grid[_ngcontent-%COMP%] {\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n            gap: 12px;\n            margin-bottom: 16px;\n        }\n\n        \n\n        .filterbar[_ngcontent-%COMP%] {\n            display: flex;\n            align-items: center;\n            gap: 10px;\n            flex-wrap: wrap;\n            background: var(--mj-bg-surface);\n            border: 1px solid var(--mj-border-default);\n            border-radius: 12px;\n            padding: 10px 14px;\n            margin-bottom: 16px;\n        }\n\n        .search-input[_ngcontent-%COMP%] {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n            background: var(--mj-bg-surface-sunken);\n            border: 1px solid var(--mj-border-subtle);\n            border-radius: 8px;\n            padding: 6px 10px;\n            min-width: 240px;\n            flex: 1;\n            max-width: 360px;\n        }\n\n        .search-input[_ngcontent-%COMP%]   i[_ngcontent-%COMP%] {\n            color: var(--mj-text-muted);\n            font-size: 12px;\n        }\n\n        .search-input[_ngcontent-%COMP%]   input[_ngcontent-%COMP%] {\n            border: none;\n            outline: none;\n            background: transparent;\n            color: var(--mj-text-primary);\n            font-size: 13px;\n            width: 100%;\n        }\n\n        .search-input[_ngcontent-%COMP%]   input[_ngcontent-%COMP%]::placeholder { color: var(--mj-text-disabled); }\n\n        .filter-select[_ngcontent-%COMP%] {\n            background: var(--mj-bg-surface);\n            border: 1px solid var(--mj-border-default);\n            border-radius: 8px;\n            color: var(--mj-text-secondary);\n            font-size: 12.5px;\n            padding: 6px 8px;\n            max-width: 200px;\n        }\n\n        .result-pill[_ngcontent-%COMP%] {\n            margin-left: auto;\n            font-size: 12px;\n            color: var(--mj-text-muted);\n            background: var(--mj-bg-surface-sunken);\n            border: 1px solid var(--mj-border-subtle);\n            border-radius: 12px;\n            padding: 4px 12px;\n            white-space: nowrap;\n        }\n\n        \n\n        .panel[_ngcontent-%COMP%] {\n            background: var(--mj-bg-surface);\n            border: 1px solid var(--mj-border-default);\n            border-radius: 12px;\n            overflow: hidden;\n        }\n\n        .table-wrapper[_ngcontent-%COMP%] { overflow-x: auto; }\n\n        .data-table[_ngcontent-%COMP%] {\n            width: 100%;\n            border-collapse: collapse;\n            font-size: 13px;\n        }\n\n        .data-table[_ngcontent-%COMP%]   th[_ngcontent-%COMP%], \n   .data-table[_ngcontent-%COMP%]   td[_ngcontent-%COMP%] {\n            padding: 10px 14px;\n            text-align: left;\n            border-bottom: 1px solid var(--mj-border-subtle);\n        }\n\n        .data-table[_ngcontent-%COMP%]   th[_ngcontent-%COMP%] {\n            font-size: 11px;\n            font-weight: 600;\n            color: var(--mj-text-muted);\n            text-transform: uppercase;\n            letter-spacing: 0.4px;\n            background: var(--mj-bg-surface-card);\n            white-space: nowrap;\n        }\n\n        .th-numeric[_ngcontent-%COMP%] { text-align: right; }\n\n        .session-row[_ngcontent-%COMP%] { cursor: pointer; transition: background 0.15s; }\n        .session-row[_ngcontent-%COMP%]:hover { background: var(--mj-bg-surface-hover); }\n\n        .cell-strong[_ngcontent-%COMP%] {\n            font-weight: 600;\n            color: var(--mj-text-primary);\n            white-space: nowrap;\n        }\n\n        .cell-sub[_ngcontent-%COMP%] {\n            font-size: 11.5px;\n            color: var(--mj-text-muted);\n            display: flex;\n            align-items: center;\n            gap: 6px;\n            white-space: nowrap;\n        }\n\n        .cell-user[_ngcontent-%COMP%] {\n            max-width: 200px;\n            white-space: nowrap;\n            overflow: hidden;\n            text-overflow: ellipsis;\n            color: var(--mj-text-secondary);\n        }\n\n        .cell-numeric[_ngcontent-%COMP%] {\n            text-align: right;\n            font-variant-numeric: tabular-nums;\n            color: var(--mj-text-secondary);\n        }\n\n        .cell-time[_ngcontent-%COMP%] {\n            white-space: nowrap;\n            color: var(--mj-text-muted);\n            font-size: 12px;\n        }\n\n        .cell-host[_ngcontent-%COMP%] {\n            max-width: 160px;\n            white-space: nowrap;\n            overflow: hidden;\n            text-overflow: ellipsis;\n            color: var(--mj-text-muted);\n        }\n\n        .cell-action[_ngcontent-%COMP%] { text-align: right; white-space: nowrap; }\n\n        .mono[_ngcontent-%COMP%] {\n            font-family: var(--mj-font-mono, monospace);\n            font-size: 12px;\n        }\n\n        .empty-row[_ngcontent-%COMP%] {\n            text-align: center;\n            color: var(--mj-text-disabled);\n            padding: 24px;\n        }\n\n        \n\n        .status-pill[_ngcontent-%COMP%] {\n            display: inline-flex;\n            align-items: center;\n            gap: 6px;\n            padding: 3px 10px;\n            border-radius: 12px;\n            font-size: 11px;\n            font-weight: 600;\n            letter-spacing: 0.3px;\n            white-space: nowrap;\n        }\n\n        .status-active[_ngcontent-%COMP%] {\n            background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n            color: var(--mj-status-success);\n        }\n\n        .status-idle[_ngcontent-%COMP%] {\n            background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n            color: var(--mj-status-warning);\n        }\n\n        .status-closed[_ngcontent-%COMP%] {\n            background: color-mix(in srgb, var(--mj-text-disabled) 12%, var(--mj-bg-surface));\n            color: var(--mj-text-muted);\n        }\n\n        .dot--live[_ngcontent-%COMP%] {\n            width: 7px;\n            height: 7px;\n            border-radius: 50%;\n            background: var(--mj-status-success);\n            animation: _ngcontent-%COMP%_pulse-live 1.6s ease-in-out infinite;\n        }\n\n        @keyframes _ngcontent-%COMP%_pulse-live {\n            0%, 100% { opacity: 1; }\n            50% { opacity: 0.35; }\n        }\n\n        .resumed-pill[_ngcontent-%COMP%] {\n            display: inline-flex;\n            align-items: center;\n            gap: 4px;\n            font-size: 10px;\n            font-weight: 600;\n            padding: 1px 7px;\n            border-radius: 10px;\n            background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n            color: var(--mj-brand-primary);\n        }\n\n        .chan-icons[_ngcontent-%COMP%] {\n            display: inline-flex;\n            gap: 8px;\n            color: var(--mj-text-secondary);\n            font-size: 13px;\n        }\n\n        .chan-count[_ngcontent-%COMP%] {\n            margin-left: 6px;\n            font-size: 11px;\n            color: var(--mj-text-muted);\n        }\n\n        \n\n        .grid-footer[_ngcontent-%COMP%] {\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            gap: 12px;\n            margin-top: 14px;\n            flex-wrap: wrap;\n        }\n\n        .grid-summary[_ngcontent-%COMP%] {\n            font-size: 12.5px;\n            color: var(--mj-text-muted);\n        }\n\n        .pager[_ngcontent-%COMP%] {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        .pager-label[_ngcontent-%COMP%] {\n            font-size: 12.5px;\n            color: var(--mj-text-secondary);\n            white-space: nowrap;\n        }"] });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AnalyticsRealtimeSessionsComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'app-analytics-realtime-sessions', template: `
        @if (IsLoading) {
            <div class="loading-container">
                <mj-loading text="Loading agent sessions..."></mj-loading>
            </div>
        } @else {
            <!-- KPI strip -->
            <div class="kpi-grid">
                @for (kpi of KPICards; track kpi.title) {
                    <app-kpi-card [data]="kpi"></app-kpi-card>
                }
            </div>

            <!-- Filter bar: search · status · target agent · user · host -->
            <div class="filterbar">
                <div class="search-input">
                    <i class="fa-solid fa-magnifying-glass"></i>
                    <input type="text"
                           placeholder="Search sessions, users, hosts…"
                           [value]="SearchTerm"
                           (input)="OnSearchChanged($event)" />
                </div>
                <select class="filter-select" [value]="StatusFilter" (change)="OnStatusFilterChanged($event)">
                    <option value="">Status: All</option>
                    <option value="Active">Active</option>
                    <option value="Idle">Idle</option>
                    <option value="Closed">Closed</option>
                </select>
                <select class="filter-select" [value]="TargetFilter" (change)="OnTargetFilterChanged($event)">
                    <option value="">Target: All</option>
                    @for (opt of TargetOptions; track opt.Value) {
                        <option [value]="opt.Value">{{ opt.Label }}</option>
                    }
                </select>
                <select class="filter-select" [value]="UserFilter" (change)="OnUserFilterChanged($event)">
                    <option value="">User: All</option>
                    @for (opt of UserOptions; track opt.Value) {
                        <option [value]="opt.Value">{{ opt.Label }}</option>
                    }
                </select>
                <select class="filter-select" [value]="HostFilter" (change)="OnHostFilterChanged($event)">
                    <option value="">Host: All</option>
                    @for (opt of HostOptions; track opt.Value) {
                        <option [value]="opt.Value">{{ opt.Label }}</option>
                    }
                </select>
                <span class="result-pill">{{ FilteredRows.length }} results · {{ LiveCount }} live</span>
                <button mjButton variant="secondary" size="sm" title="Refresh" (click)="LoadData()">
                    <i class="fa-solid fa-rotate"></i>
                </button>
            </div>

            <!-- Sessions grid -->
            <div class="panel">
                <div class="table-wrapper">
                    <table class="data-table">
                        <thead>
                            <tr>
                                <th>Agent / Target</th>
                                <th>User</th>
                                <th>Status</th>
                                <th>Channels</th>
                                <th class="th-numeric">Runs</th>
                                <th class="th-numeric">Tokens</th>
                                <th class="th-numeric">Cost</th>
                                <th>Started</th>
                                <th class="th-numeric">Duration</th>
                                <th>Host instance</th>
                                <th></th>
                            </tr>
                        </thead>
                        <tbody>
                            @if (PagedRows.length === 0) {
                                <tr><td colspan="11" class="empty-row">No sessions match the current filters</td></tr>
                            }
                            @for (row of PagedRows; track row.ID) {
                                <tr class="session-row" (click)="OpenSession(row.ID)">
                                    <td>
                                        <div class="cell-strong">{{ row.Agent }}</div>
                                        <div class="cell-sub">
                                            <i class="fa-solid fa-arrow-right-long"></i> {{ row.Target }}
                                            @if (row.IsResumed) {
                                                <span class="resumed-pill" title="Resumed from a prior session">
                                                    <i class="fa-solid fa-link"></i> resumed
                                                </span>
                                            }
                                        </div>
                                    </td>
                                    <td class="cell-user">{{ row.User }}</td>
                                    <td>
                                        <span class="status-pill" [class]="row.StatusClass" [title]="row.StatusTitle">
                                            @if (row.Status === 'Active') { <span class="dot dot--live"></span> }
                                            @else if (row.StatusIcon) { <i [class]="row.StatusIcon"></i> }
                                            {{ row.StatusLabel }}
                                        </span>
                                    </td>
                                    <td>
                                        <span class="chan-icons">
                                            @for (chan of row.ChannelIcons; track chan.Name) {
                                                <i [class]="chan.Icon" [title]="chan.Name"></i>
                                            }
                                        </span>
                                        @if (row.ChannelCount > 0) {
                                            <span class="chan-count">{{ row.ChannelCount }}</span>
                                        }
                                    </td>
                                    <td class="cell-numeric">{{ row.Runs }}</td>
                                    <td class="cell-numeric mono">{{ row.Tokens }}</td>
                                    <td class="cell-numeric mono">{{ row.Cost }}</td>
                                    <td class="cell-time">{{ row.Started }}</td>
                                    <td class="cell-numeric mono">{{ row.Duration }}</td>
                                    <td class="cell-host mono" [title]="row.Host">{{ row.Host }}</td>
                                    <td class="cell-action">
                                        <button mjButton variant="icon" size="sm" title="Open session record"
                                                (click)="OpenSession(row.ID); $event.stopPropagation()">
                                            <i class="fa-solid fa-arrow-up-right-from-square"></i>
                                        </button>
                                    </td>
                                </tr>
                            }
                        </tbody>
                    </table>
                </div>
            </div>

            <!-- Pagination / summary -->
            <div class="grid-footer">
                <span class="grid-summary">
                    Showing {{ PagedRows.length }} of {{ FilteredRows.length }}
                    · {{ LiveCount }} live · {{ IdleCount }} idle · {{ ClosedCount }} closed
                </span>
                @if (PageCount > 1) {
                    <div class="pager">
                        <button mjButton variant="secondary" size="sm" [disabled]="PageIndex === 0" (click)="PrevPage()">
                            <i class="fa-solid fa-chevron-left"></i>
                        </button>
                        <span class="pager-label">Page {{ PageIndex + 1 }} of {{ PageCount }}</span>
                        <button mjButton variant="secondary" size="sm" [disabled]="PageIndex >= PageCount - 1" (click)="NextPage()">
                            <i class="fa-solid fa-chevron-right"></i>
                        </button>
                    </div>
                }
            </div>
        }
    `, styles: ["\n        :host { display: block; }\n\n        .loading-container {\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            min-height: 300px;\n        }\n\n        /* \u2500\u2500 KPI Grid \u2500\u2500 */\n        .kpi-grid {\n            display: grid;\n            grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n            gap: 12px;\n            margin-bottom: 16px;\n        }\n\n        /* \u2500\u2500 Filter bar \u2500\u2500 */\n        .filterbar {\n            display: flex;\n            align-items: center;\n            gap: 10px;\n            flex-wrap: wrap;\n            background: var(--mj-bg-surface);\n            border: 1px solid var(--mj-border-default);\n            border-radius: 12px;\n            padding: 10px 14px;\n            margin-bottom: 16px;\n        }\n\n        .search-input {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n            background: var(--mj-bg-surface-sunken);\n            border: 1px solid var(--mj-border-subtle);\n            border-radius: 8px;\n            padding: 6px 10px;\n            min-width: 240px;\n            flex: 1;\n            max-width: 360px;\n        }\n\n        .search-input i {\n            color: var(--mj-text-muted);\n            font-size: 12px;\n        }\n\n        .search-input input {\n            border: none;\n            outline: none;\n            background: transparent;\n            color: var(--mj-text-primary);\n            font-size: 13px;\n            width: 100%;\n        }\n\n        .search-input input::placeholder { color: var(--mj-text-disabled); }\n\n        .filter-select {\n            background: var(--mj-bg-surface);\n            border: 1px solid var(--mj-border-default);\n            border-radius: 8px;\n            color: var(--mj-text-secondary);\n            font-size: 12.5px;\n            padding: 6px 8px;\n            max-width: 200px;\n        }\n\n        .result-pill {\n            margin-left: auto;\n            font-size: 12px;\n            color: var(--mj-text-muted);\n            background: var(--mj-bg-surface-sunken);\n            border: 1px solid var(--mj-border-subtle);\n            border-radius: 12px;\n            padding: 4px 12px;\n            white-space: nowrap;\n        }\n\n        /* \u2500\u2500 Panel + table (matches sibling analytics sections) \u2500\u2500 */\n        .panel {\n            background: var(--mj-bg-surface);\n            border: 1px solid var(--mj-border-default);\n            border-radius: 12px;\n            overflow: hidden;\n        }\n\n        .table-wrapper { overflow-x: auto; }\n\n        .data-table {\n            width: 100%;\n            border-collapse: collapse;\n            font-size: 13px;\n        }\n\n        .data-table th,\n        .data-table td {\n            padding: 10px 14px;\n            text-align: left;\n            border-bottom: 1px solid var(--mj-border-subtle);\n        }\n\n        .data-table th {\n            font-size: 11px;\n            font-weight: 600;\n            color: var(--mj-text-muted);\n            text-transform: uppercase;\n            letter-spacing: 0.4px;\n            background: var(--mj-bg-surface-card);\n            white-space: nowrap;\n        }\n\n        .th-numeric { text-align: right; }\n\n        .session-row { cursor: pointer; transition: background 0.15s; }\n        .session-row:hover { background: var(--mj-bg-surface-hover); }\n\n        .cell-strong {\n            font-weight: 600;\n            color: var(--mj-text-primary);\n            white-space: nowrap;\n        }\n\n        .cell-sub {\n            font-size: 11.5px;\n            color: var(--mj-text-muted);\n            display: flex;\n            align-items: center;\n            gap: 6px;\n            white-space: nowrap;\n        }\n\n        .cell-user {\n            max-width: 200px;\n            white-space: nowrap;\n            overflow: hidden;\n            text-overflow: ellipsis;\n            color: var(--mj-text-secondary);\n        }\n\n        .cell-numeric {\n            text-align: right;\n            font-variant-numeric: tabular-nums;\n            color: var(--mj-text-secondary);\n        }\n\n        .cell-time {\n            white-space: nowrap;\n            color: var(--mj-text-muted);\n            font-size: 12px;\n        }\n\n        .cell-host {\n            max-width: 160px;\n            white-space: nowrap;\n            overflow: hidden;\n            text-overflow: ellipsis;\n            color: var(--mj-text-muted);\n        }\n\n        .cell-action { text-align: right; white-space: nowrap; }\n\n        .mono {\n            font-family: var(--mj-font-mono, monospace);\n            font-size: 12px;\n        }\n\n        .empty-row {\n            text-align: center;\n            color: var(--mj-text-disabled);\n            padding: 24px;\n        }\n\n        /* \u2500\u2500 Status pills \u2500\u2500 */\n        .status-pill {\n            display: inline-flex;\n            align-items: center;\n            gap: 6px;\n            padding: 3px 10px;\n            border-radius: 12px;\n            font-size: 11px;\n            font-weight: 600;\n            letter-spacing: 0.3px;\n            white-space: nowrap;\n        }\n\n        .status-active {\n            background: color-mix(in srgb, var(--mj-status-success) 12%, var(--mj-bg-surface));\n            color: var(--mj-status-success);\n        }\n\n        .status-idle {\n            background: color-mix(in srgb, var(--mj-status-warning) 12%, var(--mj-bg-surface));\n            color: var(--mj-status-warning);\n        }\n\n        .status-closed {\n            background: color-mix(in srgb, var(--mj-text-disabled) 12%, var(--mj-bg-surface));\n            color: var(--mj-text-muted);\n        }\n\n        .dot--live {\n            width: 7px;\n            height: 7px;\n            border-radius: 50%;\n            background: var(--mj-status-success);\n            animation: pulse-live 1.6s ease-in-out infinite;\n        }\n\n        @keyframes pulse-live {\n            0%, 100% { opacity: 1; }\n            50% { opacity: 0.35; }\n        }\n\n        .resumed-pill {\n            display: inline-flex;\n            align-items: center;\n            gap: 4px;\n            font-size: 10px;\n            font-weight: 600;\n            padding: 1px 7px;\n            border-radius: 10px;\n            background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n            color: var(--mj-brand-primary);\n        }\n\n        .chan-icons {\n            display: inline-flex;\n            gap: 8px;\n            color: var(--mj-text-secondary);\n            font-size: 13px;\n        }\n\n        .chan-count {\n            margin-left: 6px;\n            font-size: 11px;\n            color: var(--mj-text-muted);\n        }\n\n        /* \u2500\u2500 Footer / pager \u2500\u2500 */\n        .grid-footer {\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            gap: 12px;\n            margin-top: 14px;\n            flex-wrap: wrap;\n        }\n\n        .grid-summary {\n            font-size: 12.5px;\n            color: var(--mj-text-muted);\n        }\n\n        .pager {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        .pager-label {\n            font-size: 12.5px;\n            color: var(--mj-text-secondary);\n            white-space: nowrap;\n        }\n    "] }]
    }], null, { TimeRange: [{
            type: Input
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AnalyticsRealtimeSessionsComponent, { className: "AnalyticsRealtimeSessionsComponent", filePath: "src/AI/components/analytics/realtime/realtime-sessions.component.ts", lineNumber: 477 }); })();
export function LoadAnalyticsRealtimeSessions() { }
//# sourceMappingURL=realtime-sessions.component.js.map