import React, { useState, useEffect, useRef, useCallback } from "react";
import { createRoot } from "react-dom/client";
import {
  LayoutDashboard, Microscope, ClipboardCheck, Radar, ListTodo, UserCircle,
  Plus, Sparkles, TrendingUp, TrendingDown, Minus, Upload, X, Check, ChevronRight,
  Building2, Target, Palette, Users, Megaphone, FileText, Search, Loader2,
  AlertTriangle, CheckCircle2, Circle, Clock, Wrench, Globe, Presentation,
  Trash2, Edit3, Save, LogOut, Eye, Flag, ArrowUpRight, Briefcase, Zap
} from "lucide-react";

const LOGO = "data:image/png;base64,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";

/* ============================== THEME ============================== */
const C = {
  yellow: "#F9C112",
  yellowDark: "#E0A800",
  ink: "#1C1C1A",
  ink2: "#2A2A27",
  paper: "#FAFAF7",
  card: "#FFFFFF",
  line: "#E9E7E0",
  muted: "#8A877E",
  good: "#2E9E5B",
  bad: "#D8513B",
  blue: "#3E6FB0",
};

const FONT_DISPLAY = "'Space Grotesk', system-ui, sans-serif";
const FONT_BODY = "'Inter', system-ui, sans-serif";

/* ============================== STORAGE ============================== */
const store = {
  async get(key, def) {
    try {
      const r = await fetch("/api/store/" + encodeURIComponent(key), { credentials: "include" });
      if (!r.ok) return def;
      const d = await r.json();
      return d.value === null || d.value === undefined ? def : d.value;
    } catch { return def; }
  },
  async set(key, value) {
    try {
      await fetch("/api/store/" + encodeURIComponent(key), {
        method: "PUT", credentials: "include",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ value }),
      });
    } catch (e) { console.error(e); }
  },
};

/* ============================== AI ============================== */
async function callAI(prompt, { json = false, system = "" } = {}) {
  const res = await fetch("/api/ai", {
    method: "POST", credentials: "include",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ prompt, system, json }),
  });
  if (!res.ok) {
    if (res.status === 401) { window.location.reload(); return json ? null : ""; }
    return json ? null : "Er ging iets mis bij de AI-aanroep.";
  }
  const data = await res.json();
  const text = data.text || "";
  if (!json) return text;
  const clean = text.replace(/```json/g, "").replace(/```/g, "").trim();
  try { return JSON.parse(clean); } catch {
    const m = clean.match(/[\{\[][\s\S]*[\}\]]/);
    if (m) { try { return JSON.parse(m[0]); } catch {} }
    return null;
  }
}

/* ============================== UI PRIMITIVES ============================== */
const Btn = ({ children, onClick, variant = "primary", size = "md", icon: Icon, disabled, style }) => {
  const base = {
    display: "inline-flex", alignItems: "center", gap: 8, border: "none", cursor: disabled ? "not-allowed" : "pointer",
    fontFamily: FONT_BODY, fontWeight: 600, borderRadius: 10, transition: "all .15s ease",
    opacity: disabled ? 0.5 : 1,
    padding: size === "sm" ? "7px 12px" : "11px 18px", fontSize: size === "sm" ? 13 : 14.5,
  };
  const variants = {
    primary: { background: C.ink, color: "#fff" },
    yellow: { background: C.yellow, color: C.ink },
    ghost: { background: "transparent", color: C.ink, border: `1.5px solid ${C.line}` },
    danger: { background: "transparent", color: C.bad, border: `1.5px solid ${C.bad}33` },
  };
  return (
    <button onClick={disabled ? undefined : onClick} style={{ ...base, ...variants[variant], ...style }}
      onMouseEnter={e => !disabled && (e.currentTarget.style.transform = "translateY(-1px)")}
      onMouseLeave={e => (e.currentTarget.style.transform = "translateY(0)")}>
      {Icon && <Icon size={size === "sm" ? 15 : 17} />} {children}
    </button>
  );
};

const Card = ({ children, style, onClick, hover }) => (
  <div onClick={onClick} style={{
    background: C.card, border: `1px solid ${C.line}`, borderRadius: 16, padding: 20,
    cursor: onClick ? "pointer" : "default", transition: "all .18s ease", ...style,
  }}
    onMouseEnter={e => hover && (e.currentTarget.style.boxShadow = "0 8px 28px rgba(0,0,0,.08)", e.currentTarget.style.borderColor = C.yellow)}
    onMouseLeave={e => hover && (e.currentTarget.style.boxShadow = "none", e.currentTarget.style.borderColor = C.line)}>
    {children}
  </div>
);

const Tag = ({ children, color = C.muted, bg }) => (
  <span style={{ fontSize: 11.5, fontWeight: 700, color, background: bg || color + "18", padding: "3px 9px", borderRadius: 20, letterSpacing: .2 }}>{children}</span>
);

const Field = ({ label, value, onChange, multiline, placeholder, rows = 3 }) => (
  <div style={{ marginBottom: 16 }}>
    <label style={{ display: "block", fontSize: 12.5, fontWeight: 700, color: C.muted, marginBottom: 6, letterSpacing: .3, textTransform: "uppercase" }}>{label}</label>
    {multiline
      ? <textarea value={value || ""} onChange={e => onChange(e.target.value)} placeholder={placeholder} rows={rows}
          style={{ width: "100%", boxSizing: "border-box", padding: "11px 13px", border: `1.5px solid ${C.line}`, borderRadius: 10, fontFamily: FONT_BODY, fontSize: 14, resize: "vertical", outline: "none", color: C.ink, lineHeight: 1.5 }}
          onFocus={e => e.target.style.borderColor = C.yellow} onBlur={e => e.target.style.borderColor = C.line} />
      : <input value={value || ""} onChange={e => onChange(e.target.value)} placeholder={placeholder}
          style={{ width: "100%", boxSizing: "border-box", padding: "11px 13px", border: `1.5px solid ${C.line}`, borderRadius: 10, fontFamily: FONT_BODY, fontSize: 14, outline: "none", color: C.ink }}
          onFocus={e => e.target.style.borderColor = C.yellow} onBlur={e => e.target.style.borderColor = C.line} />}
  </div>
);

const Spinner = ({ label }) => (
  <div style={{ display: "flex", alignItems: "center", gap: 10, color: C.muted, fontSize: 14, padding: 12 }}>
    <Loader2 size={18} className="spin" style={{ animation: "spin 1s linear infinite" }} /> {label || "AI is aan het werk…"}
  </div>
);

const AIBadge = () => (
  <span style={{ display: "inline-flex", alignItems: "center", gap: 4, fontSize: 11, fontWeight: 700, color: C.ink, background: C.yellow, padding: "2px 8px", borderRadius: 20 }}>
    <Sparkles size={11} /> AI
  </span>
);

const Empty = ({ icon: Icon, title, sub }) => (
  <div style={{ textAlign: "center", padding: "48px 20px", color: C.muted }}>
    {Icon && <Icon size={36} style={{ opacity: .4, marginBottom: 12 }} />}
    <div style={{ fontWeight: 700, color: C.ink2, fontSize: 15 }}>{title}</div>
    {sub && <div style={{ fontSize: 13.5, marginTop: 4 }}>{sub}</div>}
  </div>
);

