/**
 * @fileoverview Classify · Suggestions Inbox tab.
 *
 * Self-contained sub-page that surfaces `MJ: Tag Suggestions` — the
 * human-in-the-loop review queue produced by the classifier when a tag lands in
 * the ambiguous band (BelowThreshold, ConstrainedMode, ParentFrozen, …) and by
 * the server-side TagHealthJob (merge / low-usage / wide-node candidates).
 *
 * 3-pane layout: (1) a filter rail by Reason (with counts) + Status,
 * (2) the suggestion list, (3) a reading pane with the proposed name/parent,
 * best-match score on a threshold-band gradient, the source-item link, and the
 * Approve / Merge / Reject action bar.
 *
 * Data is TRANSACTIONAL and can grow — it is loaded via RunView (NOT cached).
 * Status filtering re-queries the DB; Reason filtering is applied in-memory on
 * the loaded Pending set.
 *
 * The host owns the lightweight pending-count badge on the nav rail; this tab
 * emits `(Resolved)` after every action so the host can refresh that badge.
 */
import { Component, ChangeDetectorRef, EventEmitter, Output, inject } from '@angular/core';
import { RunView } from '@memberjunction/core';
import { UUIDsEqual } from '@memberjunction/global';
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
import { MJNotificationService } from '@memberjunction/ng-notifications';
import { TagEngineBase } from '@memberjunction/tag-engine-base';
import { formatShortDate } from '../shared/classify.format';
import * as i0 from "@angular/core";
import * as i1 from "@angular/forms";
import * as i2 from "@memberjunction/ng-shared-generic";
import * as i3 from "@memberjunction/ng-ui-components";
const _forTrack0 = ($index, $item) => $item.Reason;
const _forTrack1 = ($index, $item) => $item.ID;
function ClassifyInboxTabComponent_Conditional_7_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 10);
    i0.ɵɵelementStart(1, "span", 11);
    i0.ɵɵtext(2, "Refreshing\u2026");
    i0.ɵɵelementEnd();
} }
function ClassifyInboxTabComponent_Conditional_8_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 12);
    i0.ɵɵelementStart(1, "span", 11);
    i0.ɵɵtext(2, "Refresh");
    i0.ɵɵelementEnd();
} }
function ClassifyInboxTabComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 8);
    i0.ɵɵelement(1, "mj-loading", 13);
    i0.ɵɵelementEnd();
} }
function ClassifyInboxTabComponent_Conditional_12_For_9_Template(rf, ctx) { if (rf & 1) {
    const _r3 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "a", 15);
    i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_For_9_Template_a_click_0_listener() { const rc_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetReasonFilter(rc_r4.Reason)); });
    i0.ɵɵtext(1);
    i0.ɵɵelementStart(2, "span", 16);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const rc_r4 = ctx.$implicit;
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵclassProp("ci-active", ctx_r1.ReasonFilter === rc_r4.Reason);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" ", rc_r4.Label, " ");
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(rc_r4.Count);
} }
function ClassifyInboxTabComponent_Conditional_12_For_13_Template(rf, ctx) { if (rf & 1) {
    const _r5 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "a", 15);
    i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_For_13_Template_a_click_0_listener() { const st_r6 = i0.ɵɵrestoreView(_r5).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.SetStatusFilter(st_r6)); });
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const st_r6 = ctx.$implicit;
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵclassProp("ci-active", ctx_r1.StatusFilter === st_r6);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" ", st_r6, " ");
} }
function ClassifyInboxTabComponent_Conditional_12_Conditional_22_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 22);
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵproperty("Title", ctx_r1.NoSuggestionsMessage);
} }
function ClassifyInboxTabComponent_Conditional_12_Conditional_23_For_1_Conditional_9_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 32);
    i0.ɵɵtext(1, "\u2248 ");
    i0.ɵɵelementStart(2, "b");
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd();
    i0.ɵɵtext(4);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const s_r8 = i0.ɵɵnextContext().$implicit;
    const ctx_r1 = i0.ɵɵnextContext(3);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(s_r8.BestMatchTag);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" \u00B7 ", ctx_r1.FormatScore(s_r8.BestMatchScore));
} }
function ClassifyInboxTabComponent_Conditional_12_Conditional_23_For_1_Template(rf, ctx) { if (rf & 1) {
    const _r7 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 26);
    i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Conditional_23_For_1_Template_div_click_0_listener() { const s_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.SelectSuggestion(s_r8)); });
    i0.ɵɵelementStart(1, "div", 27)(2, "span", 28);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "span", 29);
    i0.ɵɵtext(5);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(6, "div", 30)(7, "span", 31);
    i0.ɵɵtext(8);
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(9, ClassifyInboxTabComponent_Conditional_12_Conditional_23_For_1_Conditional_9_Template, 5, 2, "span", 32);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const s_r8 = ctx.$implicit;
    const ctx_r1 = i0.ɵɵnextContext(3);
    i0.ɵɵclassProp("ci-sel", (ctx_r1.Selected == null ? null : ctx_r1.Selected.ID) === s_r8.ID);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate1("\"", s_r8.ProposedName, "\"");
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(ctx_r1.formatShortDate(s_r8.__mj_CreatedAt + ""));
    i0.ɵɵadvance(2);
    i0.ɵɵclassMap("ci-pill-" + ctx_r1.ReasonPill(s_r8.Reason));
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(ctx_r1.ReasonLabel(s_r8.Reason));
    i0.ɵɵadvance();
    i0.ɵɵconditional(s_r8.BestMatchTag ? 9 : -1);
} }
function ClassifyInboxTabComponent_Conditional_12_Conditional_23_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵrepeaterCreate(0, ClassifyInboxTabComponent_Conditional_12_Conditional_23_For_1_Template, 10, 8, "div", 25, _forTrack1);
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵrepeater(ctx_r1.FilteredSuggestions);
} }
function ClassifyInboxTabComponent_Conditional_12_Conditional_25_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 24);
} }
function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_17_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵtext(0);
    i0.ɵɵelementStart(1, "span", 41);
    i0.ɵɵtext(2, "(existing tag)");
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(3);
    i0.ɵɵtextInterpolate1(" ", ctx_r1.Selected.BestMatchTag, " ");
} }
function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_18_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 41);
    i0.ɵɵtext(1, "No close match");
    i0.ɵɵelementEnd();
} }
function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_19_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 39);
    i0.ɵɵtext(1, "From content item");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(2, "div", 56);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(3);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(ctx_r1.Selected.SourceContentItem);
} }
function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_20_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 39);
    i0.ɵɵtext(1, "Source text");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(2, "div", 57);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(3);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(ctx_r1.Selected.SourceText);
} }
function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_21_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 42)(1, "h5");
    i0.ɵɵtext(2, "Match confidence vs thresholds");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(3, "div", 58);
    i0.ɵɵelement(4, "div", 59);
    i0.ɵɵelementStart(5, "div", 60);
    i0.ɵɵtext(6);
    i0.ɵɵelementEnd();
    i0.ɵɵelement(7, "div", 59);
    i0.ɵɵelementStart(8, "div", 60);
    i0.ɵɵtext(9);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(10, "div", 61);
    i0.ɵɵtext(11);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(12, "div", 62)(13, "span");
    i0.ɵɵtext(14, "reject / new");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(15, "span");
    i0.ɵɵtext(16, "review band");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(17, "span");
    i0.ɵɵtext(18, "auto-apply");
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(3);
    i0.ɵɵadvance(4);
    i0.ɵɵstyleProp("left", ctx_r1.ScorePct(ctx_r1.SuggestThreshold), "%");
    i0.ɵɵadvance();
    i0.ɵɵstyleProp("left", ctx_r1.ScorePct(ctx_r1.SuggestThreshold), "%");
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1("Suggest ", ctx_r1.FormatScore(ctx_r1.SuggestThreshold));
    i0.ɵɵadvance();
    i0.ɵɵstyleProp("left", ctx_r1.ScorePct(ctx_r1.MatchThreshold), "%");
    i0.ɵɵadvance();
    i0.ɵɵstyleProp("left", ctx_r1.ScorePct(ctx_r1.MatchThreshold), "%");
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1("Match ", ctx_r1.FormatScore(ctx_r1.MatchThreshold));
    i0.ɵɵadvance();
    i0.ɵɵstyleProp("left", ctx_r1.ScorePct(ctx_r1.Selected.BestMatchScore), "%");
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(ctx_r1.FormatScore(ctx_r1.Selected.BestMatchScore));
} }
function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template(rf, ctx) { if (rf & 1) {
    const _r9 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 33)(1, "div")(2, "div", 34);
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "h4", 35);
    i0.ɵɵtext(5);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(6, "span", 36);
    i0.ɵɵelement(7, "i", 37);
    i0.ɵɵtext(8);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(9, "div", 38)(10, "div", 39);
    i0.ɵɵtext(11, "Proposed parent");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(12, "div", 40);
    i0.ɵɵtext(13);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(14, "div", 39);
    i0.ɵɵtext(15, "Best match");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(16, "div", 40);
    i0.ɵɵconditionalCreate(17, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_17_Template, 3, 1)(18, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_18_Template, 2, 0, "span", 41);
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(19, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_19_Template, 4, 1);
    i0.ɵɵconditionalCreate(20, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_20_Template, 4, 1);
    i0.ɵɵelementEnd();
    i0.ɵɵconditionalCreate(21, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Conditional_21_Template, 19, 13, "div", 42);
    i0.ɵɵelementStart(22, "div", 43)(23, "label", 44);
    i0.ɵɵtext(24, "Merge target");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(25, "mj-combobox", 45);
    i0.ɵɵlistener("ValueChange", function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template_mj_combobox_ValueChange_25_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.OnMergeTargetChange($event)); });
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(26, "div", 46)(27, "label", 44);
    i0.ɵɵtext(28, "Reviewer note (optional)");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(29, "textarea", 47);
    i0.ɵɵtwoWayListener("ngModelChange", function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template_textarea_ngModelChange_29_listener($event) { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); i0.ɵɵtwoWayBindingSet(ctx_r1.ReviewerNotes, $event) || (ctx_r1.ReviewerNotes = $event); return i0.ɵɵresetView($event); });
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(30, "div", 48)(31, "button", 49);
    i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template_button_click_31_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.MergeIntoExisting()); });
    i0.ɵɵelement(32, "i", 50);
    i0.ɵɵtext(33);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(34, "button", 51);
    i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template_button_click_34_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.ApproveAsNewTag()); });
    i0.ɵɵelement(35, "i", 52);
    i0.ɵɵtext(36, " Approve as new tag ");
    i0.ɵɵelementEnd();
    i0.ɵɵelement(37, "span", 53);
    i0.ɵɵelementStart(38, "button", 54);
    i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template_button_click_38_listener() { i0.ɵɵrestoreView(_r9); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.Reject()); });
    i0.ɵɵelement(39, "i", 55);
    i0.ɵɵtext(40, " Reject ");
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate1(" Source \u00B7 ", ctx_r1.Selected.SourceContentSource ?? "Unknown source", " ");
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1("\"", ctx_r1.Selected.ProposedName, "\"");
    i0.ɵɵadvance();
    i0.ɵɵclassMap("ci-pill-" + ctx_r1.ReasonPill(ctx_r1.Selected.Reason));
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1(" ", ctx_r1.ReasonLabel(ctx_r1.Selected.Reason), " ");
    i0.ɵɵadvance(5);
    i0.ɵɵtextInterpolate(ctx_r1.Selected.ProposedParent ?? "\u2014 (root)");
    i0.ɵɵadvance(4);
    i0.ɵɵconditional(ctx_r1.Selected.BestMatchTag ? 17 : 18);
    i0.ɵɵadvance(2);
    i0.ɵɵconditional(ctx_r1.Selected.SourceContentItem ? 19 : -1);
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r1.Selected.SourceText ? 20 : -1);
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r1.Selected.BestMatchScore != null ? 21 : -1);
    i0.ɵɵadvance(4);
    i0.ɵɵproperty("Data", ctx_r1.TagOptions)("ValuePrimitive", true)("Filterable", true)("ngModel", ctx_r1.MergeTargetID);
    i0.ɵɵadvance(4);
    i0.ɵɵtwoWayProperty("ngModel", ctx_r1.ReviewerNotes);
    i0.ɵɵadvance(2);
    i0.ɵɵproperty("disabled", ctx_r1.IsActing || !ctx_r1.MergeTargetID);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate1(" Merge into \"", ctx_r1.MergeTargetLabel || "\u2026", "\" ");
    i0.ɵɵadvance();
    i0.ɵɵproperty("disabled", ctx_r1.IsActing);
    i0.ɵɵadvance(4);
    i0.ɵɵproperty("disabled", ctx_r1.IsActing);
} }
function ClassifyInboxTabComponent_Conditional_12_Template(rf, ctx) { if (rf & 1) {
    const _r1 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 9)(1, "div", 14)(2, "h5");
    i0.ɵɵtext(3, "By reason");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(4, "a", 15);
    i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Template_a_click_4_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.SetReasonFilter("")); });
    i0.ɵɵtext(5, " All ");
    i0.ɵɵelementStart(6, "span", 16);
    i0.ɵɵtext(7);
    i0.ɵɵelementEnd()();
    i0.ɵɵrepeaterCreate(8, ClassifyInboxTabComponent_Conditional_12_For_9_Template, 4, 4, "a", 17, _forTrack0);
    i0.ɵɵelementStart(10, "h5", 18);
    i0.ɵɵtext(11, "Status");
    i0.ɵɵelementEnd();
    i0.ɵɵrepeaterCreate(12, ClassifyInboxTabComponent_Conditional_12_For_13_Template, 2, 3, "a", 17, i0.ɵɵrepeaterTrackByIdentity);
    i0.ɵɵelementStart(14, "h5", 18);
    i0.ɵɵtext(15, "Scope");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(16, "a", 15);
    i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Conditional_12_Template_a_click_16_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.ToggleHealthReasons()); });
    i0.ɵɵelementStart(17, "span");
    i0.ɵɵelement(18, "i", 19);
    i0.ɵɵtext(19, " Include health reasons");
    i0.ɵɵelementEnd();
    i0.ɵɵelement(20, "i", 20);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(21, "div", 21);
    i0.ɵɵconditionalCreate(22, ClassifyInboxTabComponent_Conditional_12_Conditional_22_Template, 1, 1, "mj-empty-state", 22)(23, ClassifyInboxTabComponent_Conditional_12_Conditional_23_Template, 2, 0);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(24, "div", 23);
    i0.ɵɵconditionalCreate(25, ClassifyInboxTabComponent_Conditional_12_Conditional_25_Template, 1, 0, "mj-empty-state", 24)(26, ClassifyInboxTabComponent_Conditional_12_Conditional_26_Template, 41, 19);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r1 = i0.ɵɵnextContext();
    i0.ɵɵadvance(4);
    i0.ɵɵclassProp("ci-active", ctx_r1.ReasonFilter === "");
    i0.ɵɵadvance(3);
    i0.ɵɵtextInterpolate(ctx_r1.TotalLoadedCount);
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r1.ReasonCounts);
    i0.ɵɵadvance(4);
    i0.ɵɵrepeater(ctx_r1.StatusOptions);
    i0.ɵɵadvance(4);
    i0.ɵɵclassProp("ci-active", ctx_r1.IncludeHealthReasons);
    i0.ɵɵadvance(4);
    i0.ɵɵclassProp("fa-toggle-on", ctx_r1.IncludeHealthReasons)("fa-toggle-off", !ctx_r1.IncludeHealthReasons);
    i0.ɵɵadvance(2);
    i0.ɵɵconditional(ctx_r1.FilteredSuggestions.length === 0 ? 22 : 23);
    i0.ɵɵadvance(3);
    i0.ɵɵconditional(!ctx_r1.Selected ? 25 : 26);
} }
/** Reasons owned by the Health tab — excluded from the Inbox default view. */
const HEALTH_REASONS = ['MergeCandidate', 'LowUsage', 'WideNode'];
/** Human-readable labels + pill class for each Reason value. */
const REASON_META = {
    ConstrainedMode: { label: 'Constrained mode', pill: 'gray' },
    BelowThreshold: { label: 'Below threshold', pill: 'amber' },
    ParentFrozen: { label: 'Parent frozen', pill: 'red' },
    AutoGrowDisabled: { label: 'Auto-grow disabled', pill: 'gray' },
    MaxChildrenExceeded: { label: 'Max children', pill: 'red' },
    MaxDepthExceeded: { label: 'Max depth', pill: 'red' },
    BelowMinWeight: { label: 'Below min weight', pill: 'amber' },
    RequiresReview: { label: 'Requires review', pill: 'amber' },
    MergeCandidate: { label: 'Merge candidate', pill: 'blue' },
    LowUsage: { label: 'Low usage', pill: 'gray' },
    WideNode: { label: 'Wide node', pill: 'blue' },
};
export class ClassifyInboxTabComponent extends BaseAngularComponent {
    cdr = inject(ChangeDetectorRef);
    /** Threshold markers shown on the band gradient (match the server defaults). */
    SuggestThreshold = 0.70;
    MatchThreshold = 0.87;
    // ── Loaded data (NOT cached — transactional) ──
    allSuggestions = [];
    FilteredSuggestions = [];
    ReasonCounts = [];
    Selected = null;
    IsLoading = false;
    hasLoaded = false;
    // ── Filters ──
    StatusFilter = 'Pending';
    StatusOptions = ['Pending', 'Approved', 'Merged', 'Rejected'];
    /** Active reason filter; '' = all (human-review reasons), 'all' = include health reasons. */
    ReasonFilter = '';
    /** When true, include the 3 Health-owned reasons that the Health tab normally owns. */
    IncludeHealthReasons = false;
    // ── Merge-target state ──
    TagOptions = [];
    /** Selected merge-target tag ID (defaults to BestMatchTagID on selection). */
    MergeTargetID = null;
    ReviewerNotes = '';
    IsActing = false;
    /** Number of Pending suggestions currently in the loaded set (for the host badge). */
    get PendingCount() {
        return this.StatusFilter === 'Pending' ? this.allSuggestions.length : 0;
    }
    /** Empty-state message for the suggestion list (reflects the active filters). */
    get NoSuggestionsMessage() {
        const status = this.StatusFilter.toLowerCase();
        return `No ${status} suggestions${this.ReasonFilter ? ' for this reason' : ''}.`;
    }
    /** Total loaded suggestions (across all reasons) for the "All" filter count. */
    get TotalLoadedCount() {
        return this.allSuggestions.length;
    }
    /** Template-facing formatter. */
    formatShortDate = formatShortDate;
    /** Emitted after any Approve/Merge/Reject so the host refreshes its pending badge. */
    Resolved = new EventEmitter();
    // ════════════════════════════════════════════
    // ACTIVATION + LOAD
    // ════════════════════════════════════════════
    /** Lazy-load on first activation (host calls this when the tab becomes active). */
    async EnsureLoaded() {
        if (this.hasLoaded)
            return;
        this.hasLoaded = true;
        await Promise.all([this.loadSuggestions(), this.loadTagOptions()]);
    }
    /** Public refresh — re-pull suggestions for the current status filter. */
    async Refresh() {
        await this.loadSuggestions();
    }
    buildStatusFilterClause() {
        // Health-reason suggestions (MergeCandidate / LowUsage / WideNode) are owned
        // by the Health tab. By default the Inbox shows only the human-review reasons
        // and EXCLUDES the 3 health reasons; the "include health reasons" toggle lifts
        // that exclusion so an operator can see everything in one place.
        const statusClause = `Status='${this.StatusFilter}'`;
        if (this.IncludeHealthReasons)
            return statusClause;
        const excluded = HEALTH_REASONS.map(r => `'${r}'`).join(',');
        return `${statusClause} AND Reason NOT IN (${excluded})`;
    }
    async loadSuggestions() {
        this.IsLoading = true;
        this.cdr.detectChanges();
        const rv = RunView.FromMetadataProvider(this.ProviderToUse);
        const result = await rv.RunView({
            EntityName: 'MJ: Tag Suggestions',
            ExtraFilter: this.buildStatusFilterClause(),
            OrderBy: '__mj_CreatedAt DESC',
            ResultType: 'entity_object',
        }, this.ProviderToUse.CurrentUser);
        this.allSuggestions = result.Success ? result.Results : [];
        this.buildReasonCounts();
        this.applyReasonFilter();
        this.IsLoading = false;
        this.cdr.detectChanges();
    }
    async loadTagOptions() {
        await TagEngineBase.Instance.Config(false, this.ProviderToUse.CurrentUser, this.ProviderToUse);
        this.TagOptions = TagEngineBase.Instance.Tags
            .filter(t => t.Status === 'Active')
            .map(t => ({ ID: t.ID, Label: t.DisplayName || t.Name }))
            .sort((a, b) => a.Label.localeCompare(b.Label));
    }
    // ════════════════════════════════════════════
    // FILTERING
    // ════════════════════════════════════════════
    buildReasonCounts() {
        const counts = new Map();
        for (const s of this.allSuggestions) {
            counts.set(s.Reason, (counts.get(s.Reason) ?? 0) + 1);
        }
        this.ReasonCounts = Array.from(counts.entries())
            .map(([Reason, Count]) => ({ Reason, Label: this.ReasonLabel(Reason), Count }))
            .sort((a, b) => b.Count - a.Count);
    }
    applyReasonFilter() {
        this.FilteredSuggestions = this.ReasonFilter
            ? this.allSuggestions.filter(s => s.Reason === this.ReasonFilter)
            : this.allSuggestions;
        // Keep selection valid; otherwise select the first row.
        if (!this.Selected || !this.FilteredSuggestions.some(s => UUIDsEqual(s.ID, this.Selected.ID))) {
            this.SelectSuggestion(this.FilteredSuggestions[0] ?? null);
        }
    }
    SetReasonFilter(reason) {
        this.ReasonFilter = reason;
        this.applyReasonFilter();
        this.cdr.detectChanges();
    }
    async SetStatusFilter(status) {
        if (status === this.StatusFilter)
            return;
        this.StatusFilter = status;
        this.ReasonFilter = '';
        this.Selected = null;
        await this.loadSuggestions();
    }
    async ToggleHealthReasons() {
        this.IncludeHealthReasons = !this.IncludeHealthReasons;
        this.ReasonFilter = '';
        await this.loadSuggestions();
    }
    SelectSuggestion(suggestion) {
        this.Selected = suggestion;
        this.MergeTargetID = suggestion?.BestMatchTagID ?? null;
        this.ReviewerNotes = '';
        this.cdr.detectChanges();
    }
    OnMergeTargetChange(value) {
        this.MergeTargetID = value ?? null;
    }
    // ════════════════════════════════════════════
    // DISPLAY HELPERS
    // ════════════════════════════════════════════
    ReasonLabel(reason) {
        return REASON_META[reason]?.label ?? reason;
    }
    ReasonPill(reason) {
        return REASON_META[reason]?.pill ?? 'gray';
    }
    /** Score as a 0..100 percent for band/marker positioning. */
    ScorePct(score) {
        if (score == null)
            return 0;
        return Math.round(Math.min(1, Math.max(0, score)) * 100);
    }
    FormatScore(score) {
        return score == null ? '—' : score.toFixed(2);
    }
    /** Resolve the merge-target tag's display label for confirmation copy. */
    get MergeTargetLabel() {
        if (!this.MergeTargetID)
            return '';
        return this.TagOptions.find(t => UUIDsEqual(t.ID, this.MergeTargetID))?.Label ?? 'selected tag';
    }
    // ════════════════════════════════════════════
    // ACTIONS — entity-level mutations on the client
    // ════════════════════════════════════════════
    //
    // NOTE: full content-item-tag re-pointing (moving every ContentItemTag from the
    // suggested name onto the resolved tag) is handled by the server-side promotion
    // job. This UI performs the CORE promotion: it creates/links the tag and stamps
    // the suggestion's Status / ResolvedTagID / reviewer fields. The server-only
    // TagGovernanceEngine is intentionally NOT used here (it is server-side).
    stampReviewFields(suggestion) {
        suggestion.ReviewedByUserID = this.ProviderToUse.CurrentUser.ID;
        suggestion.ReviewedAt = new Date();
        if (this.ReviewerNotes.trim()) {
            suggestion.ReviewerNotes = this.ReviewerNotes.trim();
        }
    }
    /** Approve as a brand-new tag: create the MJTagEntity, then resolve the suggestion. */
    async ApproveAsNewTag() {
        const suggestion = this.Selected;
        if (!suggestion || this.IsActing)
            return;
        this.IsActing = true;
        this.cdr.detectChanges();
        try {
            const p = this.ProviderToUse;
            const tag = await p.GetEntityObject('MJ: Tags', p.CurrentUser);
            tag.NewRecord();
            tag.Name = suggestion.ProposedName;
            tag.DisplayName = suggestion.ProposedName;
            tag.ParentID = suggestion.ProposedParentID;
            const tagSaved = await tag.Save();
            if (!tagSaved) {
                this.notifyFailure('Failed to create tag', tag.LatestResult?.CompleteMessage);
                return;
            }
            this.stampReviewFields(suggestion);
            suggestion.Status = 'Approved';
            suggestion.ResolvedTagID = tag.ID;
            const sugSaved = await suggestion.Save();
            if (!sugSaved) {
                this.notifyFailure('Tag created but failed to resolve suggestion', suggestion.LatestResult?.CompleteMessage);
                return;
            }
            MJNotificationService.Instance.CreateSimpleNotification(`Approved "${suggestion.ProposedName}" as a new tag`, 'success', 3000);
            this.finishAction(suggestion);
        }
        catch (error) {
            this.notifyError(error);
        }
        finally {
            this.IsActing = false;
            this.cdr.detectChanges();
        }
    }
    /** Merge into an existing tag (default target = BestMatchTagID, override via dropdown). */
    async MergeIntoExisting() {
        const suggestion = this.Selected;
        if (!suggestion || this.IsActing)
            return;
        if (!this.MergeTargetID) {
            MJNotificationService.Instance.CreateSimpleNotification('Select a tag to merge into first', 'warning', 3000);
            return;
        }
        this.IsActing = true;
        this.cdr.detectChanges();
        try {
            this.stampReviewFields(suggestion);
            suggestion.Status = 'Merged';
            suggestion.ResolvedTagID = this.MergeTargetID;
            const saved = await suggestion.Save();
            if (!saved) {
                this.notifyFailure('Failed to merge suggestion', suggestion.LatestResult?.CompleteMessage);
                return;
            }
            MJNotificationService.Instance.CreateSimpleNotification(`Merged "${suggestion.ProposedName}" into "${this.MergeTargetLabel}"`, 'success', 3000);
            this.finishAction(suggestion);
        }
        catch (error) {
            this.notifyError(error);
        }
        finally {
            this.IsActing = false;
            this.cdr.detectChanges();
        }
    }
    /** Reject the suggestion. */
    async Reject() {
        const suggestion = this.Selected;
        if (!suggestion || this.IsActing)
            return;
        this.IsActing = true;
        this.cdr.detectChanges();
        try {
            this.stampReviewFields(suggestion);
            suggestion.Status = 'Rejected';
            const saved = await suggestion.Save();
            if (!saved) {
                this.notifyFailure('Failed to reject suggestion', suggestion.LatestResult?.CompleteMessage);
                return;
            }
            MJNotificationService.Instance.CreateSimpleNotification(`Rejected "${suggestion.ProposedName}"`, 'success', 2500);
            this.finishAction(suggestion);
        }
        catch (error) {
            this.notifyError(error);
        }
        finally {
            this.IsActing = false;
            this.cdr.detectChanges();
        }
    }
    /** Remove a resolved row, advance selection, rebuild counts, notify the host. */
    finishAction(resolved) {
        const idx = this.FilteredSuggestions.findIndex(s => UUIDsEqual(s.ID, resolved.ID));
        this.allSuggestions = this.allSuggestions.filter(s => !UUIDsEqual(s.ID, resolved.ID));
        this.buildReasonCounts();
        this.applyReasonFilterAfterRemoval(idx);
        this.Resolved.emit();
        this.cdr.detectChanges();
    }
    /** Rebuild the filtered list and advance selection to the next sensible row. */
    applyReasonFilterAfterRemoval(removedIndex) {
        this.FilteredSuggestions = this.ReasonFilter
            ? this.allSuggestions.filter(s => s.Reason === this.ReasonFilter)
            : this.allSuggestions;
        const next = this.FilteredSuggestions[removedIndex] ?? this.FilteredSuggestions[removedIndex - 1] ?? null;
        this.SelectSuggestion(next);
    }
    notifyFailure(prefix, detail) {
        MJNotificationService.Instance.CreateSimpleNotification(`${prefix}: ${detail ?? 'unknown error'}`, 'error', 5000);
    }
    notifyError(error) {
        const msg = error instanceof Error ? error.message : String(error);
        MJNotificationService.Instance.CreateSimpleNotification(`Error: ${msg}`, 'error', 5000);
    }
    static ɵfac = /*@__PURE__*/ (() => { let ɵClassifyInboxTabComponent_BaseFactory; return function ClassifyInboxTabComponent_Factory(__ngFactoryType__) { return (ɵClassifyInboxTabComponent_BaseFactory || (ɵClassifyInboxTabComponent_BaseFactory = i0.ɵɵgetInheritedFactory(ClassifyInboxTabComponent)))(__ngFactoryType__ || ClassifyInboxTabComponent); }; })();
    static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ClassifyInboxTabComponent, selectors: [["classify-inbox-tab"]], outputs: { Resolved: "Resolved" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 13, vars: 8, consts: [["Title", "Suggestions Inbox", "Subtitle", "Review classifications that landed in the ambiguous band"], ["meta", ""], [1, "ci-status-pill"], [1, "fa-solid", "fa-inbox"], ["actions", ""], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click", "disabled"], [3, "Padding", "Flex"], [1, "at-main-area"], [1, "at-page-body"], [1, "ci-inbox"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "mj-action-label"], [1, "fa-solid", "fa-arrows-rotate"], ["text", "Loading suggestions\u2026"], [1, "ci-col", "ci-filter"], [1, "ci-filter-link", 3, "click"], [1, "ci-n"], [1, "ci-filter-link", 3, "ci-active"], [1, "ci-section-gap"], [1, "fa-solid", "fa-heart-pulse"], [1, "fa-solid"], [1, "ci-col", "ci-list"], ["Variant", "success", "Size", "compact", 3, "Title"], [1, "ci-col", "ci-read"], ["Icon", "fa-solid fa-hand-pointer", "Title", "Select a suggestion to review it.", 1, "at-fill"], [1, "ci-row", 3, "ci-sel"], [1, "ci-row", 3, "click"], [1, "ci-row-top"], [1, "ci-row-name"], [1, "ci-row-ago"], [1, "ci-row-reason"], [1, "ci-pill"], [1, "ci-row-match"], [1, "ci-read-head"], [1, "ci-read-source"], [1, "ci-read-title"], [1, "ci-pill", "ci-pill-lg"], [1, "fa-solid", "fa-triangle-exclamation"], [1, "ci-kv"], [1, "ci-k"], [1, "ci-v"], [1, "ci-muted"], [1, "ci-band"], [1, "ci-merge-picker"], [1, "ci-merge-label"], ["TextField", "Label", "ValueField", "ID", "Placeholder", "Choose a tag to merge into\u2026", 3, "ValueChange", "Data", "ValuePrimitive", "Filterable", "ngModel"], [1, "ci-note"], ["rows", "2", "placeholder", "Why this decision\u2026", 1, "mj-textarea", "ci-note-input", 3, "ngModelChange", "ngModel"], [1, "ci-actbar"], ["mjButton", "", "variant", "success", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-code-merge"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-plus"], [1, "ci-actbar-spacer"], ["mjButton", "", "variant", "danger", "size", "sm", 3, "click", "disabled"], [1, "fa-solid", "fa-xmark"], [1, "ci-v", "ci-link"], [1, "ci-v", "ci-source-text"], [1, "ci-bandbar"], [1, "ci-bandmark"], [1, "ci-bandmark-label"], [1, "ci-bandscore"], [1, "ci-bandlabels"]], template: function ClassifyInboxTabComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵelementStart(0, "mj-page-header-interior", 0)(1, "div", 1)(2, "span", 2);
            i0.ɵɵelement(3, "i", 3);
            i0.ɵɵtext(4);
            i0.ɵɵelementEnd()();
            i0.ɵɵelementStart(5, "div", 4)(6, "button", 5);
            i0.ɵɵlistener("click", function ClassifyInboxTabComponent_Template_button_click_6_listener() { return ctx.Refresh(); });
            i0.ɵɵconditionalCreate(7, ClassifyInboxTabComponent_Conditional_7_Template, 3, 0)(8, ClassifyInboxTabComponent_Conditional_8_Template, 3, 0);
            i0.ɵɵelementEnd()()();
            i0.ɵɵelementStart(9, "mj-page-body-interior", 6)(10, "div", 7);
            i0.ɵɵconditionalCreate(11, ClassifyInboxTabComponent_Conditional_11_Template, 2, 0, "div", 8)(12, ClassifyInboxTabComponent_Conditional_12_Template, 27, 11, "div", 9);
            i0.ɵɵelementEnd()();
        } if (rf & 2) {
            i0.ɵɵadvance(2);
            i0.ɵɵclassProp("ci-status-pill-active", ctx.PendingCount > 0);
            i0.ɵɵadvance(2);
            i0.ɵɵtextInterpolate1(" ", ctx.PendingCount, " pending ");
            i0.ɵɵadvance(2);
            i0.ɵɵproperty("disabled", ctx.IsLoading);
            i0.ɵɵadvance();
            i0.ɵɵconditional(ctx.IsLoading ? 7 : 8);
            i0.ɵɵadvance(2);
            i0.ɵɵproperty("Padding", false)("Flex", true);
            i0.ɵɵadvance(2);
            i0.ɵɵconditional(ctx.IsLoading ? 11 : 12);
        } }, dependencies: [i1.DefaultValueAccessor, i1.NgControlStatus, i1.NgModel, i2.LoadingComponent, i3.MJButtonDirective, i3.MJComboboxComponent, i3.MJPageHeaderInteriorComponent, i3.MJPageBodyInteriorComponent, i3.MJEmptyStateComponent], styles: ["\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n.ci-inbox[_ngcontent-%COMP%] {\n    display: grid;\n    grid-template-columns: 180px 320px 1fr;\n    border: 1px solid var(--mj-border-default);\n    border-radius: 12px;\n    overflow: hidden;\n    min-height: 460px;\n    margin: 12px;\n    background: var(--mj-bg-surface);\n}\n\n.ci-col[_ngcontent-%COMP%] {\n    border-right: 1px solid var(--mj-border-default);\n    overflow: auto;\n}\n.ci-col[_ngcontent-%COMP%]:last-child {\n    border-right: 0;\n}\n\n\n\n.ci-filter[_ngcontent-%COMP%] {\n    padding: 12px;\n    background: var(--mj-bg-surface-card);\n}\n.ci-filter[_ngcontent-%COMP%]   h5[_ngcontent-%COMP%] {\n    font-size: 11px;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    color: var(--mj-text-muted);\n    margin: 0 0 8px;\n}\n.ci-section-gap[_ngcontent-%COMP%] {\n    margin-top: 14px;\n}\n.ci-filter-link[_ngcontent-%COMP%] {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    gap: 8px;\n    padding: 7px 9px;\n    border-radius: 7px;\n    color: var(--mj-text-secondary);\n    font-size: 12.5px;\n    font-weight: 600;\n    cursor: pointer;\n    margin-bottom: 2px;\n}\n.ci-filter-link[_ngcontent-%COMP%]:hover {\n    background: var(--mj-bg-surface-hover);\n}\n.ci-filter-link.ci-active[_ngcontent-%COMP%] {\n    background: var(--mj-bg-surface);\n    box-shadow: inset 0 0 0 1px var(--mj-border-default);\n    color: var(--mj-text-primary);\n}\n.ci-n[_ngcontent-%COMP%] {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n\n\n.ci-list[_ngcontent-%COMP%] {\n    background: var(--mj-bg-surface);\n}\n.ci-row[_ngcontent-%COMP%] {\n    padding: 11px 13px;\n    border-bottom: 1px solid var(--mj-border-subtle);\n    cursor: pointer;\n}\n.ci-row[_ngcontent-%COMP%]:hover {\n    background: var(--mj-bg-surface-hover);\n}\n.ci-row.ci-sel[_ngcontent-%COMP%] {\n    background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n    box-shadow: inset 3px 0 0 var(--mj-brand-primary);\n}\n.ci-row-top[_ngcontent-%COMP%] {\n    display: flex;\n    justify-content: space-between;\n    gap: 8px;\n}\n.ci-row-name[_ngcontent-%COMP%] {\n    font-weight: 700;\n    font-size: 13px;\n    color: var(--mj-text-primary);\n}\n.ci-row-ago[_ngcontent-%COMP%] {\n    font-size: 10.5px;\n    color: var(--mj-text-muted);\n    white-space: nowrap;\n}\n.ci-row-reason[_ngcontent-%COMP%] {\n    font-size: 11px;\n    color: var(--mj-text-secondary);\n    margin-top: 4px;\n    display: flex;\n    align-items: center;\n    gap: 6px;\n    flex-wrap: wrap;\n}\n.ci-row-match[_ngcontent-%COMP%]   b[_ngcontent-%COMP%] {\n    color: var(--mj-text-primary);\n}\n\n\n\n.ci-read[_ngcontent-%COMP%] {\n    padding: 18px 20px;\n}\n.ci-read-head[_ngcontent-%COMP%] {\n    display: flex;\n    justify-content: space-between;\n    align-items: flex-start;\n    gap: 12px;\n}\n.ci-read-source[_ngcontent-%COMP%] {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n    font-family: var(--mj-font-mono, monospace);\n}\n.ci-read-title[_ngcontent-%COMP%] {\n    font-size: 17px;\n    margin: 4px 0 0;\n    color: var(--mj-text-primary);\n}\n.ci-kv[_ngcontent-%COMP%] {\n    display: grid;\n    grid-template-columns: 130px 1fr;\n    gap: 7px 12px;\n    margin: 16px 0;\n    font-size: 13px;\n}\n.ci-k[_ngcontent-%COMP%] {\n    color: var(--mj-text-muted);\n}\n.ci-v[_ngcontent-%COMP%] {\n    font-weight: 600;\n    color: var(--mj-text-primary);\n}\n.ci-muted[_ngcontent-%COMP%] {\n    color: var(--mj-text-muted);\n    font-weight: 400;\n}\n.ci-link[_ngcontent-%COMP%] {\n    color: var(--mj-text-link);\n}\n.ci-source-text[_ngcontent-%COMP%] {\n    font-weight: 400;\n    color: var(--mj-text-secondary);\n    max-height: 80px;\n    overflow: auto;\n    white-space: pre-wrap;\n}\n\n\n\n.ci-band[_ngcontent-%COMP%] {\n    margin: 18px 0;\n    background: var(--mj-bg-surface-card);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 10px;\n    padding: 14px;\n}\n.ci-band[_ngcontent-%COMP%]   h5[_ngcontent-%COMP%] {\n    font-size: 11px;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    color: var(--mj-text-muted);\n    margin: 0 0 30px;\n}\n.ci-bandbar[_ngcontent-%COMP%] {\n    position: relative;\n    height: 10px;\n    border-radius: 6px;\n    \n\n    background: linear-gradient(90deg,\n        color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface)) 0%,\n        color-mix(in srgb, var(--mj-status-warning) 30%, var(--mj-bg-surface)) 55%,\n        color-mix(in srgb, var(--mj-status-success) 30%, var(--mj-bg-surface)) 78%,\n        color-mix(in srgb, var(--mj-status-success) 45%, var(--mj-bg-surface)) 100%);\n}\n.ci-bandmark[_ngcontent-%COMP%] {\n    position: absolute;\n    top: -6px;\n    width: 2px;\n    height: 22px;\n    background: var(--mj-text-primary);\n    transform: translateX(-50%);\n}\n.ci-bandmark-label[_ngcontent-%COMP%] {\n    position: absolute;\n    top: -20px;\n    transform: translateX(-50%);\n    font-size: 9px;\n    color: var(--mj-text-muted);\n    white-space: nowrap;\n}\n.ci-bandscore[_ngcontent-%COMP%] {\n    position: absolute;\n    top: -30px;\n    transform: translateX(-50%);\n    font-size: 11px;\n    font-weight: 800;\n    background: var(--mj-text-primary);\n    color: var(--mj-text-inverse);\n    padding: 2px 7px;\n    border-radius: 6px;\n}\n.ci-bandlabels[_ngcontent-%COMP%] {\n    display: flex;\n    justify-content: space-between;\n    margin-top: 9px;\n    font-size: 10.5px;\n    color: var(--mj-text-muted);\n}\n\n\n\n.ci-merge-picker[_ngcontent-%COMP%], \n.ci-note[_ngcontent-%COMP%] {\n    margin: 14px 0;\n}\n.ci-merge-label[_ngcontent-%COMP%] {\n    display: block;\n    font-size: 11px;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    color: var(--mj-text-muted);\n    margin-bottom: 6px;\n}\n.ci-note-input[_ngcontent-%COMP%] {\n    width: 100%;\n    resize: vertical;\n}\n\n\n\n.ci-actbar[_ngcontent-%COMP%] {\n    display: flex;\n    align-items: center;\n    gap: 9px;\n    margin-top: 16px;\n    padding-top: 16px;\n    border-top: 1px solid var(--mj-border-default);\n}\n.ci-actbar-spacer[_ngcontent-%COMP%] {\n    flex: 1;\n}\n\n\n\n.ci-pill[_ngcontent-%COMP%] {\n    display: inline-flex;\n    align-items: center;\n    gap: 4px;\n    font-size: 10px;\n    font-weight: 700;\n    padding: 2px 8px;\n    border-radius: 999px;\n    white-space: nowrap;\n}\n.ci-pill-lg[_ngcontent-%COMP%] {\n    font-size: 12px;\n    padding: 4px 12px;\n}\n.ci-pill-gray[_ngcontent-%COMP%] {\n    background: var(--mj-bg-surface-sunken);\n    color: var(--mj-text-secondary);\n}\n.ci-pill-amber[_ngcontent-%COMP%] {\n    background: var(--mj-status-warning-bg);\n    color: var(--mj-status-warning-text);\n}\n.ci-pill-red[_ngcontent-%COMP%] {\n    background: var(--mj-status-error-bg);\n    color: var(--mj-status-error-text);\n}\n.ci-pill-blue[_ngcontent-%COMP%] {\n    background: var(--mj-status-info-bg);\n    color: var(--mj-status-info-text);\n}\n\n\n\n.ci-status-pill[_ngcontent-%COMP%] {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    font-size: 12px;\n    font-weight: 600;\n    padding: 3px 10px;\n    border-radius: 999px;\n    background: var(--mj-bg-surface-sunken);\n    color: var(--mj-text-secondary);\n}\n.ci-status-pill-active[_ngcontent-%COMP%] {\n    background: var(--mj-status-warning-bg);\n    color: var(--mj-status-warning-text);\n}"] });
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ClassifyInboxTabComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'classify-inbox-tab', template: "<mj-page-header-interior\n    Title=\"Suggestions Inbox\"\n    Subtitle=\"Review classifications that landed in the ambiguous band\">\n  <div meta>\n    <span class=\"ci-status-pill\" [class.ci-status-pill-active]=\"PendingCount > 0\">\n      <i class=\"fa-solid fa-inbox\"></i>\n      {{ PendingCount }} pending\n    </span>\n  </div>\n  <div actions>\n    <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"Refresh()\" [disabled]=\"IsLoading\">\n      @if (IsLoading) {\n        <i class=\"fa-solid fa-spinner fa-spin\"></i> <span class=\"mj-action-label\">Refreshing\u2026</span>\n      } @else {\n        <i class=\"fa-solid fa-arrows-rotate\"></i> <span class=\"mj-action-label\">Refresh</span>\n      }\n    </button>\n  </div>\n</mj-page-header-interior>\n\n<mj-page-body-interior [Padding]=\"false\" [Flex]=\"true\">\n  <div class=\"at-main-area\">\n    @if (IsLoading) {\n      <div class=\"at-page-body\">\n        <mj-loading text=\"Loading suggestions\u2026\"></mj-loading>\n      </div>\n    } @else {\n      <div class=\"ci-inbox\">\n\n        <!-- \u2500\u2500 (1) FILTER RAIL \u2500\u2500 -->\n        <div class=\"ci-col ci-filter\">\n          <h5>By reason</h5>\n          <a class=\"ci-filter-link\" [class.ci-active]=\"ReasonFilter === ''\" (click)=\"SetReasonFilter('')\">\n            All <span class=\"ci-n\">{{ TotalLoadedCount }}</span>\n          </a>\n          @for (rc of ReasonCounts; track rc.Reason) {\n            <a class=\"ci-filter-link\" [class.ci-active]=\"ReasonFilter === rc.Reason\" (click)=\"SetReasonFilter(rc.Reason)\">\n              {{ rc.Label }} <span class=\"ci-n\">{{ rc.Count }}</span>\n            </a>\n          }\n\n          <h5 class=\"ci-section-gap\">Status</h5>\n          @for (st of StatusOptions; track st) {\n            <a class=\"ci-filter-link\" [class.ci-active]=\"StatusFilter === st\" (click)=\"SetStatusFilter(st)\">\n              {{ st }}\n            </a>\n          }\n\n          <h5 class=\"ci-section-gap\">Scope</h5>\n          <a class=\"ci-filter-link\" [class.ci-active]=\"IncludeHealthReasons\" (click)=\"ToggleHealthReasons()\">\n            <span><i class=\"fa-solid fa-heart-pulse\"></i> Include health reasons</span>\n            <i class=\"fa-solid\" [class.fa-toggle-on]=\"IncludeHealthReasons\" [class.fa-toggle-off]=\"!IncludeHealthReasons\"></i>\n          </a>\n        </div>\n\n        <!-- \u2500\u2500 (2) SUGGESTION LIST \u2500\u2500 -->\n        <div class=\"ci-col ci-list\">\n          @if (FilteredSuggestions.length === 0) {\n            <mj-empty-state Variant=\"success\" Size=\"compact\"\n              [Title]=\"NoSuggestionsMessage\" />\n          } @else {\n            @for (s of FilteredSuggestions; track s.ID) {\n              <div class=\"ci-row\" [class.ci-sel]=\"Selected?.ID === s.ID\" (click)=\"SelectSuggestion(s)\">\n                <div class=\"ci-row-top\">\n                  <span class=\"ci-row-name\">\"{{ s.ProposedName }}\"</span>\n                  <span class=\"ci-row-ago\">{{ formatShortDate(s.__mj_CreatedAt + '') }}</span>\n                </div>\n                <div class=\"ci-row-reason\">\n                  <span class=\"ci-pill\" [class]=\"'ci-pill-' + ReasonPill(s.Reason)\">{{ ReasonLabel(s.Reason) }}</span>\n                  @if (s.BestMatchTag) {\n                    <span class=\"ci-row-match\">\u2248 <b>{{ s.BestMatchTag }}</b> \u00B7 {{ FormatScore(s.BestMatchScore) }}</span>\n                  }\n                </div>\n              </div>\n            }\n          }\n        </div>\n\n        <!-- \u2500\u2500 (3) READING PANE \u2500\u2500 -->\n        <div class=\"ci-col ci-read\">\n          @if (!Selected) {\n            <mj-empty-state class=\"at-fill\" Icon=\"fa-solid fa-hand-pointer\"\n              Title=\"Select a suggestion to review it.\" />\n          } @else {\n            <div class=\"ci-read-head\">\n              <div>\n                <div class=\"ci-read-source\">\n                  Source \u00B7 {{ Selected.SourceContentSource ?? 'Unknown source' }}\n                </div>\n                <h4 class=\"ci-read-title\">\"{{ Selected.ProposedName }}\"</h4>\n              </div>\n              <span class=\"ci-pill ci-pill-lg\" [class]=\"'ci-pill-' + ReasonPill(Selected.Reason)\">\n                <i class=\"fa-solid fa-triangle-exclamation\"></i> {{ ReasonLabel(Selected.Reason) }}\n              </span>\n            </div>\n\n            <div class=\"ci-kv\">\n              <div class=\"ci-k\">Proposed parent</div>\n              <div class=\"ci-v\">{{ Selected.ProposedParent ?? '\u2014 (root)' }}</div>\n\n              <div class=\"ci-k\">Best match</div>\n              <div class=\"ci-v\">\n                @if (Selected.BestMatchTag) {\n                  {{ Selected.BestMatchTag }} <span class=\"ci-muted\">(existing tag)</span>\n                } @else {\n                  <span class=\"ci-muted\">No close match</span>\n                }\n              </div>\n\n              @if (Selected.SourceContentItem) {\n                <div class=\"ci-k\">From content item</div>\n                <div class=\"ci-v ci-link\">{{ Selected.SourceContentItem }}</div>\n              }\n\n              @if (Selected.SourceText) {\n                <div class=\"ci-k\">Source text</div>\n                <div class=\"ci-v ci-source-text\">{{ Selected.SourceText }}</div>\n              }\n            </div>\n\n            <!-- Threshold band visualization -->\n            @if (Selected.BestMatchScore != null) {\n              <div class=\"ci-band\">\n                <h5>Match confidence vs thresholds</h5>\n                <div class=\"ci-bandbar\">\n                  <div class=\"ci-bandmark\" [style.left.%]=\"ScorePct(SuggestThreshold)\"></div>\n                  <div class=\"ci-bandmark-label\" [style.left.%]=\"ScorePct(SuggestThreshold)\">Suggest {{ FormatScore(SuggestThreshold) }}</div>\n                  <div class=\"ci-bandmark\" [style.left.%]=\"ScorePct(MatchThreshold)\"></div>\n                  <div class=\"ci-bandmark-label\" [style.left.%]=\"ScorePct(MatchThreshold)\">Match {{ FormatScore(MatchThreshold) }}</div>\n                  <div class=\"ci-bandscore\" [style.left.%]=\"ScorePct(Selected.BestMatchScore)\">{{ FormatScore(Selected.BestMatchScore) }}</div>\n                </div>\n                <div class=\"ci-bandlabels\">\n                  <span>reject / new</span>\n                  <span>review band</span>\n                  <span>auto-apply</span>\n                </div>\n              </div>\n            }\n\n            <!-- Merge target picker -->\n            <div class=\"ci-merge-picker\">\n              <label class=\"ci-merge-label\">Merge target</label>\n              <mj-combobox\n                  [Data]=\"TagOptions\"\n                  TextField=\"Label\"\n                  ValueField=\"ID\"\n                  [ValuePrimitive]=\"true\"\n                  [Filterable]=\"true\"\n                  Placeholder=\"Choose a tag to merge into\u2026\"\n                  [ngModel]=\"MergeTargetID\"\n                  (ValueChange)=\"OnMergeTargetChange($event)\">\n              </mj-combobox>\n            </div>\n\n            <!-- Reviewer note -->\n            <div class=\"ci-note\">\n              <label class=\"ci-merge-label\">Reviewer note (optional)</label>\n              <textarea class=\"mj-textarea ci-note-input\" rows=\"2\"\n                  placeholder=\"Why this decision\u2026\"\n                  [(ngModel)]=\"ReviewerNotes\"></textarea>\n            </div>\n\n            <!-- Action bar: confirm/primary actions LEFT, reject RIGHT -->\n            <div class=\"ci-actbar\">\n              <button mjButton variant=\"success\" size=\"sm\" (click)=\"MergeIntoExisting()\"\n                      [disabled]=\"IsActing || !MergeTargetID\">\n                <i class=\"fa-solid fa-code-merge\"></i> Merge into \"{{ MergeTargetLabel || '\u2026' }}\"\n              </button>\n              <button mjButton variant=\"primary\" size=\"sm\" (click)=\"ApproveAsNewTag()\" [disabled]=\"IsActing\">\n                <i class=\"fa-solid fa-plus\"></i> Approve as new tag\n              </button>\n              <span class=\"ci-actbar-spacer\"></span>\n              <button mjButton variant=\"danger\" size=\"sm\" (click)=\"Reject()\" [disabled]=\"IsActing\">\n                <i class=\"fa-solid fa-xmark\"></i> Reject\n              </button>\n            </div>\n          }\n        </div>\n      </div>\n    }\n  </div>\n</mj-page-body-interior>\n", styles: ["/*\n * Suggestions Inbox tab styles.\n *\n * The host (AutotaggingPipelineResourceComponent) uses ViewEncapsulation.None,\n * so its `.at-*` utilities (.at-main-area, .at-page-body, .at-empty-state) are\n * global and style the shell markup. This component uses the default emulated\n * encapsulation, so the inbox-specific `.ci-*` classes below are scoped here.\n *\n * Design tokens only \u2014 no hardcoded hex. The band gradient is built from\n * semantic status tokens via color-mix so it adapts to dark mode.\n */\n\n/* \u2500\u2500 3-pane layout \u2500\u2500 */\n.ci-inbox {\n    display: grid;\n    grid-template-columns: 180px 320px 1fr;\n    border: 1px solid var(--mj-border-default);\n    border-radius: 12px;\n    overflow: hidden;\n    min-height: 460px;\n    margin: 12px;\n    background: var(--mj-bg-surface);\n}\n\n.ci-col {\n    border-right: 1px solid var(--mj-border-default);\n    overflow: auto;\n}\n.ci-col:last-child {\n    border-right: 0;\n}\n\n/* \u2500\u2500 (1) Filter rail \u2500\u2500 */\n.ci-filter {\n    padding: 12px;\n    background: var(--mj-bg-surface-card);\n}\n.ci-filter h5 {\n    font-size: 11px;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    color: var(--mj-text-muted);\n    margin: 0 0 8px;\n}\n.ci-section-gap {\n    margin-top: 14px;\n}\n.ci-filter-link {\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n    gap: 8px;\n    padding: 7px 9px;\n    border-radius: 7px;\n    color: var(--mj-text-secondary);\n    font-size: 12.5px;\n    font-weight: 600;\n    cursor: pointer;\n    margin-bottom: 2px;\n}\n.ci-filter-link:hover {\n    background: var(--mj-bg-surface-hover);\n}\n.ci-filter-link.ci-active {\n    background: var(--mj-bg-surface);\n    box-shadow: inset 0 0 0 1px var(--mj-border-default);\n    color: var(--mj-text-primary);\n}\n.ci-n {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n}\n\n/* \u2500\u2500 (2) Suggestion list \u2500\u2500 */\n.ci-list {\n    background: var(--mj-bg-surface);\n}\n.ci-row {\n    padding: 11px 13px;\n    border-bottom: 1px solid var(--mj-border-subtle);\n    cursor: pointer;\n}\n.ci-row:hover {\n    background: var(--mj-bg-surface-hover);\n}\n.ci-row.ci-sel {\n    background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n    box-shadow: inset 3px 0 0 var(--mj-brand-primary);\n}\n.ci-row-top {\n    display: flex;\n    justify-content: space-between;\n    gap: 8px;\n}\n.ci-row-name {\n    font-weight: 700;\n    font-size: 13px;\n    color: var(--mj-text-primary);\n}\n.ci-row-ago {\n    font-size: 10.5px;\n    color: var(--mj-text-muted);\n    white-space: nowrap;\n}\n.ci-row-reason {\n    font-size: 11px;\n    color: var(--mj-text-secondary);\n    margin-top: 4px;\n    display: flex;\n    align-items: center;\n    gap: 6px;\n    flex-wrap: wrap;\n}\n.ci-row-match b {\n    color: var(--mj-text-primary);\n}\n\n/* \u2500\u2500 (3) Reading pane \u2500\u2500 */\n.ci-read {\n    padding: 18px 20px;\n}\n.ci-read-head {\n    display: flex;\n    justify-content: space-between;\n    align-items: flex-start;\n    gap: 12px;\n}\n.ci-read-source {\n    font-size: 11px;\n    color: var(--mj-text-muted);\n    font-family: var(--mj-font-mono, monospace);\n}\n.ci-read-title {\n    font-size: 17px;\n    margin: 4px 0 0;\n    color: var(--mj-text-primary);\n}\n.ci-kv {\n    display: grid;\n    grid-template-columns: 130px 1fr;\n    gap: 7px 12px;\n    margin: 16px 0;\n    font-size: 13px;\n}\n.ci-k {\n    color: var(--mj-text-muted);\n}\n.ci-v {\n    font-weight: 600;\n    color: var(--mj-text-primary);\n}\n.ci-muted {\n    color: var(--mj-text-muted);\n    font-weight: 400;\n}\n.ci-link {\n    color: var(--mj-text-link);\n}\n.ci-source-text {\n    font-weight: 400;\n    color: var(--mj-text-secondary);\n    max-height: 80px;\n    overflow: auto;\n    white-space: pre-wrap;\n}\n\n/* \u2500\u2500 Threshold band visualization \u2500\u2500 */\n.ci-band {\n    margin: 18px 0;\n    background: var(--mj-bg-surface-card);\n    border: 1px solid var(--mj-border-default);\n    border-radius: 10px;\n    padding: 14px;\n}\n.ci-band h5 {\n    font-size: 11px;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    color: var(--mj-text-muted);\n    margin: 0 0 30px;\n}\n.ci-bandbar {\n    position: relative;\n    height: 10px;\n    border-radius: 6px;\n    /* reject/new (red) \u2192 review band (amber) \u2192 auto-apply (green) */\n    background: linear-gradient(90deg,\n        color-mix(in srgb, var(--mj-status-error) 30%, var(--mj-bg-surface)) 0%,\n        color-mix(in srgb, var(--mj-status-warning) 30%, var(--mj-bg-surface)) 55%,\n        color-mix(in srgb, var(--mj-status-success) 30%, var(--mj-bg-surface)) 78%,\n        color-mix(in srgb, var(--mj-status-success) 45%, var(--mj-bg-surface)) 100%);\n}\n.ci-bandmark {\n    position: absolute;\n    top: -6px;\n    width: 2px;\n    height: 22px;\n    background: var(--mj-text-primary);\n    transform: translateX(-50%);\n}\n.ci-bandmark-label {\n    position: absolute;\n    top: -20px;\n    transform: translateX(-50%);\n    font-size: 9px;\n    color: var(--mj-text-muted);\n    white-space: nowrap;\n}\n.ci-bandscore {\n    position: absolute;\n    top: -30px;\n    transform: translateX(-50%);\n    font-size: 11px;\n    font-weight: 800;\n    background: var(--mj-text-primary);\n    color: var(--mj-text-inverse);\n    padding: 2px 7px;\n    border-radius: 6px;\n}\n.ci-bandlabels {\n    display: flex;\n    justify-content: space-between;\n    margin-top: 9px;\n    font-size: 10.5px;\n    color: var(--mj-text-muted);\n}\n\n/* \u2500\u2500 Merge picker + note \u2500\u2500 */\n.ci-merge-picker,\n.ci-note {\n    margin: 14px 0;\n}\n.ci-merge-label {\n    display: block;\n    font-size: 11px;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    color: var(--mj-text-muted);\n    margin-bottom: 6px;\n}\n.ci-note-input {\n    width: 100%;\n    resize: vertical;\n}\n\n/* \u2500\u2500 Action bar \u2500\u2500 */\n.ci-actbar {\n    display: flex;\n    align-items: center;\n    gap: 9px;\n    margin-top: 16px;\n    padding-top: 16px;\n    border-top: 1px solid var(--mj-border-default);\n}\n.ci-actbar-spacer {\n    flex: 1;\n}\n\n/* \u2500\u2500 Reason pills \u2500\u2500 */\n.ci-pill {\n    display: inline-flex;\n    align-items: center;\n    gap: 4px;\n    font-size: 10px;\n    font-weight: 700;\n    padding: 2px 8px;\n    border-radius: 999px;\n    white-space: nowrap;\n}\n.ci-pill-lg {\n    font-size: 12px;\n    padding: 4px 12px;\n}\n.ci-pill-gray {\n    background: var(--mj-bg-surface-sunken);\n    color: var(--mj-text-secondary);\n}\n.ci-pill-amber {\n    background: var(--mj-status-warning-bg);\n    color: var(--mj-status-warning-text);\n}\n.ci-pill-red {\n    background: var(--mj-status-error-bg);\n    color: var(--mj-status-error-text);\n}\n.ci-pill-blue {\n    background: var(--mj-status-info-bg);\n    color: var(--mj-status-info-text);\n}\n\n/* \u2500\u2500 Pending status pill (header [meta]) \u2500\u2500 */\n.ci-status-pill {\n    display: inline-flex;\n    align-items: center;\n    gap: 6px;\n    font-size: 12px;\n    font-weight: 600;\n    padding: 3px 10px;\n    border-radius: 999px;\n    background: var(--mj-bg-surface-sunken);\n    color: var(--mj-text-secondary);\n}\n.ci-status-pill-active {\n    background: var(--mj-status-warning-bg);\n    color: var(--mj-status-warning-text);\n}\n"] }]
    }], null, { Resolved: [{
            type: Output
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ClassifyInboxTabComponent, { className: "ClassifyInboxTabComponent", filePath: "src/AI/components/autotagging/tabs/inbox-tab.component.ts", lineNumber: 70 }); })();
//# sourceMappingURL=inbox-tab.component.js.map