import {
  ABBREV_COHORT,
  FULL_COHORT,
  getDefaultProfilePlotSettings,
  getProfilePlotConfig,
  profilePlot
} from "./chunk-P3IENRWJ.js";
import {
  fillTwLst
} from "./chunk-SA7APTJR.js";
import "./chunk-HJ6L54YS.js";
import "./chunk-LSEFWW72.js";
import "./chunk-SKREEF3H.js";
import "./chunk-HYOEWQ5P.js";
import "./chunk-HBW42TDT.js";
import "./chunk-G6O3URDN.js";
import "./chunk-FN5XPUPH.js";
import "./chunk-IIT367QZ.js";
import "./chunk-RZGEKL77.js";
import "./chunk-UI7OCM2A.js";
import "./chunk-YZK37YCC.js";
import {
  dofetch3
} from "./chunk-7EMWHCVW.js";
import "./chunk-7IYJZZQI.js";
import {
  copyMerge,
  getCompInit
} from "./chunk-M3J4MINX.js";
import "./chunk-PF4DSFDR.js";
import "./chunk-QH6W3NVF.js";
import "./chunk-NOEAT6CX.js";
import "./chunk-4UWS5Y3N.js";
import "./chunk-DD4R5P6W.js";
import "./chunk-JNITUVXP.js";
import "./chunk-KSGA62R2.js";
import {
  axisTop
} from "./chunk-LOZEKOES.js";
import "./chunk-TOU7EVFQ.js";
import {
  linear
} from "./chunk-OAWQ6LOO.js";
import "./chunk-TLT4YIG3.js";
import "./chunk-KYBIQBXE.js";
import "./chunk-I6Y4O3RR.js";
import "./chunk-OMR2DT66.js";
import "./chunk-DQC5FFGV.js";
import "./chunk-HFNDKYVF.js";