/* ============================== LOGIN ============================== */
function Login({ onLogin }) {
  const [u, setU] = useState(""); const [p, setP] = useState(""); const [err, setErr] = useState("");
  const [loading, setLoading] = useState(false);
  const submit = async () => {
    setErr(""); setLoading(true);
    try {
      const r = await fetch("/api/login", {
        method: "POST", credentials: "include",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ username: u, password: p }),
      });
      if (r.ok) onLogin();
      else setErr("Onjuiste inloggegevens.");
    } catch { setErr("Kan geen verbinding maken met de server."); }
    setLoading(false);
  };
  return (
    <div style={{ minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center", background: C.ink, fontFamily: FONT_BODY, position: "relative", overflow: "hidden" }}>
      <div style={{ position: "absolute", inset: 0, background: `radial-gradient(circle at 30% 20%, ${C.yellow}22, transparent 45%), radial-gradient(circle at 80% 80%, ${C.yellow}11, transparent 40%)` }} />
      <div style={{ position: "relative", background: C.card, borderRadius: 24, padding: 40, width: 380, boxShadow: "0 30px 80px rgba(0,0,0,.4)" }}>
        <img src={LOGO} alt="whitevision" style={{ height: 38, marginBottom: 26 }} />
        <div style={{ fontFamily: FONT_DISPLAY, fontSize: 23, fontWeight: 700, color: C.ink, letterSpacing: -.5 }}>Brand Command Center</div>
        <div style={{ fontSize: 13.5, color: C.muted, marginTop: 4, marginBottom: 26 }}>Het AI-aangedreven werkstation voor de brand manager.</div>
        <Field label="Gebruikersnaam" value={u} onChange={setU} placeholder="admin" />
        <div style={{ marginBottom: 8 }}>
          <label style={{ display: "block", fontSize: 12.5, fontWeight: 700, color: C.muted, marginBottom: 6, letterSpacing: .3, textTransform: "uppercase" }}>Wachtwoord</label>
          <input type="password" value={p} onChange={e => setP(e.target.value)} onKeyDown={e => e.key === "Enter" && submit()} placeholder="••••"
            style={{ width: "100%", boxSizing: "border-box", padding: "11px 13px", border: `1.5px solid ${C.line}`, borderRadius: 10, fontFamily: FONT_BODY, fontSize: 14, outline: "none" }}
            onFocus={e => e.target.style.borderColor = C.yellow} onBlur={e => e.target.style.borderColor = C.line} />
        </div>
        {err && <div style={{ color: C.bad, fontSize: 13, marginTop: 8, fontWeight: 600 }}>{err}</div>}
        <div style={{ marginTop: 22 }}>
          <Btn variant="yellow" onClick={submit} disabled={loading} style={{ width: "100%", justifyContent: "center" }} icon={Zap}>{loading ? "Bezig…" : "Inloggen"}</Btn>
        </div>
        <div style={{ fontSize: 11.5, color: C.muted, marginTop: 16, textAlign: "center" }}>Veilig ingelogd — sessie via de server</div>
      </div>
    </div>
  );
}

/* ============================== APP SHELL ============================== */
const NAV = [
  { id: "dashboard", label: "Dashboard", icon: LayoutDashboard },
  { id: "research", label: "Onderzoek", icon: Microscope },
  { id: "audit", label: "Audit", icon: ClipboardCheck },
  { id: "monitor", label: "Monitor", icon: Radar },
  { id: "actions", label: "Acties", icon: ListTodo },
  { id: "profile", label: "Merkprofiel", icon: UserCircle },
];

function App() {
  const [authed, setAuthed] = useState(false);
  const [authChecked, setAuthChecked] = useState(false);
  const [tab, setTab] = useState("dashboard");
  const [loaded, setLoaded] = useState(false);

  useEffect(() => {
    fetch("/api/me", { credentials: "include" })
      .then(r => r.json())
      .then(d => { if (d.authed) setAuthed(true); })
      .catch(() => {})
      .finally(() => setAuthChecked(true));
  }, []);

  // central shared state
  const [profile, setProfile] = useState(null);
  const [metrics, setMetrics] = useState(null);
  const [research, setResearch] = useState(null);
  const [audits, setAudits] = useState(null);
  const [monitors, setMonitors] = useState(null);
  const [actions, setActions] = useState(null);
  const [companies, setCompanies] = useState(null);
  const [users, setUsers] = useState(null);

  useEffect(() => {
    (async () => {
      setProfile(await store.get("wv_profile", DEFAULT_PROFILE));
      setMetrics(await store.get("wv_metrics", DEFAULT_METRICS));
      setResearch(await store.get("wv_research", []));
      setAudits(await store.get("wv_audits", []));
      setMonitors(await store.get("wv_monitors", []));
      setActions(await store.get("wv_actions", []));
      setCompanies(await store.get("wv_companies", DEFAULT_COMPANIES));
      setUsers(await store.get("wv_users", DEFAULT_USERS));
      setLoaded(true);
    })();
  }, []);

  // persisters
  const saveProfile = v => { setProfile(v); store.set("wv_profile", v); };
  const saveMetrics = v => { setMetrics(v); store.set("wv_metrics", v); };
  const saveResearch = v => { setResearch(v); store.set("wv_research", v); };
  const saveAudits = v => { setAudits(v); store.set("wv_audits", v); };
  const saveMonitors = v => { setMonitors(v); store.set("wv_monitors", v); };
  const saveActions = v => { setActions(v); store.set("wv_actions", v); };
  const saveCompanies = v => { setCompanies(v); store.set("wv_companies", v); };
  const saveUsers = v => { setUsers(v); store.set("wv_users", v); };

  const addAction = (a) => {
    const next = [{ id: Date.now() + Math.random(), status: "todo", createdAt: Date.now(), ...a }, ...(actions || [])];
    saveActions(next);
  };

  if (!authChecked) return (<><GlobalCSS /><div style={{ minHeight: "100vh", display: "grid", placeItems: "center", background: C.ink }} /></>);
  if (!authed) return (<><GlobalCSS /><Login onLogin={() => setAuthed(true)} /></>);
  if (!loaded) return (<><GlobalCSS /><div style={{ minHeight: "100vh", display: "grid", placeItems: "center", background: C.paper }}><Spinner label="Werkstation laden…" /></div></>);

  const ctx = {
    profile, saveProfile, metrics, saveMetrics, research, saveResearch,
    audits, saveAudits, monitors, saveMonitors, actions, saveActions,
    companies, saveCompanies, users, saveUsers, addAction, goTo: setTab,
  };

  return (
    <>
      <GlobalCSS />
      <div style={{ display: "flex", minHeight: "100vh", background: C.paper, fontFamily: FONT_BODY, color: C.ink }}>
        {/* Sidebar */}
        <aside style={{ width: 232, background: C.ink, display: "flex", flexDirection: "column", padding: "22px 16px", position: "sticky", top: 0, height: "100vh", boxSizing: "border-box" }}>
          <div style={{ background: "#fff", borderRadius: 12, padding: "12px 14px", marginBottom: 26 }}>
            <img src={LOGO} alt="whitevision" style={{ height: 26, display: "block" }} />
          </div>
          <nav style={{ display: "flex", flexDirection: "column", gap: 4, flex: 1 }}>
            {NAV.map(n => {
              const active = tab === n.id;
              const isProfile = n.id === "profile";
              return (
                <button key={n.id} onClick={() => setTab(n.id)} style={{
                  display: "flex", alignItems: "center", gap: 11, padding: "11px 13px", borderRadius: 10, border: "none",
                  cursor: "pointer", fontFamily: FONT_BODY, fontSize: 14.5, fontWeight: active ? 700 : 500, textAlign: "left",
                  background: active ? (isProfile ? C.yellow : "#ffffff14") : "transparent",
                  color: active ? (isProfile ? C.ink : "#fff") : "#B9B7B0",
                  marginTop: isProfile ? "auto" : 0,
                }}>
                  <n.icon size={18} /> {n.label}
                </button>
              );
            })}
          </nav>
          <button onClick={async () => { try { await fetch("/api/logout", { method: "POST", credentials: "include" }); } catch {} setAuthed(false); }} style={{ display: "flex", alignItems: "center", gap: 10, padding: "10px 13px", borderRadius: 10, border: "none", background: "transparent", color: "#8A877E", cursor: "pointer", fontFamily: FONT_BODY, fontSize: 13.5, marginTop: 12 }}>
            <LogOut size={16} /> Uitloggen
          </button>
        </aside>

        {/* Main */}
        <main style={{ flex: 1, padding: "30px 38px", maxWidth: 1180, margin: "0 auto", width: "100%", boxSizing: "border-box" }}>
          {tab === "dashboard" && <Dashboard ctx={ctx} />}
          {tab === "research" && <Research ctx={ctx} />}
          {tab === "audit" && <Audit ctx={ctx} />}
          {tab === "monitor" && <Monitor ctx={ctx} />}
          {tab === "actions" && <Actions ctx={ctx} />}
          {tab === "profile" && <Profile ctx={ctx} />}
        </main>
      </div>
    </>
  );
}

const GlobalCSS = () => (
  <style>{`
    @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=Inter:wght@400;500;600;700&display=swap');
    * { box-sizing: border-box; }
    @keyframes spin { to { transform: rotate(360deg); } }
    @keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
    ::-webkit-scrollbar { width: 9px; height: 9px; }
    ::-webkit-scrollbar-thumb { background: #d8d6cf; border-radius: 6px; }
  `}</style>
);

/* ============================== DEFAULT DATA ============================== */
const DEFAULT_PROFILE = {
  filled: false,
  proposition: "",
  goals: "",
  usps: "",
  products: "",
  tone: "",
  icps: "",
  colors: "#F9C112, #1C1C1A",
  competitors: "",
  notes: "",
};
const DEFAULT_METRICS = [
  { id: 1, label: "Merkbekendheid (unaided)", value: 22, unit: "%", prev: 18, target: 40 },
  { id: 2, label: "Share of Voice", value: 14, unit: "%", prev: 11, target: 25 },
  { id: 3, label: "NPS", value: 41, unit: "", prev: 38, target: 55 },
  { id: 4, label: "Merkperceptie (favorability)", value: 67, unit: "%", prev: 64, target: 75 },
  { id: 5, label: "Overgenomen bedrijven", value: 6, unit: "", prev: 4, target: 10 },
  { id: 6, label: "Geïntegreerde merken", value: 3, unit: "", prev: 2, target: 6 },
];
const DEFAULT_COMPANIES = [];
const DEFAULT_USERS = [
  { id: 1, name: "Admin", email: "admin@whitevision.com", role: "Brand Manager" },
];

/* ============================== SHARED: Action capture ============================== */
function Insights({ items, onAction, prefix }) {
  if (!items || !items.length) return null;
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 10, marginTop: 14 }}>
      {items.map((it, i) => {
        const sev = (it.severity || it.type || "").toLowerCase();
        const col = sev.includes("hoog") || sev.includes("kans") || sev.includes("risico") ? C.bad : sev.includes("midden") ? C.yellowDark : C.blue;
        return (
          <div key={i} style={{ display: "flex", gap: 12, alignItems: "flex-start", padding: "13px 15px", background: C.paper, borderRadius: 12, border: `1px solid ${C.line}` }}>
            <div style={{ width: 7, height: 7, borderRadius: 8, background: col, marginTop: 7, flexShrink: 0 }} />
            <div style={{ flex: 1 }}>
              {it.title && <div style={{ fontWeight: 700, fontSize: 14, marginBottom: 2 }}>{it.title}</div>}
              <div style={{ fontSize: 13.5, color: C.ink2, lineHeight: 1.5 }}>{it.text || it.suggestion || it.detail}</div>
              {it.tag && <div style={{ marginTop: 6 }}><Tag color={col}>{it.tag}</Tag></div>}
            </div>
            <button onClick={() => onAction({ title: it.title || (prefix + ": actie"), detail: it.text || it.suggestion || it.detail, source: prefix })}
              style={{ flexShrink: 0, display: "inline-flex", alignItems: "center", gap: 5, fontSize: 12.5, fontWeight: 700, color: C.ink, background: C.yellow, border: "none", padding: "6px 11px", borderRadius: 8, cursor: "pointer" }}>
              <Flag size={13} /> Actie
            </button>
          </div>
        );
      })}
    </div>
  );
}

function PageHead({ title, sub, right }) {
  return (
    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", marginBottom: 24, animation: "fadeUp .3s ease" }}>
      <div>
        <h1 style={{ fontFamily: FONT_DISPLAY, fontSize: 28, fontWeight: 700, margin: 0, letterSpacing: -.6 }}>{title}</h1>
        {sub && <p style={{ color: C.muted, fontSize: 14.5, margin: "5px 0 0" }}>{sub}</p>}
      </div>
      {right}
    </div>
  );
}

function profileContext(p) {
  if (!p || !p.filled) return "Het merkprofiel is nog niet ingevuld. Werk met algemene aannames over whitevision (AI-driven IDP, buy-and-build, P2P/spend/contractmanagement).";
  return `MERKPROFIEL whitevision (kennisbasis om tegen te spiegelen):
- Propositie: ${p.proposition}
- Doelstellingen: ${p.goals}
- USP's: ${p.usps}
- Producten: ${p.products}
- Tone of voice: ${p.tone}
- ICP's: ${p.icps}
- Huisstijlkleuren: ${p.colors}
- Bekende concurrenten: ${p.competitors}`;
}

