/* AI Menu - filterable. */
const { useState, useMemo } = React;

const DATA_LEVELS = ["Low", "Medium", "High"];
const PROBLEM_TYPES = ["Manual workloads", "Data analysis", "Forecasting", "Prioritisation", "Citizen response", "Institutional knowledge", "Policy evaluation", "Data accessibility"];
const APPROACHES = ["Text", "Prediction", "Anomaly", "Vision", "Optimisation", "Digitisation", "Dashboards", "Agents"];

const ENTRIES = [
  {
    id: "supervised-ml", method: "Supervised ML",
    title: "Prediction & Classification",
    what: "Trains on labelled historical data to predict an outcome or assign inputs to a category. Surfaces which factors matter most for targeting and resource allocation.",
    methods: ["Regression", "Risk scoring", "Propensity models"],
    data: "High", approach: ["Prediction"], problems: ["Prioritisation", "Forecasting", "Data analysis"],
    examples: [
      "Tax non-compliance risk scoring for audit prioritisation",
      "Social programme fraud and duplicate beneficiary detection",
      "Student dropout risk identification for targeted intervention"
    ],
    cases: ["Paraguay customs fraud detection", "Customs targeting RCT"]
  },
  {
    id: "clustering", method: "Unsupervised ML",
    title: "Clustering & Segmentation",
    what: "Finds natural groupings in data without predefined labels. Useful for understanding population heterogeneity without prior assumptions.",
    methods: ["K-means", "Dimensionality reduction", "Similarity matching"],
    data: "Medium", approach: ["Prediction"], problems: ["Data analysis", "Prioritisation"],
    examples: [
      "Citizen segmentation for differentiated service delivery",
      "Grouping tax filers by behavioural profile",
      "Identifying clusters of non-compliance patterns across districts"
    ]
  },
  {
    id: "anomaly", method: "Unsupervised ML",
    title: "Anomaly Detection",
    what: "Flags data points that deviate significantly from expected patterns without requiring labelled fraud cases. Powerful for oversight and integrity work at scale.",
    methods: ["Outlier detection", "Isolation forests", "Network analysis"],
    data: "Medium", approach: ["Anomaly"], problems: ["Data analysis", "Policy evaluation"],
    examples: [
      "Procurement spending outliers and suspicious award patterns",
      "Payroll ghost-worker identification",
      "Meter reading anomalies (e.g. electricity theft)"
    ],
    cases: ["ZESCO electricity-loss targeting"]
  },
  {
    id: "forecasting", method: "Time-series",
    title: "Forecasting & Nowcasting",
    what: "Models how indicators evolve over time to anticipate future values and support planning. Spans statistical models, ML, and physics-informed neural networks.",
    methods: ["ARIMA", "LSTMs", "Physics-informed NNs", "Scenario projections"],
    data: "Medium", approach: ["Prediction"], problems: ["Forecasting", "Policy evaluation"],
    examples: [
      "Crop yield forecasting for food security planning",
      "Electricity demand and loss forecasting",
      "Tax revenue projections for fiscal planning",
      "Disease surveillance and outbreak nowcasting"
    ],
    cases: ["Zambia crop yield forecasting", "Mozambique flood forecasting"]
  },
  {
    id: "llm-classify", method: "LLM",
    title: "Classifying Unstructured Text",
    what: "Uses large language models to assign free-text inputs to categories. Requires few labelled examples, handles messy or multilingual text, and applies complex taxonomies.",
    methods: ["Zero/few-shot", "Fine-tuning", "Chain-of-thought", "Structured output"],
    data: "Low", approach: ["Text"], problems: ["Manual workloads", "Citizen response", "Data analysis"],
    examples: [
      "Coding open-ended survey responses to occupational taxonomies",
      "Citizen complaint and petition categorisation and routing",
      "Court ruling classification by outcome and legal domain"
    ],
    cases: ["Zambia Labour Force Survey", "India environmental court rulings", "Zambia citizen services"]
  },
  {
    id: "rag", method: "LLM",
    title: "AI-Powered Search",
    what: "Turns a government's own documents into a searchable, queryable knowledge base. Ask questions in plain language and get answers grounded in official sources.",
    methods: ["RAG", "Semantic search", "Citation-backed Q&A"],
    data: "Low", approach: ["Text"], problems: ["Institutional knowledge", "Manual workloads"],
    examples: [
      "Internal policy assistant for civil servants",
      "Q&A over legal frameworks grounded in official documents",
      "Cross-ministry document search and consistency checking"
    ]
  },
  {
    id: "llm-textgen", method: "LLM",
    title: "Text Analysis & Generation",
    what: "Summarises, extracts structured information from, or drafts new content. Reduces analyst time on routine processing tasks.",
    methods: ["Summarisation", "Extraction", "Translation", "Draft generation"],
    data: "Low", approach: ["Text"], problems: ["Manual workloads", "Data analysis"],
    examples: [
      "Summarisation of policy documents and parliamentary proceedings",
      "Extraction of commitments and deadlines from government reports",
      "Cross-language document analysis"
    ],
    cases: ["Reform monitoring dashboard"]
  },
  {
    id: "chatbots", method: "LLM",
    title: "Chatbots",
    what: "Conversational interfaces that let citizens or civil servants interact with government services in natural language. Handle queries and route requests at scale.",
    methods: ["Conversational AI", "Intent detection", "Multilingual"],
    data: "Low", approach: ["Text"], problems: ["Citizen response", "Institutional knowledge"],
    examples: [
      "Citizen service chatbot handling tax, benefit, and permit queries",
      "Internal HR and policy guidance assistant for civil servants",
      "Agricultural chatbot providing advice to farmers"
    ]
  },
  {
    id: "vision", method: "Computer Vision",
    title: "Computer Vision",
    what: "Extracts structured information from satellite, aerial, or drone imagery at scale for area-wide monitoring at a fraction of field-survey cost.",
    methods: ["Object detection", "Change detection", "Segmentation", "Remote sensing"],
    data: "High", approach: ["Vision"], problems: ["Data analysis", "Policy evaluation"],
    examples: [
      "Building detection and change monitoring for property tax registers",
      "Informal settlement mapping for urban planning",
      "Crop health and stress detection",
      "Post-disaster damage detection from aerial imagery"
    ],
    cases: ["Pakistan property tax", "Rwanda CAMA property tax"]
  },
  {
    id: "optim", method: "Optimisation",
    title: "Optimisation & Decision Support",
    what: "Finds the best allocation of resources under constraints. Generates options and trade-offs for humans to review and decide.",
    methods: ["Linear programming", "Simulation", "Multi-objective optimisation"],
    data: "Medium", approach: ["Optimisation"], problems: ["Prioritisation", "Forecasting"],
    examples: [
      "Health worker and school inspector deployment scheduling",
      "Procurement lot design to maximise competition",
      "School and clinic placement under coverage constraints"
    ]
  },
  {
    id: "digitisation", method: "Digitisation",
    title: "Records Digitisation",
    what: "Converts paper-based records into structured digital data using OCR and extraction models. A foundational step that unlocks most other AI use cases.",
    methods: ["OCR", "Handwriting recognition", "Form extraction"],
    data: "Low", approach: ["Digitisation"], problems: ["Data accessibility", "Manual workloads"],
    examples: [
      "Land registry and property title digitisation",
      "Handwritten census and administrative form extraction",
      "Birth, death, and civil registration record structuring"
    ],
    cases: ["Zambia maize export permits"]
  },
  {
    id: "dashboards", method: "Data products",
    title: "Dashboards & Monitoring",
    what: "Makes model outputs and administrative data accessible to decision-makers through visual interfaces. The bridge between technical systems and government action.",
    methods: ["KPI tracking", "Interactive viz", "Automated reporting", "Alert systems"],
    data: "Medium", approach: ["Dashboards"], problems: ["Policy evaluation", "Data analysis"],
    examples: [
      "Reform monitoring dashboards with KPI drill-downs",
      "Beneficiary tracking dashboards for social programmes",
      "Automated monthly statistical reporting for ministries"
    ],
    cases: ["Tax & power monitoring dashboard"]
  },
  {
    id: "agents", method: "Agents",
    title: "AI Agents",
    what: "AI systems that take sequences of actions autonomously to complete multi-step workflows with minimal human intervention. An emerging capability.",
    methods: ["Agentic LLMs", "Tool use", "Multi-agent orchestration"],
    data: "Medium", approach: ["Agents"], problems: ["Manual workloads", "Citizen response"],
    examples: [
      "Automated report drafting pipelines",
      "Multi-step procurement compliance checks",
      "Intelligent routing of citizen requests across departments"
    ]
  }
];