// plots/profile/barchart2.ts
var stepx = 500;
var barwidth = 400;
var ProfileBarchart2 = class extends profilePlot {
  constructor(opts) {
    super(opts, "profileBarchart2");
    this.rowCount = 0;
    this.additionalInputs = [];
  }
  static {
    this.type = "profileBarchart2";
  }
  async init(appState) {
    await super.init(appState);
    const config = appState.plots.find((p) => p.id === this.id);
    this.componentNames = config.plotByComponent.map((elem) => ({
      value: elem.profileComponent.name,
      label: elem.profileComponent.name
    }));
    const profileComponentInput = {
      label: "Component",
      type: "dropdown",
      chartType: "profileBarchart2",
      options: this.componentNames,
      settingsKey: "profileComponent",
      callback: (value) => this.setProfileComponent(value)
    };
    this.additionalInputs.push(profileComponentInput);
  }
  setProfileComponent(value) {
    this.settings.profileComponent = value;
    this.app.dispatch({ type: "plot_edit", id: this.id, config: this.config });
  }
  async main() {
    try {
      await super.main();
      this.configProfileComponent = this.config.plotByComponent.find((comp) => comp.profileComponent.name == this.settings.profileComponent) || this.config.plotByComponent[0];
      this.rowCount = 0;
      this.scoreTerms = [];
      for (const group of this.configProfileComponent.groups)
        for (const row of group.rows) {
          this.rowCount++;
          if (row.term1) this.scoreTerms.push(row.term1);
          if (row.term2) this.scoreTerms.push(row.term2);
        }
      await this.setControls(this.additionalInputs);
      this.profileComponent = this.settings.profileComponent || this.componentNames[0].value;
      this.plot();
    } catch (e) {
      console.error(e);
      throw `${e} [profileBarchart2 main()]`;
    }
  }
  /**
   * Override setControls() to fetch data from the dedicated barchart2 route.
   * The base class setControls() builds filter UI and sets this.filter but
   * skips the data fetch for profileBarchart2 (see profilePlot.ts).
   * This method calls termdb/profileBarchart2Scores, which derives the facility
   * term server-side and returns aggregated (median) percentages.
   */
  async setControls(additionalInputs = []) {
    await super.setControls(additionalInputs);
    this.data = await this.fetchAggregatedScores();
    if (this.data && "error" in this.data) throw this.data.error;
  }
  async fetchAggregatedScores() {
    return dofetch3("termdb/profileBarchart2Scores", {
      body: {
        genome: this.state.vocab.genome,
        dslabel: this.state.vocab.dslabel,
        scoreTerms: this.scoreTerms.map((t) => ({
          score: { term: { id: t.score.term.id }, q: t.score.q },
          maxScore: typeof t.maxScore === "number" ? t.maxScore : { term: { id: t.maxScore.term.id }, q: t.maxScore.q }
        })),
        filterByUserSites: this.settings?.filterByUserSites,
        filter: this.filter
      }
    });
  }
  onMouseOut(event) {
    if (event.target.tagName == "rect" && event.target.getAttribute("fill-opacity") == 0.3) {
      event.target.setAttribute("fill-opacity", 0);
    }
  }
  onMouseOver(event) {
    if (event.target.tagName == "rect" && event.target.getAttribute("fill-opacity") == 0) {
      event.target.setAttribute("fill-opacity", 0.3);
    }
  }
  plot() {
    const { hasSubjectiveData } = this.createSvg();
    this.drawTitleAndDefs(hasSubjectiveData);
    this.drawColumnHeaders(hasSubjectiveData);
    const yEnd = this.drawComponentRows(hasSubjectiveData);
    this.drawGuideLines(yEnd, hasSubjectiveData);
    this.drawLegend(yEnd, hasSubjectiveData);
  }
  createSvg() {
    const hasSubjectiveData = this.configProfileComponent.hasSubjectiveData;
    const width = this.state.activeCohort == ABBREV_COHORT ? 1e3 : 1300;
    const height = this.rowCount * 32 + 450;
    this.dom.svg = this.dom.plotDiv.append("svg").attr("width", width).attr("height", height);
    return { width, height, hasSubjectiveData };
  }
  drawTitleAndDefs(_hasSubjectiveData) {
    const title = this.state.activeCohort == ABBREV_COHORT ? `Score-based Results for the ${this.profileComponent} Component by Module and Domain Compared with End-User Impression` : `Objective ${this.profileComponent == "Patients and Outcomes" ? "" : "and Subjective "}Score-based Results for the ${this.profileComponent} Component by Module and Domain`;
    this.dom.svg.append("text").attr("transform", `translate(50, 30)`).attr("font-weight", "bold").text(title);
    const color = this.configProfileComponent.profileComponent.color;
    this.dom.svg.append("defs").append("pattern").attr("id", `${this.id}_diagonalHatch`).attr("patternUnits", "userSpaceOnUse").attr("width", 4).attr("height", 4).append("path").attr("d", "M-1,1 l2,-2 M0,4 l4,-4 M3,5 l2,-2").attr("stroke-width", 1).attr("stroke", color);
  }
  drawColumnHeaders(hasSubjectiveData) {
    const svg = this.dom.svg;
    const config = this.config;
    for (const [i, c] of config.columnNames.entries()) {
      if (i == 1 && !hasSubjectiveData) break;
      const x = (i % 2 == 0 ? 400 : 900) + 10;
      const y = 70;
      svg.append("text").attr("transform", `translate(${x}, ${y})`).attr("text-anchor", "start").style("font-weight", "bold").text(c);
      this.drawAxis(x, y + 30);
    }
  }
  drawAxis(x, y) {
    const xAxisScale = linear().domain([0, 100]).range([0, barwidth]);
    this.dom.svg.append("g").attr("transform", `translate(${x}, ${y})`).call(axisTop(xAxisScale));
  }
  drawComponentRows(hasSubjectiveData) {
    const svg = this.dom.svg;
    const step = 30;
    let y = 70;
    for (const group of this.configProfileComponent.groups) {
      svg.append("text").attr("transform", `translate(${50}, ${y + 40})`).attr("text-anchor", "start").text(`${group.label}`).style("font-weight", "bold");
      y += step + 20;
      for (const row of group.rows) {
        const g = svg.append("g");
        g.append("rect").attr("transform", `translate(${20}, ${y - 6})`).attr("x", 0).attr("y", 0).attr("width", hasSubjectiveData ? 1500 : 850).attr("height", 30).attr("fill", "#f8d335").attr("fill-opacity", 0);
        const x = 400;
        if (row.term1) this.drawRect(x, y, row, "term1", g);
        if (row.term2) this.drawRect(x + stepx, y, row, "term2", g);
        y += step;
      }
    }
    return y;
  }
  drawRect(x, y, row, field, g) {
    const hasSubjectiveData = this.configProfileComponent.hasSubjectiveData;
    const d = row[field];
    let subjectiveTerm = false;
    if ((row.name == "Total Module" || row.name == "End-user Impression*") && !row.term2) subjectiveTerm = true;
    const termColor = d.score.term.color;
    const value = this.getPercentage(d);
    const isFirst = field == "term1" || field == "term2" && !row.term1;
    const pairValue = field == "term1" ? this.getPercentage(row.term2) : this.getPercentage(row.term1);
    const width = value ? value / 100 * barwidth : 0;
    if (value) {
      const isObjective = this.state.activeCohort == FULL_COHORT && this.settings.profileComponent == "Patients and Outcomes" ? true : !subjectiveTerm && (pairValue || !hasSubjectiveData);
      const rect = g.append("rect").attr("transform", `translate(${x + 10}, ${y})`).attr("pointer-events", "none").attr("x", 0).attr("y", 0).attr("width", width).attr("height", 20);
      if (isObjective) rect.attr("fill", termColor);
      else {
        const termid = this.id + d.score.term.id;
        g.append("defs").append("pattern").attr("id", termid).attr("patternUnits", "userSpaceOnUse").attr("width", 4).attr("height", 4).append("path").attr("d", "M-1,1 l2,-2 M0,4 l4,-4 M3,5 l2,-2").attr("stroke-width", 1).attr("stroke", termColor);
        rect.attr("fill", `url(#${termid})`);
      }
    }
    const text = g.append("text").attr("pointer-events", "none").attr("text-anchor", "end").text(`${value || 0}%`);
    if (width > 0) text.attr("transform", `translate(${x + width + 55}, ${y + 15})`);
    else if (!pairValue && field == "term1") text.attr("transform", `translate(${x + 35}, ${y + 15})`);
    if (isFirst)
      g.append("text").attr("transform", `translate(${field == "term1" ? x : x - stepx}, ${y + 15})`).attr("text-anchor", "end").text(row.name).attr("pointer-events", "none");
  }
  drawGuideLines(yEnd, hasSubjectiveData) {
    this.drawGuide(410, 120, 50, yEnd, "B");
    this.drawGuide(410, 120, 75, yEnd, "A");
    if (!hasSubjectiveData) return;
    this.drawGuide(910, 120, 50, yEnd, "B");
    this.drawGuide(910, 120, 75, yEnd, "A");
  }
  drawGuide(x, y, percent, y2, text) {
    const svg = this.dom.svg;
    const x1 = x + percent / 100 * barwidth;
    svg.append("line").style("stroke", "#aaa").style("stroke-width", 1).style("stroke-dasharray", "5, 5").attr("x1", x1).attr("y1", y).attr("x2", x1).attr("y2", y2);
    svg.append("text").attr("transform", `translate(${x1 + 0.125 * barwidth}, ${y2 + 20})`).attr("text-anchor", "middle").text(text).style("font-weight", "bold");
    if (percent == 50)
      svg.append("text").attr("transform", `translate(${x1 - 0.25 * barwidth}, ${y2 + 20})`).attr("text-anchor", "middle").text("C").style("font-weight", "bold");
  }
  drawLegend(yEnd, hasSubjectiveData) {
    this.legendG = this.dom.svg.append("g").attr("data-testid", "sjpp-profileBarchart2-legend").attr("transform", `translate(400,${yEnd + 90})`);
    this.filterG = this.dom.svg.append("g").attr("transform", `translate(0,${yEnd + 90})`);
    if (!this.isComparison) {
      this.legendG.append("text").attr("text-anchor", "left").style("font-weight", "bold").text("Overall Score").attr("transform", `translate(0, -5)`);
      this.addLegendItem("A", "More than 75% of possible scorable items", 1);
      this.addLegendItem("B", "50-75% of possible scorable items", 2);
      this.addLegendItem("C", "Less than 50% of possible scorable items", 3);
      if (this.state.activeCohort == ABBREV_COHORT) {
        this.addEndUserImpressionNote(this.legendG.append("g"));
      } else this.addPOCNote(this.legendG.append("g"));
    }
    this.addFilterLegend();
    if (!hasSubjectiveData) return;
    const color = this.configProfileComponent.profileComponent.color;
    const svg = this.dom.svg;
    const y = yEnd + 40;
    let x = 600;
    const lineG = svg.append("g");
    this.drawLegendRect(x, y, "and", color, lineG);
    x += 300;
    this.drawLegendRect(x, y, "or", color, lineG);
  }
  drawLegendRect(x, y, operator, color, lineG) {
    const rect = lineG.append("g").attr("transform", `translate(${x}, ${y})`).append("rect").attr("x", 0).attr("y", 0).attr("width", 20).attr("height", 20);
    if (operator == "and") rect.attr("fill", color);
    else rect.attr("fill", `url(#${this.id}_diagonalHatch)`);
    const text = this.dom.svg.append("text").attr("transform", `translate(${x + 25}, ${y + 15})`).attr("text-anchor", "start").text("Objective ");
    text.append("tspan").attr("font-weight", "bold").text(operator);
    text.append("tspan").text(" Subjective data");
  }
};
async function getPlotConfig(opts, app, _activeCohort) {
  try {
    const activeCohort = _activeCohort === void 0 ? app.getState().activeCohort : _activeCohort;
    const defaults = await getProfilePlotConfig(activeCohort, app, opts);
    if (!defaults) throw "default config not found in termdbConfig.plotConfigByCohort.profileBarchart2";
    defaults.settings = { profileBarchart2: getDefaultProfilePlotSettings() };
    let config = structuredClone(defaults);
    config = copyMerge(config, opts);
    config.settings.controls = { isOpen: false };
    const twlst = [];
    for (const profileComponent of config.plotByComponent) {
      profileComponent.hasSubjectiveData = false;
      for (const group of profileComponent.groups)
        for (const row of group.rows) {
          if (row.term1) {
            row.term1.score.q = row.term1.maxScore.q = { mode: "continuous" };
            twlst.push(row.term1.score);
            twlst.push(row.term1.maxScore);
          }
          if (row.term2) {
            row.term2.score.q = row.term2.maxScore.q = { mode: "continuous" };
            twlst.push(row.term2.score);
            twlst.push(row.term2.maxScore);
          }
          if (row.term1 && row.term2) profileComponent.hasSubjectiveData = true;
        }
    }
    await fillTwLst(twlst, app.vocabApi);
    return config;
  } catch (e) {
    throw `${e} [profileBarchart2 getPlotConfig()]`;
  }
}
var profileBarchart2Init = getCompInit(ProfileBarchart2);
var componentInit = profileBarchart2Init;
function getDefaultProfileBarchart2Settings() {
  return {};
}
export {
  componentInit,
  getDefaultProfileBarchart2Settings,
  getPlotConfig,
  profileBarchart2Init
};
//# sourceMappingURL=barchart2-KMSU4ROO.js.map