/* ============================== 1. DASHBOARD ============================== */
function Dashboard({ ctx }) {
  const { metrics, saveMetrics, actions, research, audits, monitors, profile } = ctx;
  const [editing, setEditing] = useState(false);
  const [summary, setSummary] = useState("");
  const [busy, setBusy] = useState(false);

  const trend = (m) => {
    const d = m.value - m.prev;
    return { d, up: d > 0, flat: d === 0 };
  };
  const updateMetric = (id, field, val) => {
    saveMetrics(metrics.map(m => m.id === id ? { ...m, [field]: field === "label" || field === "unit" ? val : Number(val) } : m));
  };
  const addMetric = () => saveMetrics([...metrics, { id: Date.now(), label: "Nieuwe metric", value: 0, unit: "", prev: 0, target: 0 }]);
  const delMetric = (id) => saveMetrics(metrics.filter(m => m.id !== id));

  const genSummary = async () => {
    setBusy(true);
    const data = metrics.map(m => `${m.label}: ${m.value}${m.unit} (vorige ${m.prev}${m.unit}, doel ${m.target}${m.unit})`).join("; ");
    const r = await callAI(`${profileContext(profile)}\n\nHier zijn de actuele merk-KPI's: ${data}.\n\nSchrijf een beknopte management-samenvatting (max 5 zinnen) voor de CCO: wat valt op, waar zit momentum, waar is aandacht nodig richting de doelen. Zakelijk en concreet.`);
    setSummary(r); setBusy(false);
  };

  const openActions = (actions || []).filter(a => a.status !== "done").length;

  return (
    <div>
      <PageHead title="Dashboard" sub="De staat van het merk in één oogopslag."
        right={<Btn variant={editing ? "yellow" : "ghost"} size="sm" icon={editing ? Save : Edit3} onClick={() => setEditing(!editing)}>{editing ? "Klaar" : "Metrics bewerken"}</Btn>} />

      {/* quick stats */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 14, marginBottom: 22 }}>
        {[
          { l: "Openstaande acties", v: openActions, i: ListTodo },
          { l: "Onderzoeken", v: (research || []).length, i: Microscope },
          { l: "Audits", v: (audits || []).length, i: ClipboardCheck },
          { l: "Actieve monitors", v: (monitors || []).length, i: Radar },
        ].map((s, i) => (
          <Card key={i} style={{ padding: 16 }}>
            <s.i size={18} style={{ color: C.muted }} />
            <div style={{ fontFamily: FONT_DISPLAY, fontSize: 30, fontWeight: 700, marginTop: 8, lineHeight: 1 }}>{s.v}</div>
            <div style={{ fontSize: 12.5, color: C.muted, marginTop: 4 }}>{s.l}</div>
          </Card>
        ))}
      </div>

      {/* metric cards */}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 14 }}>
        {metrics.map(m => {
          const t = trend(m);
          const pct = m.target ? Math.min(100, Math.round((m.value / m.target) * 100)) : 0;
          return (
            <Card key={m.id} hover>
              {editing ? (
                <div>
                  <input value={m.label} onChange={e => updateMetric(m.id, "label", e.target.value)} style={inlineInput} />
                  <div style={{ display: "flex", gap: 6, marginTop: 8 }}>
                    <input value={m.value} onChange={e => updateMetric(m.id, "value", e.target.value)} style={{ ...inlineInput, width: 60 }} placeholder="nu" />
                    <input value={m.prev} onChange={e => updateMetric(m.id, "prev", e.target.value)} style={{ ...inlineInput, width: 60 }} placeholder="vorig" />
                    <input value={m.target} onChange={e => updateMetric(m.id, "target", e.target.value)} style={{ ...inlineInput, width: 60 }} placeholder="doel" />
                    <input value={m.unit} onChange={e => updateMetric(m.id, "unit", e.target.value)} style={{ ...inlineInput, width: 40 }} placeholder="eenh" />
                  </div>
                  <button onClick={() => delMetric(m.id)} style={{ marginTop: 10, fontSize: 12, color: C.bad, background: "none", border: "none", cursor: "pointer", display: "flex", alignItems: "center", gap: 4 }}><Trash2 size={12} /> Verwijderen</button>
                </div>
              ) : (
                <div>
                  <div style={{ fontSize: 13, color: C.muted, fontWeight: 600, minHeight: 34 }}>{m.label}</div>
                  <div style={{ display: "flex", alignItems: "baseline", gap: 8, marginTop: 4 }}>
                    <span style={{ fontFamily: FONT_DISPLAY, fontSize: 34, fontWeight: 700, lineHeight: 1 }}>{m.value}{m.unit}</span>
                    <span style={{ display: "inline-flex", alignItems: "center", gap: 2, fontSize: 13, fontWeight: 700, color: t.flat ? C.muted : t.up ? C.good : C.bad }}>
                      {t.flat ? <Minus size={13} /> : t.up ? <TrendingUp size={13} /> : <TrendingDown size={13} />}
                      {t.flat ? "" : `${t.up ? "+" : ""}${t.d}${m.unit}`}
                    </span>
                  </div>
                  <div style={{ marginTop: 14 }}>
                    <div style={{ height: 6, background: C.line, borderRadius: 6, overflow: "hidden" }}>
                      <div style={{ height: "100%", width: `${pct}%`, background: C.yellow, borderRadius: 6 }} />
                    </div>
                    <div style={{ fontSize: 11.5, color: C.muted, marginTop: 5 }}>{pct}% van doel ({m.target}{m.unit})</div>
                  </div>
                </div>
              )}
            </Card>
          );
        })}
        {editing && (
          <Card hover onClick={addMetric} style={{ display: "grid", placeItems: "center", borderStyle: "dashed", minHeight: 130 }}>
            <div style={{ textAlign: "center", color: C.muted }}><Plus size={22} /><div style={{ fontSize: 13, fontWeight: 600, marginTop: 4 }}>Metric toevoegen</div></div>
          </Card>
        )}
      </div>

      {/* AI summary */}
      <Card style={{ marginTop: 22 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: summary ? 14 : 0 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
            <AIBadge /> <span style={{ fontWeight: 700, fontSize: 15 }}>Management-samenvatting</span>
          </div>
          <Btn size="sm" variant="ghost" icon={Sparkles} onClick={genSummary} disabled={busy}>{summary ? "Opnieuw" : "Genereer"}</Btn>
        </div>
        {busy && <Spinner label="Samenvatting schrijven…" />}
        {summary && !busy && <div style={{ fontSize: 14.5, lineHeight: 1.65, color: C.ink2 }}>{summary}</div>}
      </Card>
    </div>
  );
}
const inlineInput = { width: "100%", boxSizing: "border-box", padding: "7px 9px", border: `1.5px solid ${C.line}`, borderRadius: 8, fontFamily: FONT_BODY, fontSize: 13, outline: "none" };

/* ============================== 2. ONDERZOEK ============================== */
const RESEARCH_TYPES = [
  { id: "competitor", label: "Concurrentieonderzoek", icon: Building2, desc: "Positionering, sterktes en zwaktes van concurrenten in de IDP/P2P-markt.", prompt: "Voer een concurrentieonderzoek uit. Analyseer de belangrijkste concurrenten t.o.v. het merkprofiel: hoe positioneren zij zich, waar zijn ze sterk, waar liggen kansen voor whitevision om zich te onderscheiden." },
  { id: "positioning", label: "Positioneringsonderzoek", icon: Target, desc: "Toets en scherp de positionering tussen IDP-specialist en breed platform.", prompt: "Voer een positioneringsonderzoek uit. Beoordeel de huidige positionering, de spanning tussen IDP-kern en breed P2P/spend-platform, en geef aanbevelingen voor een scherpe, geloofwaardige positionering." },
  { id: "perception", label: "Merkperceptie-onderzoek", icon: Eye, desc: "Hoe wordt het merk gezien en welke associaties leven er in de markt.", prompt: "Voer een merkperceptie-onderzoek uit. Beschrijf hoe whitevision waarschijnlijk wordt gepercipieerd, welke associaties sterk/zwak zijn, en hoe de perceptie richting marktleiderschap te sturen." },
  { id: "audience", label: "Doelgroeponderzoek (ICP)", icon: Users, desc: "Verdiep de ideale klantprofielen en hun beslissingscriteria.", prompt: "Voer een doelgroeponderzoek uit op basis van de ICP's. Beschrijf hun belangrijkste pijnpunten, beslissingscriteria en welke boodschap bij hen aanslaat." },
  { id: "category", label: "Categorie / marktonderzoek", icon: Globe, desc: "Trends, marktontwikkeling en categoriedefinitie voor AI-driven IDP.", prompt: "Voer een categorie-onderzoek uit naar de AI-driven IDP- en P2P-markt: trends, groei, hoe de categorie te claimen en te definiëren als marktleider." },
];

function Research({ ctx }) {
  const { research, saveResearch, profile, addAction } = ctx;
  const [open, setOpen] = useState(null); // research type id for "detail view"
  const [running, setRunning] = useState(false);
  const [inputBrief, setInputBrief] = useState("");
  const [showNew, setShowNew] = useState(null);

  const runResearch = async (type) => {
    setRunning(true);
    const prompt = `${profileContext(profile)}\n\nOPDRACHT: ${type.prompt}\n${inputBrief ? "Aanvullende context van de brand manager: " + inputBrief : ""}\n\nLever het resultaat als JSON met deze structuur:
{"summary": "samenvatting in 3-4 zinnen", "findings": [{"title": "kort", "text": "bevinding", "tag": "label"}], "actions": [{"title": "kort", "text": "concrete vervolgactie", "severity": "hoog|midden|laag"}]}`;
    const r = await callAI(prompt, { json: true });
    const entry = {
      id: Date.now(), typeId: type.id, typeLabel: type.label, brief: inputBrief,
      date: new Date().toISOString().slice(0, 10),
      summary: r?.summary || "Geen samenvatting gegenereerd.",
      findings: r?.findings || [], actions: r?.actions || [],
    };
    saveResearch([entry, ...research]);
    setRunning(false); setInputBrief(""); setShowNew(null); setOpen(type.id);
  };

  // detail view of one research type
  if (open) {
    const type = RESEARCH_TYPES.find(t => t.id === open);
    const history = research.filter(r => r.typeId === open);
    return (
      <div>
        <button onClick={() => setOpen(null)} style={backLink}><ChevronRight size={15} style={{ transform: "rotate(180deg)" }} /> Terug naar onderzoek</button>
        <PageHead title={type.label} sub={type.desc}
          right={<Btn variant="yellow" icon={Sparkles} onClick={() => setShowNew(type)}>Nieuw onderzoek</Btn>} />

        {showNew && (
          <Card style={{ marginBottom: 20, border: `1.5px solid ${C.yellow}` }}>
            <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 12 }}><AIBadge /><span style={{ fontWeight: 700 }}>Nieuw {type.label.toLowerCase()}</span></div>
            <Field label="Brief / focus (optioneel)" value={inputBrief} onChange={setInputBrief} multiline placeholder="Bijv. 'focus op de zorgbranche' of 'vergelijk met ABBYY en Hyperscience'…" />
            <div style={{ display: "flex", gap: 10 }}>
              <Btn variant="yellow" icon={Sparkles} onClick={() => runResearch(type)} disabled={running}>{running ? "Bezig…" : "Start AI-onderzoek"}</Btn>
              <Btn variant="ghost" onClick={() => setShowNew(null)}>Annuleren</Btn>
            </div>
            {running && <div style={{ marginTop: 12 }}><Spinner label="AI voert het onderzoek uit…" /></div>}
          </Card>
        )}

        <div style={{ fontSize: 13, fontWeight: 700, color: C.muted, textTransform: "uppercase", letterSpacing: .4, marginBottom: 12 }}>Laatste onderzoeken</div>
        {history.length === 0 && <Empty icon={Microscope} title="Nog geen onderzoeken" sub="Start een nieuw AI-onderzoek hierboven." />}
        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          {history.map(r => (
            <Card key={r.id}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
                <Tag color={C.ink} bg={C.line}>{r.date}</Tag>
                {r.brief && <span style={{ fontSize: 12.5, color: C.muted, fontStyle: "italic" }}>"{r.brief}"</span>}
              </div>
              <div style={{ fontSize: 14.5, lineHeight: 1.6, color: C.ink2 }}>{r.summary}</div>
              {r.findings?.length > 0 && <>
                <div style={{ fontSize: 12.5, fontWeight: 700, color: C.muted, marginTop: 16, marginBottom: 2, textTransform: "uppercase" }}>Bevindingen</div>
                <Insights items={r.findings} onAction={addAction} prefix={type.label} />
              </>}
              {r.actions?.length > 0 && <>
                <div style={{ fontSize: 12.5, fontWeight: 700, color: C.muted, marginTop: 16, marginBottom: 2, textTransform: "uppercase" }}>Aanbevolen acties</div>
                <Insights items={r.actions} onAction={addAction} prefix={type.label} />
              </>}
            </Card>
          ))}
        </div>
      </div>
    );
  }

  // overview of research tools
  return (
    <div>
      <PageHead title="Onderzoek" sub="AI-aangedreven onderzoekshulpmiddelen voor de brand manager." />
      <div style={{ display: "grid", gridTemplateColumns: "repeat(2,1fr)", gap: 16 }}>
        {RESEARCH_TYPES.map(t => {
          const count = research.filter(r => r.typeId === t.id).length;
          return (
            <Card key={t.id} hover onClick={() => setOpen(t.id)}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
                <div style={{ width: 42, height: 42, borderRadius: 11, background: C.yellow + "22", display: "grid", placeItems: "center" }}>
                  <t.icon size={21} style={{ color: C.ink }} />
                </div>
                {count > 0 && <Tag color={C.ink} bg={C.yellow}>{count} uitgevoerd</Tag>}
              </div>
              <div style={{ fontWeight: 700, fontSize: 16.5, marginTop: 14 }}>{t.label}</div>
              <div style={{ fontSize: 13.5, color: C.muted, marginTop: 5, lineHeight: 1.5 }}>{t.desc}</div>
              <div style={{ display: "flex", alignItems: "center", gap: 5, fontSize: 13, fontWeight: 700, color: C.ink, marginTop: 14 }}>
                Openen <ArrowUpRight size={15} />
              </div>
            </Card>
          );
        })}
      </div>
    </div>
  );
}
const backLink = { display: "inline-flex", alignItems: "center", gap: 4, fontSize: 13.5, fontWeight: 600, color: C.muted, background: "none", border: "none", cursor: "pointer", marginBottom: 14, padding: 0 };

