/* =========================================================================
   MEL Report — cohesive, reader-facing document
   Sections: Overview · Theory of Change · Baseline · Results Framework ·
             Data Collection · Ethics & Quality
   ========================================================================= */

const CHAIN_SECTIONS = [
  { title: "Outputs", items: [
    { tocKey: "outputs",     label: "Output",               timeframe: null,           indKey: "output_indicators"  }
  ]},
  { title: "Outcomes", items: [
    { tocKey: "outcomes_im", label: "Immediate outcome",    timeframe: "0–3 months",   indKey: "outcome_indicators" },
    { tocKey: "outcomes_it", label: "Intermediate outcome", timeframe: "6 mo – 3 yrs", indKey: "outcome_indicators" },
    { tocKey: "outcomes_lt", label: "Long-term outcome",    timeframe: "3–5+ years",   indKey: "outcome_indicators" },
  ]},
  { title: "Impact", items: [
    { tocKey: "impact",      label: "Impact",               timeframe: null,           indKey: "impact_indicators"  }
  ]},
];

/* METHOD_SPECS no longer needed — method assignments now come from
   outputs_methods / outcomes_methods / impact_methods via _getMethodsForItem */

/* Renders a single labelled field — returns null if unanswered */
function RptField({ prompt, answer, label }) {
  if (!prompt || !isPromptAnswered(prompt, answer)) return null;
  return (
    <div className="rpt-field">
      <div className="rpt-field__lbl">{label || prompt.label}</div>
      <ReportAnswer prompt={prompt} answer={answer} />
    </div>
  );
}

/* -------------------------------------------------------------------------
   Main report view
   ------------------------------------------------------------------------- */
