/**
 * @fileoverview Realtime Voice — analytics overview section.
 *
 * Operational analytics for voice-agent sessions, built from
 * `MJ: AI Agent Sessions`, their `MJ: AI Agent Session Channels` rows, and the
 * delegated `MJ: AI Agent Runs` linked via `AgentSessionID`. Renders the KPI
 * row (active sessions, sessions in window, avg duration, delegated runs,
 * janitor closes, cost), a sessions-over-time bar chart, the channel-usage
 * donut, the top delegated target agents, and a recent-sessions list with a
 * "View all" jump to the full sessions grid.
 */
import { Component, Input, Output, EventEmitter, 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, ChannelIconClass, TimeRangeToMs, BuildSessionStatusDisplay } from './realtime-session-data';
import * as i0 from "@angular/core";
import * as i1 from "@memberjunction/ng-shared-generic";
import * as i2 from "../../widgets/kpi-card.component";
import * as i3 from "@memberjunction/ng-ui-components";
import * as i4 from "@angular/common";
const _forTrack0 = ($index, $item) => $item.title;
const _forTrack1 = ($index, $item) => $item.Name;
const _forTrack2 = ($index, $item) => $item.ID;
const _forTrack3 = ($index, $item) => $item.Label;
function AnalyticsRealtimeOverviewComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 0);
    i0.ɵɵelement(1, "mj-loading", 1);
    i0.ɵɵelementEnd();
} }
function AnalyticsRealtimeOverviewComponent_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 AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_12_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 11);
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_13_For_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 26);
    i0.ɵɵelement(1, "div", 27);
    i0.ɵɵelementStart(2, "div", 28);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const bucket_r3 = ctx.$implicit;
    i0.ɵɵproperty("title", bucket_r3.Label + ": " + bucket_r3.Count + " session(s)");
    i0.ɵɵadvance();
    i0.ɵɵstyleProp("height", bucket_r3.HeightPercent, "%");
    i0.ɵɵclassProp("bar--accent", bucket_r3.DelegatedHeavy);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(bucket_r3.Label);
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_13_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 12);
    i0.ɵɵrepeaterCreate(1, AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_13_For_2_Template, 4, 6, "div", 26, _forTrack3);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r3 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r3.TimeBuckets);
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_22_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 14);
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_23_For_4_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 31);
    i0.ɵɵelement(1, "span", 32);
    i0.ɵɵtext(2);
    i0.ɵɵelementStart(3, "span", 33);
    i0.ɵɵtext(4);
    i0.ɵɵpipe(5, "number");
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const share_r5 = ctx.$implicit;
    i0.ɵɵadvance();
    i0.ɵɵstyleProp("background", share_r5.Color);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" ", share_r5.Name, " ");
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1("", i0.ɵɵpipeBind2(5, 4, share_r5.Percent, "1.0-0"), "%");
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_23_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 15);
    i0.ɵɵelement(1, "div", 29);
    i0.ɵɵelementStart(2, "div", 30);
    i0.ɵɵrepeaterCreate(3, AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_23_For_4_Template, 6, 7, "div", 31, _forTrack1);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r3 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵstyleProp("background", ctx_r3.DonutGradient);
    i0.ɵɵadvance(2);
    i0.ɵɵrepeater(ctx_r3.ChannelShares);
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_32_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 17);
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_For_34_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 18)(1, "span", 34);
    i0.ɵɵtext(2);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "span", 35);
    i0.ɵɵelement(4, "span", 36);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(5, "span", 37);
    i0.ɵɵtext(6);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const bar_r6 = ctx.$implicit;
    i0.ɵɵadvance();
    i0.ɵɵproperty("title", bar_r6.Name);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(bar_r6.Name);
    i0.ɵɵadvance(2);
    i0.ɵɵstyleProp("width", bar_r6.WidthPercent, "%");
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(bar_r6.Count);
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_63_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "tr")(1, "td", 38);
    i0.ɵɵtext(2, "No sessions in the selected period");
    i0.ɵɵelementEnd()();
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_For_65_Conditional_10_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "span", 43);
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_For_65_Conditional_11_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 AnalyticsRealtimeOverviewComponent_Conditional_1_For_65_For_16_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i");
} if (rf & 2) {
    const icon_r9 = ctx.$implicit;
    i0.ɵɵclassMap(icon_r9);
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_For_65_Template(rf, ctx) { if (rf & 1) {
    const _r7 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "tr", 39);
    i0.ɵɵlistener("click", function AnalyticsRealtimeOverviewComponent_Conditional_1_For_65_Template_tr_click_0_listener() { const row_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.OpenSession(row_r8.ID)); });
    i0.ɵɵelementStart(1, "td")(2, "div", 40);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "div", 41);
    i0.ɵɵtext(5);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(6, "td");
    i0.ɵɵtext(7);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(8, "td")(9, "span", 42);
    i0.ɵɵconditionalCreate(10, AnalyticsRealtimeOverviewComponent_Conditional_1_For_65_Conditional_10_Template, 1, 0, "span", 43)(11, AnalyticsRealtimeOverviewComponent_Conditional_1_For_65_Conditional_11_Template, 1, 2, "i", 44);
    i0.ɵɵtext(12);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(13, "td")(14, "span", 45);
    i0.ɵɵrepeaterCreate(15, AnalyticsRealtimeOverviewComponent_Conditional_1_For_65_For_16_Template, 1, 2, "i", 44, i0.ɵɵrepeaterTrackByIndex);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(17, "td", 46);
    i0.ɵɵtext(18);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(19, "td", 47);
    i0.ɵɵtext(20);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(21, "td", 47);
    i0.ɵɵtext(22);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(23, "td", 48)(24, "button", 49);
    i0.ɵɵlistener("click", function AnalyticsRealtimeOverviewComponent_Conditional_1_For_65_Template_button_click_24_listener($event) { const row_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); ctx_r3.OpenSession(row_r8.ID); return i0.ɵɵresetView($event.stopPropagation()); });
    i0.ɵɵelement(25, "i", 50);
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const row_r8 = ctx.$implicit;
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(row_r8.Target);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1("via ", row_r8.ViaAgent);
    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" ? 10 : row_r8.StatusIcon ? 11 : -1);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1(" ", row_r8.StatusLabel, " ");
    i0.ɵɵadvance(3);
    i0.ɵɵrepeater(row_r8.ChannelIcons);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(row_r8.Runs);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(row_r8.Cost);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(row_r8.Duration);
} }
function AnalyticsRealtimeOverviewComponent_Conditional_1_Template(rf, ctx) { if (rf & 1) {
    const _r1 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 2);
    i0.ɵɵrepeaterCreate(1, AnalyticsRealtimeOverviewComponent_Conditional_1_For_2_Template, 1, 1, "app-kpi-card", 3, _forTrack0);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 4)(4, "div", 5)(5, "div", 6)(6, "div", 7);
    i0.ɵɵelement(7, "i", 8);
    i0.ɵɵtext(8, " Sessions over time ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(9, "span", 9);
    i0.ɵɵtext(10, "Accented bars = delegated-heavy");
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(11, "div", 10);
    i0.ɵɵconditionalCreate(12, AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_12_Template, 1, 0, "mj-empty-state", 11)(13, AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_13_Template, 3, 0, "div", 12);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(14, "div", 5)(15, "div", 6)(16, "div", 7);
    i0.ɵɵelement(17, "i", 13);
    i0.ɵɵtext(18, " Channel usage ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(19, "span", 9);
    i0.ɵɵtext(20, "Share of attached session channels");
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(21, "div", 10);
    i0.ɵɵconditionalCreate(22, AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_22_Template, 1, 0, "mj-empty-state", 14)(23, AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_23_Template, 5, 2, "div", 15);
    i0.ɵɵelementEnd()()();
    i0.ɵɵelementStart(24, "div", 5)(25, "div", 6)(26, "div", 7);
    i0.ɵɵelement(27, "i", 16);
    i0.ɵɵtext(28, " Top delegated target agents ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(29, "span", 9);
    i0.ɵɵtext(30, "Delegated agent runs by target \u00B7 selected period");
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(31, "div", 10);
    i0.ɵɵconditionalCreate(32, AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_32_Template, 1, 0, "mj-empty-state", 17);
    i0.ɵɵrepeaterCreate(33, AnalyticsRealtimeOverviewComponent_Conditional_1_For_34_Template, 7, 5, "div", 18, _forTrack1);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(35, "div", 5)(36, "div", 6)(37, "div", 7);
    i0.ɵɵelement(38, "i", 19);
    i0.ɵɵtext(39, " Recent sessions ");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(40, "button", 20);
    i0.ɵɵlistener("click", function AnalyticsRealtimeOverviewComponent_Conditional_1_Template_button_click_40_listener() { i0.ɵɵrestoreView(_r1); const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.SectionNavigate.emit("realtime-sessions")); });
    i0.ɵɵtext(41, " View all ");
    i0.ɵɵelement(42, "i", 21);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(43, "div", 22)(44, "table", 23)(45, "thead")(46, "tr")(47, "th");
    i0.ɵɵtext(48, "Target");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(49, "th");
    i0.ɵɵtext(50, "User");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(51, "th");
    i0.ɵɵtext(52, "Status");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(53, "th");
    i0.ɵɵtext(54, "Channels");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(55, "th", 24);
    i0.ɵɵtext(56, "Runs");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(57, "th", 24);
    i0.ɵɵtext(58, "Cost");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(59, "th", 24);
    i0.ɵɵtext(60, "Duration");
    i0.ɵɵelementEnd();
    i0.ɵɵelement(61, "th");
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(62, "tbody");
    i0.ɵɵconditionalCreate(63, AnalyticsRealtimeOverviewComponent_Conditional_1_Conditional_63_Template, 3, 0, "tr");
    i0.ɵɵrepeaterCreate(64, AnalyticsRealtimeOverviewComponent_Conditional_1_For_65_Template, 26, 11, "tr", 25, _forTrack2);
    i0.ɵɵelementEnd()()()();
} if (rf & 2) {
    const ctx_r3 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r3.KPICards);
    i0.ɵɵadvance(11);
    i0.ɵɵconditional(ctx_r3.TimeBuckets.length === 0 ? 12 : 13);
    i0.ɵɵadvance(10);
    i0.ɵɵconditional(ctx_r3.ChannelShares.length === 0 ? 22 : 23);
    i0.ɵɵadvance(10);
    i0.ɵɵconditional(ctx_r3.TopTargetAgents.length === 0 ? 32 : -1);
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r3.TopTargetAgents);
    i0.ɵɵadvance(30);
    i0.ɵɵconditional(ctx_r3.RecentSessions.length === 0 ? 63 : -1);
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r3.RecentSessions);
} }
const DONUT_COLORS = [
    'var(--mj-brand-primary)',
    'var(--mj-status-success)',
    'var(--mj-brand-accent)',
    'var(--mj-status-warning)',
    'var(--mj-text-disabled)'
];
export class AnalyticsRealtimeOverviewComponent 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; }
    /** Lets the shell jump to the full sessions grid (mirrors Executive Summary's pattern). */
    SectionNavigate = new EventEmitter();
    initialized = false;
    cdr = inject(ChangeDetectorRef);
    dataset = null;
    IsLoading = false;
    KPICards = [];
    TimeBuckets = [];
    ChannelShares = [];
    DonutGradient = '';
    TopTargetAgents = [];
    RecentSessions = [];
    ngOnInit() {
        this.initialized = true;
        this.LoadData();
    }
    /** 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.buildKPICards();
            this.buildTimeBuckets();
            this.buildChannelShares();
            this.buildTopTargetAgents();
            this.buildRecentSessions();
        }
        catch (e) {
            console.error('Realtime Voice overview load error:', e);
        }
        finally {
            this.IsLoading = false;
            this.cdr.detectChanges();
        }
    }
    /** Opens the AIAgentSession record using the shared Explorer record-open path. */
    OpenSession(sessionId) {
        const key = new CompositeKey();
        key.LoadFromSingleKeyValuePair('ID', sessionId);
        SharedService.Instance.OpenEntityRecord('MJ: AI Agent Sessions', key);
    }
    // ── Builders ──
    get windowSessions() {
        return this.dataset?.Sessions ?? [];
    }
    buildKPICards() {
        const ds = this.dataset;
        const sessions = this.windowSessions;
        const activeCount = sessions.filter(s => s.Record.Status === 'Active').length;
        const startedInWindow = sessions.filter(s => ds != null && s.StartedAt >= ds.WindowStart);
        const priorCount = ds?.PriorWindowSessionCount ?? 0;
        const durations = sessions.map(s => s.DurationMs).filter(d => d > 0);
        const avgDuration = durations.length > 0
            ? durations.reduce((a, b) => a + b, 0) / durations.length
            : 0;
        const delegatedTotal = sessions.reduce((a, s) => a + s.DelegatedRunCount, 0);
        const delegatedPerSession = sessions.length > 0 ? delegatedTotal / sessions.length : 0;
        const janitorCloses = sessions.filter(s => s.IsJanitorClosed).length;
        const totalCost = sessions.reduce((a, s) => a + s.TotalCost, 0);
        const trendPct = priorCount > 0
            ? Math.round(((startedInWindow.length - priorCount) / priorCount) * 100)
            : 0;
        this.KPICards = [
            {
                title: 'Active sessions',
                value: activeCount,
                subtitle: 'live right now',
                icon: 'fa-tower-broadcast',
                color: 'success'
            },
            {
                title: `Sessions (${this.TimeRange})`,
                value: startedInWindow.length,
                icon: 'fa-calendar-day',
                color: 'primary',
                trend: priorCount > 0 ? {
                    direction: trendPct > 0 ? 'up' : trendPct < 0 ? 'down' : 'stable',
                    percentage: Math.abs(trendPct),
                    period: `vs prior ${this.TimeRange}`
                } : undefined,
                subtitle: priorCount > 0 ? undefined : 'no prior-period data'
            },
            {
                title: 'Avg duration',
                value: FormatSessionDuration(avgDuration),
                subtitle: 'min:sec per session',
                icon: 'fa-stopwatch',
                color: 'info'
            },
            {
                title: 'Delegated runs',
                value: delegatedTotal,
                subtitle: `${delegatedPerSession.toFixed(1)} per session avg`,
                icon: 'fa-diagram-project',
                color: 'info'
            },
            {
                title: 'Janitor closes',
                value: janitorCloses,
                subtitle: `orphans reconciled (${this.TimeRange})`,
                icon: 'fa-broom',
                color: 'warning'
            },
            {
                title: `Cost (${this.TimeRange})`,
                value: FormatSessionCost(totalCost),
                subtitle: 'co-agent + delegated',
                icon: 'fa-coins',
                color: 'danger'
            }
        ];
    }
    buildTimeBuckets() {
        const ds = this.dataset;
        if (!ds) {
            this.TimeBuckets = [];
            return;
        }
        const hourly = this.TimeRange === '24h';
        const bucketMs = hourly ? 3_600_000 : 86_400_000;
        const bucketCount = Math.max(1, Math.round(ds.WindowMs / bucketMs));
        const now = Date.now();
        const buckets = [];
        for (let i = bucketCount - 1; i >= 0; i--) {
            buckets.push({ start: now - (i + 1) * bucketMs, count: 0, delegated: 0 });
        }
        for (const session of this.windowSessions) {
            const t = session.StartedAt.getTime();
            const idx = buckets.findIndex(b => t >= b.start && t < b.start + bucketMs);
            if (idx >= 0) {
                buckets[idx].count++;
                buckets[idx].delegated += session.DelegatedRunCount;
            }
        }
        const max = Math.max(1, ...buckets.map(b => b.count));
        this.TimeBuckets = buckets.map((b, i) => {
            const date = new Date(b.start + bucketMs);
            const isLast = i === buckets.length - 1;
            const label = hourly
                ? date.toLocaleTimeString([], { hour: 'numeric' }).toLowerCase()
                : isLast ? 'Today' : date.toLocaleDateString([], { weekday: this.TimeRange === '7d' ? 'short' : undefined, month: this.TimeRange === '7d' ? undefined : 'numeric', day: this.TimeRange === '7d' ? undefined : 'numeric' });
            return {
                Label: label,
                Count: b.count,
                HeightPercent: Math.round((b.count / max) * 100),
                DelegatedHeavy: b.count > 0 && b.delegated / b.count >= 2
            };
        });
    }
    buildChannelShares() {
        const counts = new Map();
        for (const session of this.windowSessions) {
            for (const name of session.ChannelNames) {
                counts.set(name, (counts.get(name) ?? 0) + 1);
            }
        }
        const total = Array.from(counts.values()).reduce((a, b) => a + b, 0);
        if (total === 0) {
            this.ChannelShares = [];
            this.DonutGradient = '';
            return;
        }
        const sorted = Array.from(counts.entries()).sort((a, b) => b[1] - a[1]);
        this.ChannelShares = sorted.map(([name, count], i) => ({
            Name: name,
            Count: count,
            Percent: (count / total) * 100,
            Color: DONUT_COLORS[i % DONUT_COLORS.length]
        }));
        let cursor = 0;
        const stops = [];
        for (const share of this.ChannelShares) {
            const end = cursor + share.Percent;
            stops.push(`${share.Color} ${cursor.toFixed(2)}% ${end.toFixed(2)}%`);
            cursor = end;
        }
        this.DonutGradient = `conic-gradient(${stops.join(', ')})`;
    }
    buildTopTargetAgents() {
        const counts = new Map();
        for (const session of this.windowSessions) {
            if (session.DelegatedRunCount === 0)
                continue;
            const name = session.TargetAgentName ?? session.TargetAgentID ?? 'Unknown';
            counts.set(name, (counts.get(name) ?? 0) + session.DelegatedRunCount);
        }
        const sorted = Array.from(counts.entries())
            .sort((a, b) => b[1] - a[1])
            .slice(0, 5);
        const max = Math.max(1, ...sorted.map(([, c]) => c));
        this.TopTargetAgents = sorted.map(([name, count]) => ({
            Name: name,
            Count: count,
            WidthPercent: Math.round((count / max) * 100)
        }));
    }
    buildRecentSessions() {
        this.RecentSessions = [...this.windowSessions]
            .sort((a, b) => b.StartedAt.getTime() - a.StartedAt.getTime())
            .slice(0, 8)
            .map(s => {
            const statusDisplay = BuildSessionStatusDisplay(s.Record.Status, s.CloseReason);
            return {
                ID: s.Record.ID,
                Target: s.TargetAgentName ?? s.Record.Agent ?? 'Unknown',
                ViaAgent: s.Record.Agent ?? 'Unknown',
                User: s.Record.User,
                Status: s.Record.Status,
                StatusClass: 'status-pill status-' + s.Record.Status.toLowerCase(),
                StatusLabel: statusDisplay.Label,
                StatusTitle: statusDisplay.Title,
                StatusIcon: statusDisplay.Icon,
                ChannelIcons: s.ChannelNames.map(ChannelIconClass),
                Runs: s.DelegatedRunCount,
                Cost: FormatSessionCost(s.TotalCost),
                Duration: FormatSessionDuration(s.DurationMs)
            };
        });
    }
    /** Exposed for testability / template type narrowing. */
    FormatTokens(value) {
        return FormatTokenCount(value);
    }
    /** Window length in ms for the active range (exposed for tests). */
    get WindowMs() {
        return TimeRangeToMs(this.TimeRange);
    }
    static ɵfac = /*@__PURE__*/ (() => { let ɵAnalyticsRealtimeOverviewComponent_BaseFactory; return function AnalyticsRealtimeOverviewComponent_Factory(__ngFactoryType__) { return (ɵAnalyticsRealtimeOverviewComponent_BaseFactory || (ɵAnalyticsRealtimeOverviewComponent_BaseFactory = i0.ɵɵgetInheritedFactory(AnalyticsRealtimeOverviewComponent)))(__ngFactoryType__ || AnalyticsRealtimeOverviewComponent); }; })();
    static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AnalyticsRealtimeOverviewComponent, selectors: [["app-analytics-realtime-overview"]], inputs: { TimeRange: "TimeRange" }, outputs: { SectionNavigate: "SectionNavigate" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 2, vars: 1, consts: [[1, "loading-container"], ["text", "Loading realtime voice analytics..."], [1, "kpi-grid"], [3, "data"], [1, "charts-2"], [1, "panel"], [1, "panel-header"], [1, "panel-header__title"], [1, "fa-solid", "fa-chart-column", "panel-header__icon"], [1, "panel-header__subtitle"], [1, "panel-body"], ["Size", "compact", "Variant", "empty", "Icon", "fa-solid fa-chart-column", "Title", "No sessions in the selected period"], [1, "bars"], [1, "fa-solid", "fa-chart-pie", "panel-header__icon"], ["Size", "compact", "Variant", "empty", "Icon", "fa-solid fa-chart-pie", "Title", "No channels attached in the selected period"], [1, "donut-row"], [1, "fa-solid", "fa-diagram-project", "panel-header__icon"], ["Size", "compact", "Variant", "empty", "Icon", "fa-solid fa-diagram-project", "Title", "No delegated runs in the selected period"], [1, "hbar-row"], [1, "fa-solid", "fa-tower-broadcast", "panel-header__icon"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-arrow-right"], [1, "table-wrapper"], [1, "data-table"], [1, "th-numeric"], [1, "session-row"], [1, "bcol", 3, "title"], [1, "bar"], [1, "blabel"], [1, "donut"], [1, "legend"], [1, "legend-item"], [1, "legend-dot"], [1, "legend-pct"], [1, "hbar-name", 3, "title"], [1, "hbar-track"], [1, "hbar-fill"], [1, "hbar-val"], ["colspan", "8", 1, "empty-row"], [1, "session-row", 3, "click"], [1, "cell-strong"], [1, "cell-sub"], [1, "status-pill", 3, "title"], [1, "dot", "dot--live"], [3, "class"], [1, "chan-icons"], [1, "cell-numeric"], [1, "cell-numeric", "mono"], [1, "cell-action"], ["mjButton", "", "variant", "icon", "size", "sm", "title", "Open session record", 3, "click"], [1, "fa-solid", "fa-arrow-up-right-from-square"]], template: function AnalyticsRealtimeOverviewComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵconditionalCreate(0, AnalyticsRealtimeOverviewComponent_Conditional_0_Template, 2, 0, "div", 0)(1, AnalyticsRealtimeOverviewComponent_Conditional_1_Template, 66, 4);
        } if (rf & 2) {
            i0.ɵɵconditional(ctx.IsLoading ? 0 : 1);
        } }, dependencies: [i1.LoadingComponent, i2.KPICardComponent, i3.MJButtonDirective, i3.MJEmptyStateComponent, i4.DecimalPipe], 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        .charts-2[_ngcontent-%COMP%] {\n            display: grid;\n            grid-template-columns: 1.4fr 1fr;\n            gap: 16px;\n            margin-bottom: 16px;\n        }\n\n        @media (max-width: 1000px) {\n            .charts-2[_ngcontent-%COMP%] { grid-template-columns: 1fr; }\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            margin-bottom: 16px;\n            overflow: hidden;\n        }\n\n        .panel-header[_ngcontent-%COMP%] {\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            padding: 14px 18px;\n            border-bottom: 1px solid var(--mj-border-subtle);\n        }\n\n        .panel-header__title[_ngcontent-%COMP%] {\n            font-size: 14px;\n            font-weight: 600;\n            color: var(--mj-text-primary);\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        .panel-header__icon[_ngcontent-%COMP%] {\n            font-size: 13px;\n            color: var(--mj-brand-primary);\n        }\n\n        .panel-header__subtitle[_ngcontent-%COMP%] {\n            font-size: 12px;\n            color: var(--mj-text-muted);\n        }\n\n        .panel-body[_ngcontent-%COMP%] { padding: 16px 18px; }\n\n        \n\n        .bars[_ngcontent-%COMP%] {\n            display: flex;\n            align-items: flex-end;\n            gap: 8px;\n            height: 160px;\n        }\n\n        .bcol[_ngcontent-%COMP%] {\n            flex: 1;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: flex-end;\n            height: 100%;\n            min-width: 0;\n        }\n\n        .bar[_ngcontent-%COMP%] {\n            width: 100%;\n            max-width: 42px;\n            min-height: 2px;\n            border-radius: 6px 6px 2px 2px;\n            background: linear-gradient(180deg,\n                color-mix(in srgb, var(--mj-brand-primary) 85%, transparent),\n                color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n            transition: height 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n        }\n\n        .bar--accent[_ngcontent-%COMP%] {\n            background: linear-gradient(180deg,\n                color-mix(in srgb, var(--mj-status-success) 85%, transparent),\n                color-mix(in srgb, var(--mj-status-success) 55%, transparent));\n        }\n\n        .blabel[_ngcontent-%COMP%] {\n            margin-top: 6px;\n            font-size: 10px;\n            color: var(--mj-text-muted);\n            white-space: nowrap;\n            overflow: hidden;\n            text-overflow: ellipsis;\n            max-width: 100%;\n        }\n\n        \n\n        .donut-row[_ngcontent-%COMP%] {\n            display: flex;\n            align-items: center;\n            gap: 22px;\n            flex-wrap: wrap;\n        }\n\n        .donut[_ngcontent-%COMP%] {\n            width: 140px;\n            height: 140px;\n            border-radius: 50%;\n            flex-shrink: 0;\n            -webkit-mask: radial-gradient(circle at center, transparent 42px, #000 43px);\n            mask: radial-gradient(circle at center, transparent 42px, #000 43px);\n        }\n\n        .legend[_ngcontent-%COMP%] {\n            display: flex;\n            flex-direction: column;\n            gap: 8px;\n            min-width: 160px;\n            flex: 1;\n        }\n\n        .legend-item[_ngcontent-%COMP%] {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n            font-size: 12.5px;\n            color: var(--mj-text-secondary);\n        }\n\n        .legend-dot[_ngcontent-%COMP%] {\n            width: 10px;\n            height: 10px;\n            border-radius: 50%;\n            flex-shrink: 0;\n        }\n\n        .legend-pct[_ngcontent-%COMP%] {\n            margin-left: auto;\n            color: var(--mj-text-muted);\n            font-variant-numeric: tabular-nums;\n        }\n\n        \n\n        .hbar-row[_ngcontent-%COMP%] {\n            display: flex;\n            align-items: center;\n            gap: 12px;\n            margin-bottom: 10px;\n        }\n\n        .hbar-row[_ngcontent-%COMP%]:last-child { margin-bottom: 0; }\n\n        .hbar-name[_ngcontent-%COMP%] {\n            width: 140px;\n            min-width: 140px;\n            font-size: 13px;\n            font-weight: 500;\n            color: var(--mj-text-primary);\n            white-space: nowrap;\n            overflow: hidden;\n            text-overflow: ellipsis;\n        }\n\n        .hbar-track[_ngcontent-%COMP%] {\n            flex: 1;\n            height: 18px;\n            border-radius: 6px;\n            background: var(--mj-bg-surface-sunken);\n            overflow: hidden;\n        }\n\n        .hbar-fill[_ngcontent-%COMP%] {\n            display: block;\n            height: 100%;\n            border-radius: 6px;\n            background: linear-gradient(90deg,\n                var(--mj-brand-primary),\n                color-mix(in srgb, var(--mj-brand-primary) 65%, var(--mj-bg-surface)));\n            transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n        }\n\n        .hbar-val[_ngcontent-%COMP%] {\n            width: 48px;\n            min-width: 48px;\n            text-align: right;\n            font-size: 13px;\n            font-weight: 600;\n            color: var(--mj-text-secondary);\n            font-variant-numeric: tabular-nums;\n        }\n\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        }\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        }\n\n        .cell-sub[_ngcontent-%COMP%] {\n            font-size: 11px;\n            color: var(--mj-text-muted);\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-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        .chan-icons[_ngcontent-%COMP%] {\n            display: inline-flex;\n            gap: 8px;\n            color: var(--mj-text-secondary);\n            font-size: 13px;\n        }"] });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(AnalyticsRealtimeOverviewComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'app-analytics-realtime-overview', template: `
        @if (IsLoading) {
            <div class="loading-container">
                <mj-loading text="Loading realtime voice analytics..."></mj-loading>
            </div>
        } @else {
            <!-- KPI Row -->
            <div class="kpi-grid">
                @for (kpi of KPICards; track kpi.title) {
                    <app-kpi-card [data]="kpi"></app-kpi-card>
                }
            </div>

            <!-- Charts row 1: sessions over time + channel usage -->
            <div class="charts-2">
                <div class="panel">
                    <div class="panel-header">
                        <div class="panel-header__title">
                            <i class="fa-solid fa-chart-column panel-header__icon"></i>
                            Sessions over time
                        </div>
                        <span class="panel-header__subtitle">Accented bars = delegated-heavy</span>
                    </div>
                    <div class="panel-body">
                        @if (TimeBuckets.length === 0) {
                            <mj-empty-state Size="compact" Variant="empty" Icon="fa-solid fa-chart-column"
                                Title="No sessions in the selected period" />
                        } @else {
                            <div class="bars">
                                @for (bucket of TimeBuckets; track bucket.Label) {
                                    <div class="bcol" [title]="bucket.Label + ': ' + bucket.Count + ' session(s)'">
                                        <div class="bar"
                                             [class.bar--accent]="bucket.DelegatedHeavy"
                                             [style.height.%]="bucket.HeightPercent"></div>
                                        <div class="blabel">{{ bucket.Label }}</div>
                                    </div>
                                }
                            </div>
                        }
                    </div>
                </div>
                <div class="panel">
                    <div class="panel-header">
                        <div class="panel-header__title">
                            <i class="fa-solid fa-chart-pie panel-header__icon"></i>
                            Channel usage
                        </div>
                        <span class="panel-header__subtitle">Share of attached session channels</span>
                    </div>
                    <div class="panel-body">
                        @if (ChannelShares.length === 0) {
                            <mj-empty-state Size="compact" Variant="empty" Icon="fa-solid fa-chart-pie"
                                Title="No channels attached in the selected period" />
                        } @else {
                            <div class="donut-row">
                                <div class="donut" [style.background]="DonutGradient"></div>
                                <div class="legend">
                                    @for (share of ChannelShares; track share.Name) {
                                        <div class="legend-item">
                                            <span class="legend-dot" [style.background]="share.Color"></span>
                                            {{ share.Name }}
                                            <span class="legend-pct">{{ share.Percent | number:'1.0-0' }}%</span>
                                        </div>
                                    }
                                </div>
                            </div>
                        }
                    </div>
                </div>
            </div>

            <!-- Charts row 2: top delegated target agents -->
            <div class="panel">
                <div class="panel-header">
                    <div class="panel-header__title">
                        <i class="fa-solid fa-diagram-project panel-header__icon"></i>
                        Top delegated target agents
                    </div>
                    <span class="panel-header__subtitle">Delegated agent runs by target · selected period</span>
                </div>
                <div class="panel-body">
                    @if (TopTargetAgents.length === 0) {
                        <mj-empty-state Size="compact" Variant="empty" Icon="fa-solid fa-diagram-project"
                            Title="No delegated runs in the selected period" />
                    }
                    @for (bar of TopTargetAgents; track bar.Name) {
                        <div class="hbar-row">
                            <span class="hbar-name" [title]="bar.Name">{{ bar.Name }}</span>
                            <span class="hbar-track">
                                <span class="hbar-fill" [style.width.%]="bar.WidthPercent"></span>
                            </span>
                            <span class="hbar-val">{{ bar.Count }}</span>
                        </div>
                    }
                </div>
            </div>

            <!-- Recent sessions -->
            <div class="panel">
                <div class="panel-header">
                    <div class="panel-header__title">
                        <i class="fa-solid fa-tower-broadcast panel-header__icon"></i>
                        Recent sessions
                    </div>
                    <button mjButton variant="secondary" size="sm" (click)="SectionNavigate.emit('realtime-sessions')">
                        View all <i class="fa-solid fa-arrow-right"></i>
                    </button>
                </div>
                <div class="table-wrapper">
                    <table class="data-table">
                        <thead>
                            <tr>
                                <th>Target</th><th>User</th><th>Status</th><th>Channels</th>
                                <th class="th-numeric">Runs</th><th class="th-numeric">Cost</th>
                                <th class="th-numeric">Duration</th><th></th>
                            </tr>
                        </thead>
                        <tbody>
                            @if (RecentSessions.length === 0) {
                                <tr><td colspan="8" class="empty-row">No sessions in the selected period</td></tr>
                            }
                            @for (row of RecentSessions; track row.ID) {
                                <tr class="session-row" (click)="OpenSession(row.ID)">
                                    <td>
                                        <div class="cell-strong">{{ row.Target }}</div>
                                        <div class="cell-sub">via {{ row.ViaAgent }}</div>
                                    </td>
                                    <td>{{ 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 (icon of row.ChannelIcons; track $index) {
                                                <i [class]="icon"></i>
                                            }
                                        </span>
                                    </td>
                                    <td class="cell-numeric">{{ row.Runs }}</td>
                                    <td class="cell-numeric mono">{{ row.Cost }}</td>
                                    <td class="cell-numeric mono">{{ row.Duration }}</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>
        }
    `, 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 Layout \u2500\u2500 */\n        .charts-2 {\n            display: grid;\n            grid-template-columns: 1.4fr 1fr;\n            gap: 16px;\n            margin-bottom: 16px;\n        }\n\n        @media (max-width: 1000px) {\n            .charts-2 { grid-template-columns: 1fr; }\n        }\n\n        /* \u2500\u2500 Panel (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            margin-bottom: 16px;\n            overflow: hidden;\n        }\n\n        .panel-header {\n            display: flex;\n            align-items: center;\n            justify-content: space-between;\n            padding: 14px 18px;\n            border-bottom: 1px solid var(--mj-border-subtle);\n        }\n\n        .panel-header__title {\n            font-size: 14px;\n            font-weight: 600;\n            color: var(--mj-text-primary);\n            display: flex;\n            align-items: center;\n            gap: 8px;\n        }\n\n        .panel-header__icon {\n            font-size: 13px;\n            color: var(--mj-brand-primary);\n        }\n\n        .panel-header__subtitle {\n            font-size: 12px;\n            color: var(--mj-text-muted);\n        }\n\n        .panel-body { padding: 16px 18px; }\n\n        /* \u2500\u2500 Vertical bars \u2500\u2500 */\n        .bars {\n            display: flex;\n            align-items: flex-end;\n            gap: 8px;\n            height: 160px;\n        }\n\n        .bcol {\n            flex: 1;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            justify-content: flex-end;\n            height: 100%;\n            min-width: 0;\n        }\n\n        .bar {\n            width: 100%;\n            max-width: 42px;\n            min-height: 2px;\n            border-radius: 6px 6px 2px 2px;\n            background: linear-gradient(180deg,\n                color-mix(in srgb, var(--mj-brand-primary) 85%, transparent),\n                color-mix(in srgb, var(--mj-brand-primary) 55%, transparent));\n            transition: height 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n        }\n\n        .bar--accent {\n            background: linear-gradient(180deg,\n                color-mix(in srgb, var(--mj-status-success) 85%, transparent),\n                color-mix(in srgb, var(--mj-status-success) 55%, transparent));\n        }\n\n        .blabel {\n            margin-top: 6px;\n            font-size: 10px;\n            color: var(--mj-text-muted);\n            white-space: nowrap;\n            overflow: hidden;\n            text-overflow: ellipsis;\n            max-width: 100%;\n        }\n\n        /* \u2500\u2500 Donut \u2500\u2500 */\n        .donut-row {\n            display: flex;\n            align-items: center;\n            gap: 22px;\n            flex-wrap: wrap;\n        }\n\n        .donut {\n            width: 140px;\n            height: 140px;\n            border-radius: 50%;\n            flex-shrink: 0;\n            -webkit-mask: radial-gradient(circle at center, transparent 42px, #000 43px);\n            mask: radial-gradient(circle at center, transparent 42px, #000 43px);\n        }\n\n        .legend {\n            display: flex;\n            flex-direction: column;\n            gap: 8px;\n            min-width: 160px;\n            flex: 1;\n        }\n\n        .legend-item {\n            display: flex;\n            align-items: center;\n            gap: 8px;\n            font-size: 12.5px;\n            color: var(--mj-text-secondary);\n        }\n\n        .legend-dot {\n            width: 10px;\n            height: 10px;\n            border-radius: 50%;\n            flex-shrink: 0;\n        }\n\n        .legend-pct {\n            margin-left: auto;\n            color: var(--mj-text-muted);\n            font-variant-numeric: tabular-nums;\n        }\n\n        /* \u2500\u2500 Horizontal bars \u2500\u2500 */\n        .hbar-row {\n            display: flex;\n            align-items: center;\n            gap: 12px;\n            margin-bottom: 10px;\n        }\n\n        .hbar-row:last-child { margin-bottom: 0; }\n\n        .hbar-name {\n            width: 140px;\n            min-width: 140px;\n            font-size: 13px;\n            font-weight: 500;\n            color: var(--mj-text-primary);\n            white-space: nowrap;\n            overflow: hidden;\n            text-overflow: ellipsis;\n        }\n\n        .hbar-track {\n            flex: 1;\n            height: 18px;\n            border-radius: 6px;\n            background: var(--mj-bg-surface-sunken);\n            overflow: hidden;\n        }\n\n        .hbar-fill {\n            display: block;\n            height: 100%;\n            border-radius: 6px;\n            background: linear-gradient(90deg,\n                var(--mj-brand-primary),\n                color-mix(in srgb, var(--mj-brand-primary) 65%, var(--mj-bg-surface)));\n            transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1);\n        }\n\n        .hbar-val {\n            width: 48px;\n            min-width: 48px;\n            text-align: right;\n            font-size: 13px;\n            font-weight: 600;\n            color: var(--mj-text-secondary);\n            font-variant-numeric: tabular-nums;\n        }\n\n        /* \u2500\u2500 Table \u2500\u2500 */\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        }\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        }\n\n        .cell-sub {\n            font-size: 11px;\n            color: var(--mj-text-muted);\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-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        .chan-icons {\n            display: inline-flex;\n            gap: 8px;\n            color: var(--mj-text-secondary);\n            font-size: 13px;\n        }\n    "] }]
    }], null, { TimeRange: [{
            type: Input
        }], SectionNavigate: [{
            type: Output
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(AnalyticsRealtimeOverviewComponent, { className: "AnalyticsRealtimeOverviewComponent", filePath: "src/AI/components/analytics/realtime/realtime-overview.component.ts", lineNumber: 556 }); })();
export function LoadAnalyticsRealtimeOverview() { }
//# sourceMappingURL=realtime-overview.component.js.map