/* ============================== 3. AUDIT ============================== */
const AUDIT_TYPES = [
  { id: "website", label: "Website content audit", icon: Globe, desc: "Toets website-content tegen je positionering, tone-of-voice en brandbook.", input: "url" },
  { id: "presentation", label: "Presentatie audit", icon: Presentation, desc: "Plak presentatie-inhoud en laat AI merkconsistentie beoordelen.", input: "text" },
  { id: "market", label: "Marktkansen (M&A)", icon: Briefcase, desc: "Vind bedrijven die je doelstellingen aanvullen of overlappen, met fit-score.", input: "market" },
  { id: "portfolio", label: "Overgenomen bedrijven", icon: Building2, desc: "Analyseer het aanbodverschil: wat bieden zij dat wij niet, en andersom.", input: "company" },
  { id: "collateral", label: "Materiaal audit", icon: FileText, desc: "Beoordeel een brochure, e-mail of andere uiting op merkfit.", input: "text" },
];

function Audit({ ctx }) {
  const { audits, saveAudits, profile, companies, addAction } = ctx;
  const [open, setOpen] = useState(null);
  const [running, setRunning] = useState(false);
  const [val, setVal] = useState("");
  const [marketGoal, setMarketGoal] = useState("");
  const [selectedCo, setSelectedCo] = useState("");

  const runAudit = async (type) => {
    setRunning(true);
    let prompt;
    if (type.id === "market") {
      prompt = `${profileContext(profile)}\n\nOPDRACHT: Identificeer overname-/marktkansen. Doel van de brand manager: "${marketGoal || profile?.goals || "groei en marktuitbreiding"}".\n\nGeef een lijst van het type bedrijven/profielen dat past, met per kandidaat een geschatte fit-score (0-100%), of het aanvult of overlapt, en relevantie t.o.v. de doelstelling. Geef realistische voorbeeldprofielen (geen verzonnen exacte feiten als je het niet zeker weet; label inschattingen als zodanig).\n\nJSON: {"summary": "...", "candidates": [{"name": "bedrijfsprofiel/type", "fit": 0-100, "relation": "aanvullend|overlappend", "rationale": "waarom", "tag": "land/segment"}], "actions": [{"title":"...","text":"...","severity":"hoog|midden|laag"}]}`;
    } else if (type.id === "website") {
      prompt = `${profileContext(profile)}\n\nOPDRACHT: Voer een website content audit uit voor de opgegeven URL/site: "${val}". Beoordeel (op basis van algemene kennis en redelijke aannames over zo'n site) of de content aansluit op de positionering, tone-of-voice en het merkprofiel. Markeer afwijkingen.\n\nJSON: {"summary": "...", "findings": [{"title":"...","text":"afwijking of observatie","severity":"hoog|midden|laag","tag":"categorie"}], "actions": [{"title":"...","text":"...","severity":"hoog|midden|laag"}]}`;
    } else if (type.id === "portfolio") {
      const co = companies.find(c => String(c.id) === String(selectedCo));
      prompt = `${profileContext(profile)}\n\nOPDRACHT: Voer een aanbod-vergelijking (gap-analyse) uit tussen whitevision en het overgenomen bedrijf "${co?.name || selectedCo}"${co?.segment ? " (segment: " + co.segment + ")" : ""}${co?.country ? ", " + co.country : ""}. ${co?.notes ? "Context: " + co.notes : ""}\n\nBreng in kaart: wat biedt dit overgenomen bedrijf dat whitevision (nog) niet biedt, en wat biedt whitevision dat zij niet bieden, plus waar het overlapt. Geef strategische implicaties voor integratie en cross-sell.\n\nJSON: {"summary":"...", "theyOffer":[{"title":"hun aanbod dat wij missen","text":"...","severity":"hoog|midden|laag"}], "weOffer":[{"title":"ons aanbod dat zij missen","text":"...","severity":"laag"}], "overlap":["overlappend gebied"], "actions":[{"title":"...","text":"...","severity":"hoog|midden|laag"}]}`;
    } else {
      prompt = `${profileContext(profile)}\n\nOPDRACHT: Audit het volgende materiaal tegen de positionering, tone-of-voice en het merkprofiel. Markeer waar het afwijkt van het merk en wat sterk is.\n\nMATERIAAL:\n"""${val}"""\n\nJSON: {"summary": "...", "findings": [{"title":"...","text":"...","severity":"hoog|midden|laag","tag":"tone|inhoud|visueel|positionering"}], "actions": [{"title":"...","text":"...","severity":"hoog|midden|laag"}]}`;
    }
    const r = await callAI(prompt, { json: true });
    const co = companies.find(c => String(c.id) === String(selectedCo));
    const entry = {
      id: Date.now(), typeId: type.id, typeLabel: type.label,
      subject: type.id === "market" ? (marketGoal || "doelstelling") : type.id === "portfolio" ? (co?.name || "—") : (val.slice(0, 80) || "—"),
      date: new Date().toISOString().slice(0, 10),
      summary: r?.summary || "Geen samenvatting.",
      findings: r?.findings || [], candidates: r?.candidates || [], actions: r?.actions || [],
      theyOffer: r?.theyOffer || [], weOffer: r?.weOffer || [], overlap: r?.overlap || [],
    };
    saveAudits([entry, ...audits]);
    setRunning(false); setVal(""); setMarketGoal(""); setSelectedCo(""); setOpen({ ...type, justRan: entry.id });
  };

  if (open) {
    const type = AUDIT_TYPES.find(t => t.id === open.id);
    const history = audits.filter(a => a.typeId === open.id);
    return (
      <div>
        <button onClick={() => setOpen(null)} style={backLink}><ChevronRight size={15} style={{ transform: "rotate(180deg)" }} /> Terug naar audits</button>
        <PageHead title={type.label} sub={type.desc} />
        {!profile?.filled && <div style={mirrorWarn}><AlertTriangle size={15} /> Vul eerst je merkprofiel in voor scherpere spiegeling.</div>}

        <Card style={{ marginBottom: 22, border: `1.5px solid ${C.yellow}` }}>
          <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 12 }}><AIBadge /><span style={{ fontWeight: 700 }}>Nieuwe audit</span></div>
          {type.input === "url" && <Field label="Website URL of sitemap" value={val} onChange={setVal} placeholder="https://whitevision.com" />}
          {type.input === "text" && <Field label="Plak hier de inhoud" value={val} onChange={setVal} multiline rows={6} placeholder="Plak de presentatietekst, brochure of e-mail…" />}
          {type.input === "market" && <Field label="Doelstelling / richting" value={marketGoal} onChange={setMarketGoal} placeholder="Bijv. 'uitbreiden naar de zorgbranche in DACH'" />}
          {type.input === "company" && (
            <div style={{ marginBottom: 16 }}>
              <label style={{ display: "block", fontSize: 12.5, fontWeight: 700, color: C.muted, marginBottom: 6, letterSpacing: .3, textTransform: "uppercase" }}>Kies een overgenomen bedrijf</label>
              {companies.length === 0
                ? <div style={{ fontSize: 13.5, color: C.muted }}>Voeg eerst overgenomen bedrijven toe op het merkprofiel.</div>
                : <select value={selectedCo} onChange={e => setSelectedCo(e.target.value)} style={{ width: "100%", padding: "11px 13px", border: `1.5px solid ${C.line}`, borderRadius: 10, fontFamily: FONT_BODY, fontSize: 14, outline: "none", background: "#fff" }}>
                    <option value="">— Selecteer —</option>
                    {companies.map(c => <option key={c.id} value={c.id}>{c.name}{c.segment ? ` (${c.segment})` : ""}</option>)}
                  </select>}
            </div>
          )}
          <Btn variant="yellow" icon={Sparkles} onClick={() => runAudit(type)} disabled={running || (type.input === "url" || type.input === "text" ? !val : false) || (type.input === "market" && !marketGoal && !profile?.goals) || (type.input === "company" && !selectedCo)}>
            {running ? "Bezig…" : "Start AI-audit"}
          </Btn>
          {running && <div style={{ marginTop: 12 }}><Spinner label="AI voert de audit uit & spiegelt tegen je merkprofiel…" /></div>}
        </Card>

        <div style={{ fontSize: 13, fontWeight: 700, color: C.muted, textTransform: "uppercase", letterSpacing: .4, marginBottom: 12 }}>Eerdere audits</div>
        {history.length === 0 && <Empty icon={ClipboardCheck} title="Nog geen audits uitgevoerd" />}
        <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
          {history.map(a => (
            <Card key={a.id} style={open.justRan === a.id ? { border: `1.5px solid ${C.yellow}` } : {}}>
              <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 10 }}>
                <Tag color={C.ink} bg={C.line}>{a.date}</Tag>
                <span style={{ fontSize: 12.5, color: C.muted }}>{a.subject}</span>
              </div>
              <div style={{ fontSize: 14.5, lineHeight: 1.6, color: C.ink2 }}>{a.summary}</div>
              {a.candidates?.length > 0 && (
                <div style={{ marginTop: 14, display: "flex", flexDirection: "column", gap: 10 }}>
                  {a.candidates.map((c, i) => (
                    <div key={i} style={{ display: "flex", alignItems: "center", gap: 14, padding: "12px 15px", background: C.paper, borderRadius: 12, border: `1px solid ${C.line}` }}>
                      <div style={{ position: "relative", width: 46, height: 46, flexShrink: 0 }}>
                        <svg width="46" height="46" style={{ transform: "rotate(-90deg)" }}>
                          <circle cx="23" cy="23" r="19" fill="none" stroke={C.line} strokeWidth="5" />
                          <circle cx="23" cy="23" r="19" fill="none" stroke={c.fit >= 70 ? C.good : c.fit >= 40 ? C.yellowDark : C.bad} strokeWidth="5" strokeDasharray={`${(c.fit / 100) * 119} 119`} strokeLinecap="round" />
                        </svg>
                        <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", fontSize: 12.5, fontWeight: 700 }}>{c.fit}%</div>
                      </div>
                      <div style={{ flex: 1 }}>
                        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                          <span style={{ fontWeight: 700, fontSize: 14.5 }}>{c.name}</span>
                          <Tag color={c.relation === "overlappend" ? C.bad : C.good}>{c.relation}</Tag>
                          {c.tag && <Tag>{c.tag}</Tag>}
                        </div>
                        <div style={{ fontSize: 13, color: C.ink2, marginTop: 3, lineHeight: 1.45 }}>{c.rationale}</div>
                      </div>
                      <button onClick={() => addAction({ title: `Verken: ${c.name}`, detail: c.rationale, source: "Marktkansen" })}
                        style={{ flexShrink: 0, display: "inline-flex", alignItems: "center", gap: 5, fontSize: 12.5, fontWeight: 700, color: C.ink, background: C.yellow, border: "none", padding: "6px 11px", borderRadius: 8, cursor: "pointer" }}>
                        <Flag size={13} /> Actie
                      </button>
                    </div>
                  ))}
                </div>
              )}
              {(a.theyOffer?.length > 0 || a.weOffer?.length > 0) && (
                <div style={{ marginTop: 14, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14 }}>
                  <div style={{ padding: 14, background: C.bad + "0E", borderRadius: 12, border: `1px solid ${C.bad}22` }}>
                    <div style={{ fontSize: 12.5, fontWeight: 700, color: C.bad, marginBottom: 8, textTransform: "uppercase", display: "flex", alignItems: "center", gap: 6 }}><TrendingUp size={13} /> Zij bieden, wij niet</div>
                    {(a.theyOffer || []).map((x, i) => (
                      <div key={i} style={{ marginBottom: 10 }}>
                        <div style={{ display: "flex", justifyContent: "space-between", gap: 8, alignItems: "flex-start" }}>
                          <div><div style={{ fontWeight: 700, fontSize: 13.5 }}>{x.title}</div><div style={{ fontSize: 12.5, color: C.ink2, marginTop: 2, lineHeight: 1.45 }}>{x.text}</div></div>
                          <button onClick={() => addAction({ title: x.title, detail: x.text, source: "Portfolio-gap" })} style={{ flexShrink: 0, color: C.ink, background: C.yellow, border: "none", padding: "4px 8px", borderRadius: 7, cursor: "pointer", fontSize: 11.5, fontWeight: 700, display: "inline-flex", alignItems: "center", gap: 4 }}><Flag size={11} /></button>
                        </div>
                      </div>
                    ))}
                    {(!a.theyOffer || !a.theyOffer.length) && <div style={{ fontSize: 12.5, color: C.muted }}>Geen gemeld.</div>}
                  </div>
                  <div style={{ padding: 14, background: C.good + "0E", borderRadius: 12, border: `1px solid ${C.good}22` }}>
                    <div style={{ fontSize: 12.5, fontWeight: 700, color: C.good, marginBottom: 8, textTransform: "uppercase", display: "flex", alignItems: "center", gap: 6 }}><CheckCircle2 size={13} /> Wij bieden, zij niet</div>
                    {(a.weOffer || []).map((x, i) => (
                      <div key={i} style={{ marginBottom: 10 }}>
                        <div style={{ fontWeight: 700, fontSize: 13.5 }}>{x.title}</div><div style={{ fontSize: 12.5, color: C.ink2, marginTop: 2, lineHeight: 1.45 }}>{x.text}</div>
                      </div>
                    ))}
                    {(!a.weOffer || !a.weOffer.length) && <div style={{ fontSize: 12.5, color: C.muted }}>Geen gemeld.</div>}
                  </div>
                </div>
              )}
              {a.overlap?.length > 0 && (
                <div style={{ marginTop: 12, display: "flex", flexWrap: "wrap", gap: 7, alignItems: "center" }}>
                  <span style={{ fontSize: 12.5, fontWeight: 700, color: C.muted }}>Overlap:</span>
                  {a.overlap.map((o, i) => <Tag key={i} color={C.blue}>{o}</Tag>)}
                </div>
              )}
              {a.findings?.length > 0 && <Insights items={a.findings} onAction={addAction} prefix={type.label} />}
              {a.actions?.length > 0 && <>
                <div style={{ fontSize: 12.5, fontWeight: 700, color: C.muted, marginTop: 16, marginBottom: 2, textTransform: "uppercase" }}>Aanbevolen acties</div>
                <Insights items={a.actions} onAction={addAction} prefix={type.label} />
              </>}
            </Card>
          ))}
        </div>
      </div>
    );
  }

  return (
    <div>
      <PageHead title="Audit" sub="Toets materiaal en marktkansen — alles gespiegeld tegen je merkprofiel." />
      <div style={{ display: "grid", gridTemplateColumns: "repeat(2,1fr)", gap: 16 }}>
        {AUDIT_TYPES.map(t => {
          const count = audits.filter(a => a.typeId === t.id).length;
          return (
            <Card key={t.id} hover onClick={() => setOpen(t)}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
                <div style={{ width: 42, height: 42, borderRadius: 11, background: C.ink, display: "grid", placeItems: "center" }}>
                  <t.icon size={21} style={{ color: C.yellow }} />
                </div>
                {count > 0 && <Tag color={C.ink} bg={C.yellow}>{count}×</Tag>}
              </div>
              <div style={{ fontWeight: 700, fontSize: 16.5, marginTop: 14 }}>{t.label}</div>
              <div style={{ fontSize: 13.5, color: C.muted, marginTop: 5, lineHeight: 1.5 }}>{t.desc}</div>
              <div style={{ display: "flex", alignItems: "center", gap: 5, fontSize: 13, fontWeight: 700, color: C.ink, marginTop: 14 }}>Openen <ArrowUpRight size={15} /></div>
            </Card>
          );
        })}
      </div>
    </div>
  );
}
const mirrorWarn = { display: "flex", alignItems: "center", gap: 8, fontSize: 13.5, color: C.yellowDark, background: C.yellow + "18", padding: "10px 14px", borderRadius: 10, marginBottom: 18, fontWeight: 600 };