function ReportView({ steps, answers, naState, projectName, onBack }) {
  const today = new Date().toLocaleDateString("en-US", { year: "numeric", month: "long", day: "numeric" });

  const promptMap = useMemo(() => {
    const map = {};
    steps.forEach(s => s.lessons.forEach(l => l.prompts.forEach(p => { map[p.id] = p; })));
    return map;
  }, [steps]);

  const toc = (answers.toc && typeof answers.toc === "object") ? answers.toc : {};

  /* Shorthand: render a field by prompt id */
  const fld = (id, label) => (
    <RptField key={id} prompt={promptMap[id]} answer={answers[id]} label={label} />
  );

  /* Does a section have any filled prompts? */
  const hasAny = (...ids) => ids.some(id => {
    const p = promptMap[id];
    return p && isPromptAnswered(p, answers[id]);
  });

  /* ---- Print / export -------------------------------------------------- */
  const handlePrint = () => {
    const oldTitle = document.title;
    const safe = (projectName || "MEL Report").replace(/[\\/:*?"<>|]/g, "");
    document.title = `${safe} — ISD MEL Report`;
    setTimeout(() => { window.print(); setTimeout(() => { document.title = oldTitle; }, 200); }, 50);
  };

  const handleWordExport = () => {
    function esc(str) {
      if (!str) return "";
      return String(str).replace(/\\/g,"\\\\").replace(/\{/g,"\\{").replace(/\}/g,"\\}")
        .replace(/[^\x00-\x7F]/g, c => `\\u${c.charCodeAt(0)}?`);
    }
    function ansRtf(p, answer) {
      if (!isPromptAnswered(p, answer)) return "\\i Not yet completed.\\i0\\par\n";
      switch (p.type) {
        case "textarea": case "text":
          return esc(answer).replace(/\r?\n/g,"\\par\n") + "\\par\n";
        case "radio": return `\\b ${esc(answer)}\\b0\\par\n`;
        case "radio-other": {
          let s = `\\b ${esc(answer.value)}\\b0\\par\n`;
          if (answer.other) s += esc(answer.other) + "\\par\n";
          const det = p.optionDetails && p.optionDetails[answer.value];
          if (det) s += `\\par\\i ${esc(det.quote)}\\i0\\par\n\\fs18 ${esc(det.attribution)}\\fs20\\par\n`;
          return s;
        }
        case "checks":
          return answer.filter(x=>(x||"").trim()).map(x=>`\\u8226? ${esc(x)}\\par\n`).join("");
        case "list":
          return answer.filter(x=>(x||"").trim()).map((x,i)=>`${i+1}. ${esc(x)}\\par\n`).join("");
        case "toc-builder": {
          const pillars = [
            {label:"Inputs",keys:["inputs"]},{label:"Activities",keys:["activities"]},
            {label:"Outputs",keys:["outputs"]},
            {label:"Outcomes \\u8212? Immediate",keys:["outcomes_im"]},
            {label:"Outcomes \\u8212? Intermediate",keys:["outcomes_it"]},
            {label:"Outcomes \\u8212? Long-term",keys:["outcomes_lt"]},
            {label:"Impact",keys:["impact"]},{label:"Assumptions",keys:["assumptions"]},
          ];
          return pillars.flatMap(pl => {
            const items = pl.keys.flatMap(k=>(answer[k]||[]).filter(x=>(x||"").trim()));
            if (!items.length) return [];
            return [`\\b ${pl.label}\\b0\\par\n`,...items.map(x=>`\\u8226? ${esc(x)}\\par\n`),"\\par\n"];
          }).join("");
        }
        case "sampling-tree": {
          const apps = Array.isArray(answer.approaches)?answer.approaches:(answer.approach?[answer.approach]:[]);
          const meths = Array.isArray(answer.methods)?answer.methods:(answer.method?[answer.method]:[]);
          return `\\b ${esc(apps.join(" + "))}\\b0\\par\n`+meths.map(m=>`\\u8226? ${esc(m)}\\par\n`).join("");
        }
        default: return esc(String(answer))+"\\par\n";
      }
    }

    function secHead(text) { return `\\pard\\sb480\\sa80\\f1\\fs28\\b ${esc(text)}\\b0\\par\n`; }
    function subHead(text) { return `\\pard\\sb240\\sa40\\f1\\fs22\\b ${esc(text)}\\b0\\par\n`; }
    function fieldLbl(text){ return `\\pard\\sb120\\sa30\\f0\\fs18\\b\\cf2 ${esc(text)}\\b0\\cf0\\par\n`; }
    function fieldVal(p,a) { return `\\pard\\f0\\fs20 ${ansRtf(p,a)}`; }

    let body = "";
    const safe = projectName || "MEL Report";
    body += `\\pard\\sa120\\f1\\fs52\\b ${esc(safe)}\\b0\\par\n`;
    body += `\\pard\\f0\\fs22\\cf1 ISD MEL Framework \\u183? Draft Report\\cf0\\par\n`;
    body += `\\pard\\f0\\fs20 ${esc(today)}\\par\n\\par\n`;
    body += `{\\pard\\brdrb\\brdrs\\brdrw15\\brsp80 \\par}\\par\n`;

    /* 1. Project Overview */
    body += secHead("Project Overview");
    [["problem","Problem statement"],["antisemitism_def","Definition of antisemitism"],
     ["expressions","Expressions addressed"],["scope","Scope"],
     ["audience","Target audience"],["beneficiaries","Beneficiaries"],
     ["context_factors","Contextual factors"],["context_detail","Context detail"]
    ].forEach(([id,lbl])=>{
      const p=promptMap[id]; const a=answers[id];
      if(p&&isPromptAnswered(p,a)){ body+=fieldLbl(lbl); body+=fieldVal(p,a); }
    });

    /* 2. Theory of Change */
    if(isPromptAnswered(promptMap["toc"],toc)){
      body += secHead("Theory of Change");
      body += fieldVal(promptMap["toc"],toc);
    }

    /* 3. Baseline */
    if(hasAny("baseline_types","baseline_plan","prior_trends")){
      body += secHead("Baseline");
      [["baseline_types","Baseline types"],["baseline_plan","Collection plan"],["prior_trends","Prior trends"]
      ].forEach(([id,lbl])=>{
        const p=promptMap[id]; const a=answers[id];
        if(p&&isPromptAnswered(p,a)){ body+=fieldLbl(lbl); body+=fieldVal(p,a); }
      });
    }

    /* 4. Results Framework */
    body += secHead("Results Framework");
    CHAIN_SECTIONS.forEach(sec => {
      const hasItems = sec.items.some(grp=>(toc[grp.tocKey]||[]).filter(x=>(x||"").trim()).length>0);
      if(!hasItems) return;
      body += subHead(sec.title);
      sec.items.forEach(grp => {
        (toc[grp.tocKey]||[]).filter(x=>(x||"").trim()).forEach((itemText,idx)=>{
          const itemKey=`${grp.tocKey}__${idx}`;
          const typeLabel=grp.timeframe?`${grp.label} (${grp.timeframe})`:grp.label;
          body+=`\\pard\\sb200\\sa40\\f0\\fs18\\cf2 ${esc(typeLabel)}\\cf0\\par\n`;
          body+=`\\pard\\f1\\fs22\\b ${esc(itemText)}\\b0\\par\n`;
          /* Indicators */
          const indAns=answers[grp.indKey]; const indP=promptMap[grp.indKey];
          const indItem=indAns&&typeof indAns==="object"?indAns[itemKey]:null;
          if(indItem&&indP){
            body+=`\\pard\\sb80\\f0\\fs18\\b Indicators\\b0\\par\n`;
            indP.fields.forEach(f=>{
              const fv=indItem[f.id];
              if(!fv||(Array.isArray(fv)&&!fv.filter(x=>(x||"").trim()).length)) return;
              body+=fieldLbl(f.label); body+=`\\pard\\f0\\fs20 ${ansRtf(f,fv)}`;
            });
          }
          /* Methods + specifications */
          const itemMethods = window._getMethodsForItem ? window._getMethodsForItem(itemKey, answers) : [];
          if(itemMethods.length > 0){
            body+=`\\pard\\sb80\\f0\\fs18\\b Data collection methods\\b0\\par\n`;
            body+=itemMethods.map(m=>`\\u8226? ${esc(m)}\\par\n`).join("");
            const itemEntry = window._getMethodEntryForItem ? window._getMethodEntryForItem(itemKey, answers) : null;
            const itemDetails = (itemEntry && itemEntry.details && typeof itemEntry.details === "object") ? itemEntry.details : {};
            Object.keys(itemDetails).forEach(mName => {
              const lines = window._reportMethodDetailLines ? window._reportMethodDetailLines(mName, itemDetails[mName]) : [];
              if(!lines.length) return;
              body+=`\\pard\\sb60\\f0\\fs18\\b\\cf2 ${esc(mName)}\\b0\\cf0\\par\n`;
              lines.forEach(line => {
                body+=`\\pard\\f0\\fs18\\b ${esc(line.label)}: \\b0 ${esc(line.value)}\\par\n`;
              });
            });
          }
          body+="\\pard\\par\n";
        });
      });
    });

    /* 5. Data Collection */
    if(hasAny("sampling_tree","sample_size","control_group")){
      body += secHead("Data Collection Design");
      [["sampling_tree","Sampling approach"],["sample_size","Target sample size"],["control_group","Control group"]
      ].forEach(([id,lbl])=>{
        const p=promptMap[id]; const a=answers[id];
        if(p&&isPromptAnswered(p,a)){ body+=fieldLbl(lbl); body+=fieldVal(p,a); }
      });
    }

    /* 6. Ethics */
    const step4 = steps.find(s=>s.id==="step4");
    if(step4){
      body += secHead("Ethics & Quality");
      step4.lessons.forEach(lesson=>{
        if(naState&&naState[lesson.id]) return;
        const anyFilled = lesson.prompts.some(p=>isPromptAnswered(p,answers[p.id]));
        if(!anyFilled) return;
        body += subHead(lesson.title);
        lesson.prompts.forEach(p=>{
          if(!isPromptAnswered(p,answers[p.id])) return;
          body+=fieldLbl(p.label); body+=fieldVal(p,answers[p.id]);
        });
      });
    }

    const rtf =
      `{\\rtf1\\ansi\\deff0\n{\\fonttbl{\\f0\\froman\\fcharset0 Georgia;}{\\f1\\fswiss\\fcharset0 Arial;}}\n` +
      `{\\colortbl;\\red76\\green65\\blue147;\\red100\\green100\\blue100;}\n` +
      `\\paperw12240\\paperh15840\\margl1800\\margr1800\\margt1440\\margb1440\n` +
      body + `}`;

    const blob = new Blob([rtf],{type:"application/rtf"});
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href=url; a.download=`${safe.replace(/[\\/:*?"<>|]/g,"")} — ISD MEL Report.rtf`;
    document.body.appendChild(a); a.click(); document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  /* ---- Results Framework renderer -------------------------------------- */
  const renderResultsFramework = () => {
    const hasChainContent = CHAIN_SECTIONS.some(sec =>
      sec.items.some(grp => (toc[grp.tocKey]||[]).filter(x=>(x||"").trim()).length > 0)
    );
    if (!hasChainContent) {
      return <div className="rpt-field"><div className="rpt-field__lbl">Note</div><div className="report-q__ans report-q__ans--empty">— Complete your Theory of Change in section 1.2 to populate this section —</div></div>;
    }
    return CHAIN_SECTIONS.map(sec => {
      const tocItems = sec.items.flatMap(grp =>
        (toc[grp.tocKey]||[]).filter(x=>(x||"").trim()).map((text,idx) => ({grp,text,idx}))
      );
      if (!tocItems.length) return null;
      return (
        <div key={sec.title} className="rpt-chain-section">
          <div className="rpt-chain-section__title">{sec.title}</div>
          {tocItems.map(({grp, text, idx}) => {
            const itemKey = `${grp.tocKey}__${idx}`;
            const indAns   = answers[grp.indKey];
            const indItem  = (indAns && typeof indAns === "object") ? (indAns[itemKey] || null) : null;
            const indPrompt = promptMap[grp.indKey];
            const activeMethods = window._getMethodsForItem
              ? window._getMethodsForItem(itemKey, answers)
              : [];
            const methodEntry = window._getMethodEntryForItem
              ? window._getMethodEntryForItem(itemKey, answers)
              : null;
            const methodDetails = (methodEntry && methodEntry.details && typeof methodEntry.details === "object")
              ? methodEntry.details : {};
            return (
              <div key={itemKey} className="rpt-chain-item">
                <div className="rpt-chain-item__type">
                  {grp.label}{grp.timeframe && <span className="rpt-chain-item__tf"> · {grp.timeframe}</span>}
                </div>
                <div className="rpt-chain-item__text">{text}</div>

                {/* Indicators */}
                {indItem && indPrompt && (
                  <div className="rpt-chain-item__sub">
                    <div className="rpt-chain-item__sub-title">Indicators</div>
                    {indPrompt.fields.map(field => {
                      const fv = indItem[field.id];
                      if (!fv || (Array.isArray(fv) && !fv.filter(x=>(x||"").trim()).length)) return null;
                      return (
                        <div key={field.id} className="rpt-chain-item__field">
                          <div className="rpt-chain-item__field-lbl">{field.label}</div>
                          <ReportAnswer prompt={field} answer={fv} />
                        </div>
                      );
                    })}
                  </div>
                )}

                {/* Data collection methods + specifications */}
                {activeMethods.length > 0 && (
                  <div className="rpt-chain-item__sub rpt-chain-item__sub--method">
                    <div className="rpt-chain-item__sub-title">Data collection methods</div>
                    <ul className="report-q__list">
                      {activeMethods.map((m, mi) => <li key={mi}>{m}</li>)}
                    </ul>
                    {Object.keys(methodDetails).map(mName => {
                      const lines = window._reportMethodDetailLines
                        ? window._reportMethodDetailLines(mName, methodDetails[mName])
                        : [];
                      if (!lines.length) return null;
                      return (
                        <div key={mName} className="report-toc-pi__method-details">
                          <div className="report-toc-pi__method-name">{mName}</div>
                          <dl className="report-toc-pi__method-dl">
                            {lines.map((line, i) => (
                              <React.Fragment key={i}>
                                <dt>{line.label}</dt>
                                <dd>{line.value}</dd>
                              </React.Fragment>
                            ))}
                          </dl>
                        </div>
                      );
                    })}
                  </div>
                )}
              </div>
            );
          })}
        </div>
      );
    });
  };

  /* ---- Ethics renderer ------------------------------------------------- */
  const step4 = steps.find(s => s.id === "step4");
  const renderEthics = () => {
    if (!step4) return null;
    return step4.lessons.map(lesson => {
      if (naState && naState[lesson.id]) return null;
      const anyFilled = lesson.prompts.some(p => isPromptAnswered(p, answers[p.id]));
      if (!anyFilled) return null;
      return (
        <div key={lesson.id} className="rpt-ethics-group">
          <div className="rpt-ethics-group__title">{lesson.title}</div>
          {lesson.prompts.map(p => (
            <RptField key={p.id} prompt={p} answer={answers[p.id]} />
          ))}
        </div>
      );
    });
  };

  /* ---- Render ---------------------------------------------------------- */
  return (
    <div className="report-shell">
      <div className="report-toolbar">
        <Btn variant="ghost" icon="arrow-l" onClick={onBack}>Back to toolkit</Btn>
        <div style={{ flex: 1 }} />
        <Btn variant="ghost" icon="doc" onClick={handleWordExport}>Export to Word</Btn>
        <Btn variant="dark" icon="print" onClick={handlePrint}>Save as PDF</Btn>
      </div>

      <div className="report-wrap">
        <div className="report-header">
          <div>
            <div className="report-header__eyebrow">ISD MEL Framework · Draft Report</div>
            <h1 className="report-header__title">{projectName || "Untitled MEL plan"}</h1>
          </div>
          <div className="report-header__logo">
            <img src="assets/isd-logo.png" alt="ISD" />
          </div>
        </div>

        {/* 1. Project Overview */}
        {hasAny("problem","antisemitism_def","expressions","scope","audience","beneficiaries","context_factors","context_detail") && (
          <section className="rpt-section">
            <h2 className="rpt-section__title">Project Overview</h2>
            {fld("problem",            "Problem statement")}
            {fld("antisemitism_def",   "Definition of antisemitism")}
            {fld("expressions",        "Expressions addressed")}
            {fld("scope",              "Scope")}
            {fld("audience",           "Target audience")}
            {fld("beneficiaries",      "Beneficiaries")}
            {fld("context_factors",    "Contextual factors")}
            {fld("context_detail",     "Context detail")}
          </section>
        )}

        {/* 2. Theory of Change */}
        {isPromptAnswered(promptMap["toc"], toc) && (
          <section className="rpt-section">
            <h2 className="rpt-section__title">Theory of Change</h2>
            <ReportAnswer prompt={promptMap["toc"]} answer={toc} />
          </section>
        )}

        {/* 3. Baseline */}
        {hasAny("baseline_types","baseline_plan","prior_trends") && (
          <section className="rpt-section">
            <h2 className="rpt-section__title">Baseline</h2>
            {fld("baseline_types", "Baseline types")}
            {fld("baseline_plan",  "Collection plan")}
            {fld("prior_trends",   "Prior trends")}
          </section>
        )}

        {/* 4. Results Framework */}
        <section className="rpt-section">
          <h2 className="rpt-section__title">Results Framework</h2>
          {renderResultsFramework()}
        </section>

        {/* 5. Data Collection Design */}
        {hasAny("sampling_tree","sample_size","control_group") && (
          <section className="rpt-section">
            <h2 className="rpt-section__title">Data Collection Design</h2>
            {fld("sampling_tree", "Sampling approach")}
            {fld("sample_size",   "Target sample size")}
            {fld("control_group", "Control group")}
          </section>
        )}

        {/* 6. Ethics & Quality */}
        {step4 && step4.lessons.some(l => l.prompts.some(p => isPromptAnswered(p, answers[p.id]))) && (
          <section className="rpt-section">
            <h2 className="rpt-section__title">Ethics & Quality</h2>
            {renderEthics()}
          </section>
        )}

        <div style={{ marginTop: 48, paddingTop: 24, borderTop: "1px solid var(--border-soft)", display: "flex", justifyContent: "space-between", alignItems: "center", gap: 16, flexWrap: "wrap" }}>
          <div style={{ fontSize: 12, color: "var(--fg-3)", maxWidth: 480 }}>
            This report is a planning artefact. Refer to ISD's <em>Evaluating Projects to Counter Online Antisemitism</em> for full framework guidance.
          </div>
          <Btn variant="primary" icon="pencil" onClick={onBack}>Continue editing</Btn>
        </div>
      </div>
    </div>
  );
}

window.ReportView = ReportView;