function FilterPills({ label, options, value, onChange }) {
  return (
    <div className="filter-group">
      <h5>{label}</h5>
      <div className="filter-pills">
        {options.map((o) => {
          const on = value.includes(o);
          return (
            <button key={o} className={"pill" + (on ? " is-on" : "")} onClick={() => {
              onChange(on ? value.filter((v) => v !== o) : [...value, o]);
            }}>{o}{on && <span className="x">×</span>}</button>
          );
        })}
      </div>
    </div>
  );
}

function Menu() {
  const [search, setSearch] = useState("");
  const [problems, setProblems] = useState([]);
  const [data, setData] = useState([]);
  const [approach, setApproach] = useState([]);

  const filtered = useMemo(() => ENTRIES.filter((e) => {
    if (problems.length && !problems.some((p) => e.problems.includes(p))) return false;
    if (data.length && !data.includes(e.data)) return false;
    if (approach.length && !approach.some((a) => e.approach.includes(a))) return false;
    if (search.trim()) {
      const s = search.toLowerCase();
      const blob = (e.method + " " + e.title + " " + e.what + " " + e.examples.join(" ") + " " + (e.cases || []).join(" ")).toLowerCase();
      if (!blob.includes(s)) return false;
    }
    return true;
  }), [search, problems, data, approach]);

  const totalActive = problems.length + data.length + approach.length;
  const clearAll = () => { setProblems([]); setData([]); setApproach([]); setSearch(""); };

  return (
    <div>
      <div className="menu-toolbar">
        <label className="menu-search">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="11" cy="11" r="8"></circle><path d="m21 21-4.3-4.3"></path></svg>
          <input type="search" placeholder="Search methods, examples, case studies…" value={search} onChange={(e) => setSearch(e.target.value)} />
        </label>
        <span className="menu-count"><strong>{filtered.length}</strong> of {ENTRIES.length} approaches</span>
      </div>

      <div className="menu-filters">
        <FilterPills label="Problem type" options={PROBLEM_TYPES} value={problems} onChange={setProblems} />
        <FilterPills label="Data requirement" options={DATA_LEVELS} value={data} onChange={setData} />
        <FilterPills label="Approach family" options={APPROACHES} value={approach} onChange={setApproach} />
      </div>

      {totalActive > 0 && (
        <div className="active-filters">
          <span className="label">Active:</span>
          {[...problems, ...data.map((d) => d + " data"), ...approach].map((t) => <span key={t} className="chip">{t}</span>)}
          <button className="clear" onClick={clearAll}>Clear all</button>
        </div>
      )}

      {filtered.length === 0 ? (
        <div className="empty">No approaches match your filters. <button className="btn btn--ghost btn--sm" onClick={clearAll}>Clear filters</button></div>
      ) : (
        <div className="menu-grid">
          {filtered.map((e) => (
            <article key={e.id} className="menu-card">
              <div className="meta">
                <span className="method-tag">{e.method}</span>
                <span className={"data-level data-level--" + e.data.toLowerCase()} aria-label={"Data requirement: " + e.data}>
                  <span className="data-level-bars" aria-hidden="true">
                    <i className={e.data === "Low" || e.data === "Medium" || e.data === "High" ? "on" : ""}></i>
                    <i className={e.data === "Medium" || e.data === "High" ? "on" : ""}></i>
                    <i className={e.data === "High" ? "on" : ""}></i>
                  </span>
                  <span className="data-level-text">{e.data} data</span>
                </span>
              </div>
              <h3>{e.title}</h3>
              <p className="what">{e.what}</p>
              <div className="examples">
                <div className="examples-h">Government examples</div>
                <ul>{e.examples.slice(0, 3).map((x, i) => <li key={i}>{x}</li>)}</ul>
              </div>
              {e.cases && (
                <div className="footer">
                  <span style={{fontSize: 12, color: "var(--igc-grey-700)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.12em"}}>IGC case studies</span>
                  <span style={{fontSize: 13, color: "var(--igc-purple)"}}>{e.cases.join(", ")}</span>
                </div>
              )}
            </article>
          ))}
        </div>
      )}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("menu-root")).render(<Menu />);