/* ============================== 4. MONITOR ============================== */
const MONITOR_TYPES = [
  { id: "mentions", label: "Brand mentions", icon: Megaphone, desc: "Doorlopend volgen waar merknamen genoemd worden, met notificaties.",
    placeholder: "Merknaam of term (bijv. whitevision, WhiteVision IDP)…", addLabel: "Merknaam / term toevoegen", noun: "merk" },
  { id: "competitors", label: "Concurrenten", icon: Building2, desc: "Volg concurrenten: blogs, nieuwe features en social posts.",
    placeholder: "Naam van een concurrent (bijv. ABBYY)…", addLabel: "Concurrent toevoegen", noun: "concurrent" },
  { id: "acquired", label: "Overgenomen bedrijven", icon: Briefcase, desc: "Volg de overnames die je op het merkprofiel hebt aangezet.",
    placeholder: "", addLabel: "", noun: "overgenomen bedrijf" },
];

function Monitor({ ctx }) {
  const { monitors, saveMonitors, profile, companies, saveCompanies, addAction } = ctx;
  const [activeType, setActiveType] = useState(null);
  const [openItem, setOpenItem] = useState(null);
  const [newName, setNewName] = useState("");
  const [busyId, setBusyId] = useState(null);

  // monitors = array of { id, typeId, name, notify, lastCheck, activity:[], gaps:[] }
  const itemsOf = (typeId) => (monitors || []).filter(m => m.typeId === typeId);

  const addItem = (typeId, name) => {
    if (!name.trim()) return;
    saveMonitors([{ id: Date.now(), typeId, name: name.trim(), notify: true, lastCheck: null, activity: [], gaps: [] }, ...monitors]);
    setNewName("");
  };
  const toggleNotify = (id) => saveMonitors(monitors.map(m => m.id === id ? { ...m, notify: !m.notify } : m));
  const removeItem = (id) => saveMonitors(monitors.filter(m => m.id !== id));

  // pull acquired companies (with monitor flag) into the monitor list view
  const acquiredMonitored = (companies || []).filter(c => c.monitor);

  const checkActivity = async (item, isCompany) => {
    setBusyId(item.id);
    let prompt = `${profileContext(profile)}\n\n`;
    if (item.typeId === "mentions") {
      prompt += `OPDRACHT: Simuleer recente brand mentions voor "${item.name}". Geef plausibele mentions met bron-type en sentiment, en markeer waar de externe perceptie afwijkt van het merkprofiel.`;
    } else if (item.typeId === "competitors") {
      prompt += `OPDRACHT: Simuleer recente activiteit van concurrent "${item.name}": blogposts, nieuwe features, social posts, positioneringsverschuivingen. Breng in kaart waar zij AFWIJKEN of OVERLAPPEN met het merkprofiel van whitevision.`;
    } else {
      prompt += `OPDRACHT: Simuleer recente activiteit en merksignalen van overgenomen bedrijf "${item.name}"${item.segment ? " (" + item.segment + ")" : ""}. Beoordeel merkconsistentie en signaleer waar hun uitingen AFWIJKEN van het whitevision-merkprofiel.`;
    }
    prompt += `\n\nJSON: {"activity":[{"title":"...","text":"wat is er gebeurd","tag":"bron/type","severity":"hoog|midden|laag"}], "gaps":[{"title":"afwijking t.o.v. merkprofiel","text":"...","severity":"hoog|midden|laag"}]}`;
    const r = await callAI(prompt, { json: true });
    const update = { activity: r?.activity || [], gaps: r?.gaps || [], lastCheck: new Date().toISOString().slice(0, 10) };
    if (isCompany) {
      saveCompanies(companies.map(c => c.id === item.id ? { ...c, ...update } : c));
      setOpenItem({ ...item, ...update, isCompany: true });
    } else {
      saveMonitors(monitors.map(m => m.id === item.id ? { ...m, ...update } : m));
      setOpenItem({ ...item, ...update });
    }
    setBusyId(null);
  };

  const sevDot = (list) => {
    if (!list || !list.length) return C.muted;
    if (list.some(x => (x.severity || "").includes("hoog"))) return C.bad;
    if (list.some(x => (x.severity || "").includes("midden"))) return C.yellowDark;
    return C.good;
  };

  // ---- DETAIL VIEW: activity for one monitored item ----
  if (openItem) {
    return (
      <div>
        <button onClick={() => setOpenItem(null)} style={backLink}><ChevronRight size={15} style={{ transform: "rotate(180deg)" }} /> Terug naar monitor</button>
        <PageHead title={openItem.name} sub={openItem.lastCheck ? `Laatst gecontroleerd op ${openItem.lastCheck}` : "Nog niet gecontroleerd"}
          right={<Btn variant="yellow" size="sm" icon={Sparkles} onClick={() => checkActivity(openItem, openItem.isCompany)} disabled={busyId === openItem.id}>{busyId === openItem.id ? "Bezig…" : "Nu controleren"}</Btn>} />
        {busyId === openItem.id && <Spinner label="AI haalt recente activiteit op…" />}
        {(!openItem.activity || !openItem.activity.length) && busyId !== openItem.id && <Empty icon={Radar} title="Nog geen activiteit opgehaald" sub="Klik op 'Nu controleren'." />}
        {openItem.activity?.length > 0 && (
          <Card>
            <div style={{ fontSize: 12.5, fontWeight: 700, color: C.muted, marginBottom: 2, textTransform: "uppercase" }}>Recente activiteit</div>
            <Insights items={openItem.activity} onAction={addAction} prefix={"Monitor: " + openItem.name} />
            {openItem.gaps?.length > 0 && <>
              <div style={{ fontSize: 12.5, fontWeight: 700, color: C.bad, marginTop: 18, marginBottom: 2, textTransform: "uppercase", display: "flex", alignItems: "center", gap: 6 }}><AlertTriangle size={13} /> Afwijkingen t.o.v. merkprofiel</div>
              <Insights items={openItem.gaps} onAction={addAction} prefix={"Monitor gap: " + openItem.name} />
            </>}
          </Card>
        )}
      </div>
    );
  }

  // ---- TYPE VIEW: list of monitored items for a type ----
  if (activeType) {
    const type = MONITOR_TYPES.find(t => t.id === activeType);
    const isAcquired = activeType === "acquired";
    const list = isAcquired ? acquiredMonitored : itemsOf(activeType);
    return (
      <div>
        <button onClick={() => setActiveType(null)} style={backLink}><ChevronRight size={15} style={{ transform: "rotate(180deg)" }} /> Terug naar monitor</button>
        <PageHead title={type.label} sub={type.desc} />

        {!isAcquired && (
          <Card style={{ marginBottom: 20 }}>
            <div style={{ display: "flex", gap: 10 }}>
              <input value={newName} onChange={e => setNewName(e.target.value)} onKeyDown={e => e.key === "Enter" && addItem(activeType, newName)}
                placeholder={type.placeholder} style={{ flex: 1, padding: "11px 13px", border: `1.5px solid ${C.line}`, borderRadius: 10, fontFamily: FONT_BODY, fontSize: 14, outline: "none" }} />
              <Btn variant="primary" icon={Plus} onClick={() => addItem(activeType, newName)}>{type.addLabel}</Btn>
            </div>
          </Card>
        )}
        {isAcquired && (
          <div style={mirrorWarn}><AlertTriangle size={15} /> Bedrijven beheer en activeer je op het <b style={{ marginLeft: 4 }}>Merkprofiel</b>. Zet daar "monitoren" aan om ze hier te zien.</div>
        )}

        {list.length === 0 && <Empty icon={Radar} title={isAcquired ? "Geen overgenomen bedrijven op monitoren gezet" : `Nog geen ${type.noun}en toegevoegd`} sub={isAcquired ? "Ga naar het merkprofiel om bedrijven toe te voegen." : "Voeg er hierboven één toe om te volgen."} />}

        <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          {list.map(item => {
            const it = isAcquired ? { ...item, typeId: "acquired", isCompany: true } : item;
            const actCount = (it.activity || []).length;
            const dot = sevDot([...(it.activity || []), ...(it.gaps || [])]);
            return (
              <Card key={it.id} hover>
                <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
                  <div onClick={() => setOpenItem(it)} style={{ display: "flex", alignItems: "center", gap: 14, flex: 1, cursor: "pointer" }}>
                    <div style={{ width: 40, height: 40, borderRadius: 10, background: C.ink, display: "grid", placeItems: "center", color: C.yellow, fontWeight: 700, fontFamily: FONT_DISPLAY }}>{it.name?.[0]?.toUpperCase()}</div>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontWeight: 700, fontSize: 15, display: "flex", alignItems: "center", gap: 9 }}>
                        {it.name}
                        <span style={{ width: 8, height: 8, borderRadius: 8, background: dot }} />
                      </div>
                      <div style={{ fontSize: 12.5, color: C.muted, marginTop: 2 }}>
                        {actCount ? `${actCount} activiteit${actCount > 1 ? "en" : ""}` : "Nog niet gecontroleerd"}
                        {it.lastCheck ? ` · laatst ${it.lastCheck}` : ""}
                        {it.gaps?.length ? ` · ${it.gaps.length} afwijking(en)` : ""}
                      </div>
                    </div>
                  </div>
                  {/* notify toggle */}
                  {!isAcquired && <Toggle on={it.notify} onChange={() => toggleNotify(it.id)} label="Notificaties" />}
                  <Btn size="sm" variant="ghost" icon={Sparkles} onClick={() => checkActivity(it, isAcquired)} disabled={busyId === it.id}>{busyId === it.id ? "…" : "Check"}</Btn>
                  <button onClick={() => setOpenItem(it)} style={{ background: "none", border: "none", cursor: "pointer", color: C.muted }}><ChevronRight size={18} /></button>
                  {!isAcquired && <button onClick={() => removeItem(it.id)} style={{ background: "none", border: "none", cursor: "pointer", color: C.bad }}><Trash2 size={15} /></button>}
                </div>
              </Card>
            );
          })}
        </div>
      </div>
    );
  }

  // ---- OVERVIEW ----
  const counts = {
    mentions: itemsOf("mentions").length,
    competitors: itemsOf("competitors").length,
    acquired: acquiredMonitored.length,
  };
  const notifyOn = (monitors || []).filter(m => m.notify).length;
  return (
    <div>
      <PageHead title="Monitor" sub="Doorlopende bewaking van merk, concurrentie en overnames — met notificaties." />
      <div style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 13, color: C.muted, marginBottom: 18 }}>
        <div style={{ width: 8, height: 8, borderRadius: 8, background: C.good }} /> {notifyOn} bron(nen) met notificaties aan
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 14 }}>
        {MONITOR_TYPES.map(t => (
          <Card key={t.id} hover onClick={() => setActiveType(t.id)}>
            <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start" }}>
              <div style={{ width: 42, height: 42, borderRadius: 11, background: C.yellow + "22", display: "grid", placeItems: "center" }}><t.icon size={21} style={{ color: C.ink }} /></div>
              <Tag color={C.ink} bg={C.line}>{counts[t.id]} gevolgd</Tag>
            </div>
            <div style={{ fontWeight: 700, fontSize: 16, marginTop: 14 }}>{t.label}</div>
            <div style={{ fontSize: 13, color: C.muted, marginTop: 4, lineHeight: 1.45 }}>{t.desc}</div>
            <div style={{ display: "flex", alignItems: "center", gap: 5, fontSize: 13, fontWeight: 700, color: C.ink, marginTop: 14 }}>Openen <ArrowUpRight size={15} /></div>
          </Card>
        ))}
      </div>
    </div>
  );
}

const Toggle = ({ on, onChange, label }) => (
  <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
    {label && <span style={{ fontSize: 12, color: C.muted, fontWeight: 600 }}>{label}</span>}
    <button onClick={onChange} style={{ width: 38, height: 22, borderRadius: 20, border: "none", cursor: "pointer", background: on ? C.good : C.line, position: "relative", transition: "all .15s", padding: 0 }}>
      <span style={{ position: "absolute", top: 2, left: on ? 18 : 2, width: 18, height: 18, borderRadius: 18, background: "#fff", transition: "all .15s", boxShadow: "0 1px 3px rgba(0,0,0,.2)" }} />
    </button>
  </div>
);

/* ============================== 5. ACTIES ============================== */
const COLUMNS = [
  { id: "todo", label: "Te doen", color: C.muted },
  { id: "doing", label: "Mee bezig", color: C.blue },
  { id: "done", label: "Afgerond", color: C.good },
];

function Actions({ ctx }) {
  const { actions, saveActions } = ctx;
  const [busyId, setBusyId] = useState(null);
  const [adding, setAdding] = useState(false);
  const [newTitle, setNewTitle] = useState("");

  const move = (id, status) => saveActions(actions.map(a => a.id === id ? { ...a, status } : a));
  const del = (id) => saveActions(actions.filter(a => a.id !== id));
  const add = () => {
    if (!newTitle.trim()) return;
    saveActions([{ id: Date.now(), title: newTitle, status: "todo", createdAt: Date.now() }, ...actions]);
    setNewTitle(""); setAdding(false);
  };

  const estimate = async (a) => {
    setBusyId(a.id);
    const r = await callAI(`Een brand manager van whitevision heeft deze actie op de lijst: "${a.title}"${a.detail ? " — context: " + a.detail : ""}.\n\nGeef een realistische tijdsindicatie en welke hulpmiddelen/tools nodig zijn.\n\nJSON: {"time":"bijv. 2-3 uur of 1 dag","tools":["tool1","tool2"],"firstStep":"de logische eerste stap in 1 zin"}`, { json: true });
    saveActions(actions.map(x => x.id === a.id ? { ...x, estimate: r } : x));
    setBusyId(null);
  };

  return (
    <div>
      <PageHead title="Acties" sub="Je openstaande merk-acties — met AI-tijdsindicatie en benodigde tools."
        right={<Btn variant="yellow" icon={Plus} onClick={() => setAdding(true)}>Actie</Btn>} />
      {adding && (
        <Card style={{ marginBottom: 18, border: `1.5px solid ${C.yellow}` }}>
          <div style={{ display: "flex", gap: 10 }}>
            <input value={newTitle} onChange={e => setNewTitle(e.target.value)} onKeyDown={e => e.key === "Enter" && add()} autoFocus placeholder="Wat moet er gebeuren?" style={{ flex: 1, padding: "11px 13px", border: `1.5px solid ${C.line}`, borderRadius: 10, fontFamily: FONT_BODY, fontSize: 14, outline: "none" }} />
            <Btn variant="primary" onClick={add}>Toevoegen</Btn>
            <Btn variant="ghost" onClick={() => setAdding(false)}><X size={16} /></Btn>
          </div>
        </Card>
      )}
      {(!actions || actions.length === 0) && <Empty icon={ListTodo} title="Nog geen acties" sub="Markeer inzichten in onderzoek, audit of monitor als actie — of voeg er handmatig een toe." />}
      <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 16 }}>
        {COLUMNS.map(col => {
          const items = (actions || []).filter(a => a.status === col.id);
          return (
            <div key={col.id}>
              <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 12 }}>
                <div style={{ width: 9, height: 9, borderRadius: 9, background: col.color }} />
                <span style={{ fontWeight: 700, fontSize: 14 }}>{col.label}</span>
                <span style={{ fontSize: 12.5, color: C.muted }}>({items.length})</span>
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 12, minHeight: 60 }}>
                {items.map(a => (
                  <Card key={a.id} style={{ padding: 15 }}>
                    <div style={{ fontWeight: 700, fontSize: 14.5, lineHeight: 1.4 }}>{a.title}</div>
                    {a.source && <div style={{ marginTop: 6 }}><Tag color={C.ink} bg={C.line}>{a.source}</Tag></div>}
                    {a.detail && <div style={{ fontSize: 13, color: C.muted, marginTop: 7, lineHeight: 1.45 }}>{a.detail}</div>}
                    {a.estimate && (
                      <div style={{ marginTop: 12, padding: "10px 12px", background: C.paper, borderRadius: 10, border: `1px solid ${C.line}` }}>
                        <div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 13, fontWeight: 700 }}><Clock size={13} style={{ color: C.yellowDark }} /> {a.estimate.time}</div>
                        {a.estimate.tools?.length > 0 && <div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 12.5, color: C.ink2, marginTop: 6, flexWrap: "wrap" }}><Wrench size={12} style={{ color: C.muted }} /> {a.estimate.tools.join(", ")}</div>}
                        {a.estimate.firstStep && <div style={{ fontSize: 12.5, color: C.muted, marginTop: 6, fontStyle: "italic" }}>→ {a.estimate.firstStep}</div>}
                      </div>
                    )}
                    <div style={{ display: "flex", gap: 6, marginTop: 12, flexWrap: "wrap", alignItems: "center" }}>
                      {!a.estimate && (
                        <button onClick={() => estimate(a)} disabled={busyId === a.id} style={miniBtn(C.yellow, C.ink)}>
                          {busyId === a.id ? <Loader2 size={12} style={{ animation: "spin 1s linear infinite" }} /> : <Sparkles size={12} />} {busyId === a.id ? "" : "Inschatten"}
                        </button>
                      )}
                      {COLUMNS.filter(c => c.id !== a.status).map(c => (
                        <button key={c.id} onClick={() => move(a.id, c.id)} style={miniBtn(C.line, C.ink2)}>→ {c.label}</button>
                      ))}
                      <button onClick={() => del(a.id)} style={{ ...miniBtn("transparent", C.bad), marginLeft: "auto" }}><Trash2 size={12} /></button>
                    </div>
                  </Card>
                ))}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}
const miniBtn = (bg, color) => ({ display: "inline-flex", alignItems: "center", gap: 4, fontSize: 12, fontWeight: 600, color, background: bg, border: bg === "transparent" ? "none" : "none", padding: "5px 9px", borderRadius: 7, cursor: "pointer" });

/* ============================== 6. MERKPROFIEL (KERN) ============================== */
const PROFILE_FIELDS = [
  { key: "proposition", label: "Huidige propositie", icon: Megaphone, multiline: true },
  { key: "goals", label: "Bedrijfsdoelstellingen", icon: Target, multiline: true },
  { key: "usps", label: "USP's", icon: Zap, multiline: true },
  { key: "products", label: "Producten & oplossingen", icon: Briefcase, multiline: true },
  { key: "tone", label: "Tone of voice", icon: FileText, multiline: true },
  { key: "icps", label: "ICP-profielen", icon: Users, multiline: true },
  { key: "competitors", label: "Concurrenten", icon: Building2, multiline: true },
  { key: "notes", label: "Brandbook-notities", icon: Palette, multiline: true },
];

function Profile({ ctx }) {
  const { profile, saveProfile, companies, saveCompanies, users, saveUsers } = ctx;
  const [p, setP] = useState(profile);
  const [dirty, setDirty] = useState(false);
  const [sources, setSources] = useState({ website: "", brandbook: "", extra: "" });
  const [aiBusy, setAiBusy] = useState(false);
  const [saved, setSaved] = useState(false);
  const [checkText, setCheckText] = useState("");
  const [checkResult, setCheckResult] = useState(null);
  const [checking, setChecking] = useState(false);
  const fileRef = useRef();
  const [uploadNames, setUploadNames] = useState([]);

  useEffect(() => { setP(profile); }, [profile]);
  const set = (k, v) => { setP(prev => ({ ...prev, [k]: v })); setDirty(true); };

  const handleFiles = (e) => {
    const files = Array.from(e.target.files || []);
    setUploadNames(files.map(f => f.name));
    let combined = sources.extra;
    let pending = files.length;
    if (!pending) return;
    files.forEach(f => {
      const reader = new FileReader();
      reader.onload = () => {
        combined += `\n\n[Bestand: ${f.name}]\n` + (typeof reader.result === "string" ? reader.result.slice(0, 4000) : "(binair bestand, naam meegegeven)");
        pending--; if (pending === 0) setSources(s => ({ ...s, extra: combined }));
      };
      reader.onerror = () => { pending--; };
      if (f.type.startsWith("text") || f.name.match(/\.(txt|md|csv|html|json)$/i)) reader.readAsText(f);
      else { combined += `\n\n[Bestand geüpload: ${f.name} — beschrijf inhoud in het tekstveld]`; pending--; if (pending === 0) setSources(s => ({ ...s, extra: combined })); }
    });
  };

  const aiFill = async () => {
    setAiBusy(true);
    const input = `Website/URL: ${sources.website || "—"}\nBrandbook/identiteit (tekst): ${sources.brandbook || "—"}\nOverige aangeleverde info: ${sources.extra || "—"}`;
    const prompt = `Je helpt de brand manager van whitevision (AI-driven IDP-software, buy-and-build, oplossingen in purchase-to-pay, contractmanagement, spend management) een merkprofiel op te bouwen.\n\nOp basis van onderstaande aangeleverde input, vul een merkprofiel in. Waar informatie ontbreekt, doe een onderbouwde, realistische inschatting passend bij dit type bedrijf en markeer die als [aanname].\n\nINPUT:\n${input}\n\nJSON met exact deze sleutels (strings): {"proposition":"","goals":"","usps":"","products":"","tone":"","icps":"","colors":"hex-codes","competitors":""}`;
    const r = await callAI(prompt, { json: true });
    if (r) {
      const next = { ...p, ...r, filled: true };
      setP(next); setDirty(true);
    }
    setAiBusy(false);
  };

  const save = () => { saveProfile({ ...p, filled: true }); setDirty(false); setSaved(true); setTimeout(() => setSaved(false), 1800); };

  const runCheck = async () => {
    setChecking(true); setCheckResult(null);
    const prompt = `${profileContext({ ...p, filled: true })}\n\nOPDRACHT: Beoordeel of het volgende materiaal voldoet aan de tone-of-voice en het merkprofiel hierboven. Geef per punt aan of het PAST of AFWIJKT.\n\nMATERIAAL:\n"""${checkText}"""\n\nJSON: {"score":0-100,"verdict":"korte conclusie","issues":[{"title":"...","text":"wat wijkt af en hoe te herstellen","severity":"hoog|midden|laag"}],"strengths":["wat past goed"]}`;
    const r = await callAI(prompt, { json: true });
    setCheckResult(r); setChecking(false);
  };

  // company management
  const [coForm, setCoForm] = useState(null);
  const saveCo = () => {
    if (!coForm.name) return;
    if (coForm.id) saveCompanies(companies.map(c => c.id === coForm.id ? coForm : c));
    else saveCompanies([...companies, { ...coForm, id: Date.now() }]);
    setCoForm(null);
  };
  // user management
  const [uForm, setUForm] = useState(null);
  const saveU = () => {
    if (!uForm.name) return;
    if (uForm.id) saveUsers(users.map(u => u.id === uForm.id ? uForm : u));
    else saveUsers([...users, { ...uForm, id: Date.now() }]);
    setUForm(null);
  };

  return (
    <div>
      <PageHead title="Merkprofiel" sub="De kennisbasis van je merk. Alles in de tool spiegelt hiertegen."
        right={<Btn variant={dirty ? "yellow" : "ghost"} icon={saved ? Check : Save} onClick={save} disabled={!dirty && !saved}>{saved ? "Opgeslagen" : "Opslaan"}</Btn>} />

      {/* AI start */}
      <Card style={{ marginBottom: 22, background: C.ink, border: "none" }}>
        <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
          <Sparkles size={20} style={{ color: C.yellow }} />
          <span style={{ fontWeight: 700, fontSize: 17, color: "#fff", fontFamily: FONT_DISPLAY }}>Start met AI</span>
        </div>
        <div style={{ fontSize: 13.5, color: "#B9B7B0", marginBottom: 16, lineHeight: 1.5 }}>Lever je website, brandbook, templates of logo aan. AI vult het profiel voor je in — daarna pas je het handmatig aan.</div>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 12 }}>
          <input value={sources.website} onChange={e => setSources(s => ({ ...s, website: e.target.value }))} placeholder="Website-URL (bijv. whitevision.com)" style={darkInput} />
          <button onClick={() => fileRef.current?.click()} style={{ ...darkInput, cursor: "pointer", display: "flex", alignItems: "center", gap: 8, color: "#B9B7B0", textAlign: "left" }}>
            <Upload size={15} /> {uploadNames.length ? `${uploadNames.length} bestand(en)` : "Upload brandbook / template / logo"}
          </button>
          <input ref={fileRef} type="file" multiple onChange={handleFiles} style={{ display: "none" }} />
        </div>
        <textarea value={sources.extra} onChange={e => setSources(s => ({ ...s, extra: e.target.value }))} rows={3} placeholder="Of plak hier vrije input: bestaande propositie, doelstellingen, kleuren, concurrenten…"
          style={{ ...darkInput, width: "100%", boxSizing: "border-box", resize: "vertical", marginBottom: 12, fontFamily: FONT_BODY }} />
        <Btn variant="yellow" icon={Sparkles} onClick={aiFill} disabled={aiBusy}>{aiBusy ? "AI vult het profiel in…" : "Profiel invullen met AI"}</Btn>
        {aiBusy && <div style={{ marginTop: 10 }}><Spinner label="Velden genereren op basis van je input…" /></div>}
      </Card>

      {/* fields */}
      <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 18 }}>
        {PROFILE_FIELDS.map(f => (
          <Card key={f.key}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 10 }}>
              <f.icon size={16} style={{ color: C.yellowDark }} />
              <span style={{ fontWeight: 700, fontSize: 14.5 }}>{f.label}</span>
            </div>
            <textarea value={p[f.key] || ""} onChange={e => set(f.key, e.target.value)} rows={4} placeholder={`Vul ${f.label.toLowerCase()} in of laat AI dit doen…`}
              style={{ width: "100%", boxSizing: "border-box", padding: "10px 12px", border: `1.5px solid ${C.line}`, borderRadius: 10, fontFamily: FONT_BODY, fontSize: 13.5, resize: "vertical", outline: "none", lineHeight: 1.5, color: C.ink }}
              onFocus={e => e.target.style.borderColor = C.yellow} onBlur={e => e.target.style.borderColor = C.line} />
          </Card>
        ))}
        {/* colors special */}
        <Card>
          <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 10 }}>
            <Palette size={16} style={{ color: C.yellowDark }} /><span style={{ fontWeight: 700, fontSize: 14.5 }}>Huisstijlkleuren</span>
          </div>
          <input value={p.colors || ""} onChange={e => set("colors", e.target.value)} placeholder="#F9C112, #1C1C1A"
            style={{ width: "100%", boxSizing: "border-box", padding: "10px 12px", border: `1.5px solid ${C.line}`, borderRadius: 10, fontFamily: FONT_BODY, fontSize: 13.5, outline: "none" }} />
          <div style={{ display: "flex", gap: 8, marginTop: 12, flexWrap: "wrap" }}>
            {(p.colors || "").split(",").map(c => c.trim()).filter(Boolean).map((c, i) => (
              <div key={i} style={{ display: "flex", alignItems: "center", gap: 6 }}>
                <div style={{ width: 26, height: 26, borderRadius: 7, background: c, border: `1px solid ${C.line}` }} /><span style={{ fontSize: 12, color: C.muted }}>{c}</span>
              </div>
            ))}
          </div>
        </Card>
      </div>

      {/* Compliance checker */}
      <Card style={{ marginTop: 22, border: `1.5px solid ${C.yellow}` }}>
        <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 6 }}><AIBadge /><span style={{ fontWeight: 700, fontSize: 16 }}>Brand-consistentie checker</span></div>
        <div style={{ fontSize: 13.5, color: C.muted, marginBottom: 14, lineHeight: 1.5 }}>Plak een tekst of uiting. AI toetst of het klopt met je tone-of-voice en brandbook en markeert wat afwijkt.</div>
        <Field label="Te controleren materiaal" value={checkText} onChange={setCheckText} multiline rows={4} placeholder="Plak hier een stuk website-copy, een social post, e-mail…" />
        <Btn variant="yellow" icon={CheckCircle2} onClick={runCheck} disabled={checking || !checkText || !p.filled}>{checking ? "Controleren…" : "Controleer tegen merk"}</Btn>
        {!p.filled && <span style={{ fontSize: 12.5, color: C.muted, marginLeft: 12 }}>Vul en sla eerst je profiel op.</span>}
        {checking && <div style={{ marginTop: 12 }}><Spinner label="Toetsen tegen tone-of-voice…" /></div>}
        {checkResult && !checking && (
          <div style={{ marginTop: 16 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: 12 }}>
              <div style={{ position: "relative", width: 60, height: 60 }}>
                <svg width="60" height="60" style={{ transform: "rotate(-90deg)" }}>
                  <circle cx="30" cy="30" r="25" fill="none" stroke={C.line} strokeWidth="6" />
                  <circle cx="30" cy="30" r="25" fill="none" stroke={checkResult.score >= 75 ? C.good : checkResult.score >= 50 ? C.yellowDark : C.bad} strokeWidth="6" strokeDasharray={`${(checkResult.score / 100) * 157} 157`} strokeLinecap="round" />
                </svg>
                <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", fontWeight: 700, fontSize: 16 }}>{checkResult.score}</div>
              </div>
              <div style={{ fontSize: 14.5, fontWeight: 600, color: C.ink2, flex: 1 }}>{checkResult.verdict}</div>
            </div>
            {checkResult.strengths?.length > 0 && (
              <div style={{ marginBottom: 10 }}>
                {checkResult.strengths.map((s, i) => <div key={i} style={{ display: "flex", gap: 8, fontSize: 13.5, color: C.good, marginBottom: 4 }}><CheckCircle2 size={15} style={{ flexShrink: 0, marginTop: 1 }} /> {s}</div>)}
              </div>
            )}
            {checkResult.issues?.length > 0 && <Insights items={checkResult.issues} onAction={ctx.addAction} prefix="Brand-check" />}
          </div>
        )}
      </Card>

      {/* Acquired companies */}
      <Card style={{ marginTop: 22 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 9 }}><Briefcase size={18} style={{ color: C.yellowDark }} /><span style={{ fontWeight: 700, fontSize: 16 }}>Overgenomen bedrijven</span></div>
          <Btn size="sm" variant="ghost" icon={Plus} onClick={() => setCoForm({ name: "", country: "", segment: "", status: "endorsed", notes: "", monitor: false })}>Bedrijf</Btn>
        </div>
        {coForm && (
          <div style={{ padding: 16, background: C.paper, borderRadius: 12, marginBottom: 14, border: `1px solid ${C.line}` }}>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 10 }}>
              <Field label="Naam" value={coForm.name} onChange={v => setCoForm({ ...coForm, name: v })} />
              <Field label="Land" value={coForm.country} onChange={v => setCoForm({ ...coForm, country: v })} />
              <Field label="Segment / focus" value={coForm.segment} onChange={v => setCoForm({ ...coForm, segment: v })} />
              <div style={{ marginBottom: 16 }}>
                <label style={{ display: "block", fontSize: 12.5, fontWeight: 700, color: C.muted, marginBottom: 6, letterSpacing: .3, textTransform: "uppercase" }}>Merkstatus</label>
                <select value={coForm.status} onChange={e => setCoForm({ ...coForm, status: e.target.value })} style={{ width: "100%", padding: "11px 13px", border: `1.5px solid ${C.line}`, borderRadius: 10, fontFamily: FONT_BODY, fontSize: 14, outline: "none", background: "#fff" }}>
                  <option value="endorsed">Endorsed (overgang)</option>
                  <option value="rebranded">Gerebrand naar whitevision</option>
                  <option value="standalone">Zelfstandig merk</option>
                </select>
              </div>
            </div>
            <Field label="Notities" value={coForm.notes} onChange={v => setCoForm({ ...coForm, notes: v })} multiline rows={2} />
            <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "10px 13px", background: "#fff", border: `1.5px solid ${C.line}`, borderRadius: 10, marginBottom: 14 }}>
              <Radar size={16} style={{ color: C.yellowDark }} />
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13.5, fontWeight: 700 }}>Monitoren in de Monitor-sectie</div>
                <div style={{ fontSize: 12, color: C.muted }}>Volg dit bedrijf doorlopend op activiteit en merkafwijkingen.</div>
              </div>
              <Toggle on={!!coForm.monitor} onChange={() => setCoForm({ ...coForm, monitor: !coForm.monitor })} />
            </div>
            <div style={{ display: "flex", gap: 10 }}><Btn variant="yellow" onClick={saveCo}>Opslaan</Btn><Btn variant="ghost" onClick={() => setCoForm(null)}>Annuleren</Btn></div>
          </div>
        )}
        {companies.length === 0 && !coForm && <div style={{ fontSize: 13.5, color: C.muted }}>Nog geen overgenomen bedrijven vastgelegd.</div>}
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          {companies.map(c => (
            <div key={c.id} style={{ display: "flex", alignItems: "center", gap: 12, padding: "12px 14px", background: C.paper, borderRadius: 11, border: `1px solid ${C.line}` }}>
              <div style={{ width: 36, height: 36, borderRadius: 9, background: C.ink, display: "grid", placeItems: "center", color: C.yellow, fontWeight: 700, fontFamily: FONT_DISPLAY }}>{c.name?.[0]?.toUpperCase() || "?"}</div>
              <div style={{ flex: 1 }}>
                <div style={{ fontWeight: 700, fontSize: 14.5, display: "flex", alignItems: "center", gap: 8 }}>{c.name}
                  <Tag color={c.status === "rebranded" ? C.good : c.status === "endorsed" ? C.yellowDark : C.blue}>{c.status === "rebranded" ? "gerebrand" : c.status === "endorsed" ? "endorsed" : "standalone"}</Tag>
                  {c.monitor && <Tag color={C.ink} bg={C.yellow}>● monitor</Tag>}</div>
                <div style={{ fontSize: 12.5, color: C.muted, marginTop: 2 }}>{[c.country, c.segment].filter(Boolean).join(" · ")}{c.notes ? " — " + c.notes : ""}</div>
              </div>
              <button onClick={() => setCoForm(c)} style={{ background: "none", border: "none", cursor: "pointer", color: C.muted }}><Edit3 size={15} /></button>
              <button onClick={() => saveCompanies(companies.filter(x => x.id !== c.id))} style={{ background: "none", border: "none", cursor: "pointer", color: C.bad }}><Trash2 size={15} /></button>
            </div>
          ))}
        </div>
      </Card>

      {/* Users */}
      <Card style={{ marginTop: 22, marginBottom: 30 }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 14 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 9 }}><Users size={18} style={{ color: C.yellowDark }} /><span style={{ fontWeight: 700, fontSize: 16 }}>Gebruikers</span></div>
          <Btn size="sm" variant="ghost" icon={Plus} onClick={() => setUForm({ name: "", email: "", role: "Teamlid" })}>Gebruiker</Btn>
        </div>
        {uForm && (
          <div style={{ padding: 16, background: C.paper, borderRadius: 12, marginBottom: 14, border: `1px solid ${C.line}` }}>
            <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr 1fr", gap: 10 }}>
              <Field label="Naam" value={uForm.name} onChange={v => setUForm({ ...uForm, name: v })} />
              <Field label="E-mail" value={uForm.email} onChange={v => setUForm({ ...uForm, email: v })} />
              <Field label="Rol" value={uForm.role} onChange={v => setUForm({ ...uForm, role: v })} />
            </div>
            <div style={{ display: "flex", gap: 10 }}><Btn variant="yellow" onClick={saveU}>Opslaan</Btn><Btn variant="ghost" onClick={() => setUForm(null)}>Annuleren</Btn></div>
          </div>
        )}
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          {users.map(u => (
            <div key={u.id} style={{ display: "flex", alignItems: "center", gap: 12, padding: "12px 14px", background: C.paper, borderRadius: 11, border: `1px solid ${C.line}` }}>
              <div style={{ width: 36, height: 36, borderRadius: 99, background: C.yellow, display: "grid", placeItems: "center", color: C.ink, fontWeight: 700 }}>{u.name?.[0]?.toUpperCase() || "?"}</div>
              <div style={{ flex: 1 }}><div style={{ fontWeight: 700, fontSize: 14.5 }}>{u.name}</div><div style={{ fontSize: 12.5, color: C.muted }}>{u.email} · {u.role}</div></div>
              <button onClick={() => setUForm(u)} style={{ background: "none", border: "none", cursor: "pointer", color: C.muted }}><Edit3 size={15} /></button>
              {users.length > 1 && <button onClick={() => saveUsers(users.filter(x => x.id !== u.id))} style={{ background: "none", border: "none", cursor: "pointer", color: C.bad }}><Trash2 size={15} /></button>}
            </div>
          ))}
        </div>
      </Card>
    </div>
  );
}
const darkInput = { padding: "11px 13px", border: "1.5px solid #3a3a36", borderRadius: 10, fontFamily: FONT_BODY, fontSize: 14, outline: "none", background: "#252521", color: "#fff" };


/* ============================== MOUNT ============================== */
const root = createRoot(document.getElementById("root"));
root.render(React.createElement(App));
