/* global React */
const { useState: useStateV, useMemo: useMemoV, useEffect: useEffectV } = React;
const { KpiStrip, CommandBar, ControlBar } = window.__dashAtoms;
const { buildNiches, buildStats } = window.__dashUtils;

// compute global axes for spec bars (one pass)
function globalAxes(niches) {
  const prices = niches.flatMap(n => [n.priceMin, n.priceMax]).filter(v => v != null);
  const ranges = niches.flatMap(n => [n.rangeMin, n.rangeMax]).filter(v => v != null);
  return {
    priceMin: 0,
    priceMax: prices.length ? Math.max(...prices) : 1,
    rangeMin: 0,
    rangeMax: ranges.length ? Math.max(...ranges) : 1,
  };
}

// ============================================================
// MAKER LEADERBOARD — small support widget under grid
// ============================================================
function MakerLeaderboard({ accent }) {
  const map = new Map();
  window.UAV_DATA.forEach(m => {
    if (!m.maker || m.maker === "—") return;
    const e = map.get(m.maker) || { maker: m.maker, count: 0, ours: window.IS_OURS(m.maker), niches: new Set() };
    e.count += 1;
    e.niches.add(window.TYPE_TO_NICHE[m.type]);
    map.set(m.maker, e);
  });
  const rows = [...map.values()]
    .map(e => ({ ...e, niches: e.niches.size }))
    .sort((a, b) => b.count - a.count || b.niches - a.niches);
  const max = Math.max(...rows.map(r => r.count));
  return (
    <div style={{ padding: 20, color: "#fff", fontFamily: "var(--sketch)" }}>
      <div style={{ display: "flex", alignItems: "baseline", gap: 10, marginBottom: 14 }}>
        <h3 style={{ margin: 0, fontSize: 12, textTransform: "uppercase", letterSpacing: 2, fontWeight: 700 }}>// Виробники в каталозі</h3>
        <span style={{ fontSize: 11, opacity: 0.45, fontFamily: "var(--mono-num)" }}>{rows.length}</span>
        <span style={{ fontSize: 11, opacity: 0.4, marginLeft: "auto" }}>модельний ряд · кількість ніш</span>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(280px, 1fr))", gap: 6 }}>
        {rows.map(r => (
          <div key={r.maker} style={{
            display: "flex", alignItems: "center", gap: 10,
            padding: "8px 12px",
            background: r.ours ? `color-mix(in srgb, ${accent} 8%, #0a0a0a)` : "#0a0a0a",
            border: `1px solid ${r.ours ? `color-mix(in srgb, ${accent} 40%, transparent)` : "rgba(255,255,255,0.08)"}`,
            borderRadius: 4,
          }}>
            <div style={{
              width: 26, height: 26, display: "grid", placeItems: "center",
              fontFamily: "var(--mono-num)", fontWeight: 700, fontSize: 13,
              background: r.ours ? accent : "rgba(255,255,255,0.06)",
              color: r.ours ? "#000" : "rgba(255,255,255,0.85)", borderRadius: 4,
            }}>{r.count}</div>
            <div style={{ minWidth: 0, flex: 1 }}>
              <div style={{ fontSize: 12, fontWeight: r.ours ? 700 : 500, color: r.ours ? accent : "#fff", textOverflow: "ellipsis", overflow: "hidden", whiteSpace: "nowrap" }}>
                {r.ours && "🍒 "}{r.maker}
              </div>
              <div style={{ height: 2, background: "rgba(255,255,255,0.05)", marginTop: 4, position: "relative" }}>
                <div style={{ position: "absolute", top: 0, left: 0, height: "100%", width: `${100 * r.count / max}%`, background: r.ours ? accent : "rgba(255,255,255,0.35)" }}/>
              </div>
            </div>
            <div style={{ fontSize: 10, opacity: 0.45, fontFamily: "var(--mono-num)" }}>{r.niches}н</div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ============================================================
// HEADER (within variant)
// ============================================================
const Header = ({ title, subtitle, tweaks = {} }) => {
  const accent = tweaks.accent || "#22c55e";
  const upper = tweaks.uppercaseTitles !== false;
  const [a, b] = title.split("—");
  return (
    <div style={{ marginBottom: 18, display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 24 }}>
      <div>
        <div style={{ fontSize: 10, opacity: 0.45, textTransform: "uppercase", letterSpacing: 3, marginBottom: 6, fontWeight: 600 }}>
          Огляд каталогу
        </div>
        <h1 style={{
          margin: 0, fontSize: 26, fontWeight: 800, lineHeight: 1.1,
          textTransform: upper ? "uppercase" : "none", letterSpacing: -0.3,
        }}>
          {a}{b && <span style={{ color: accent }}>— {b.trim()}</span>}
        </h1>
        <div style={{ fontSize: 12, opacity: 0.6, marginTop: 8, maxWidth: 720, lineHeight: 1.5 }}>{subtitle}</div>
      </div>
    </div>
  );
};

const Legend = ({ accent }) => (
  <div style={{
    display: "flex", gap: 18, marginTop: 18, padding: "12px 16px",
    background: "#0a0a0a", border: "1px solid rgba(255,255,255,0.06)",
    fontSize: 11, opacity: 0.75, borderRadius: 6,
  }}>
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <span style={{ width: 10, height: 10, background: accent, borderRadius: 2 }}/>Є наш продукт
    </span>
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <span style={{ width: 10, height: 10, background: "rgba(255,255,255,0.4)", borderRadius: 2 }}/>Тільки конкуренти
    </span>
    <span style={{ display: "inline-flex", alignItems: "center", gap: 6 }}>
      <span style={{ width: 10, height: 10, border: "1px dashed #d9aa50", borderRadius: 2 }}/>Біла пляма
    </span>
    <span style={{ marginLeft: "auto", opacity: 0.5, fontFamily: "var(--mono-num)" }}>↗ клік на нішу — деталі</span>
  </div>
);

// ============================================================
// SORTING
// ============================================================
function sortNiches(arr, mode) {
  const copy = [...arr];
  if (mode === "count-desc") copy.sort((a, b) => b.models.length - a.models.length);
  else if (mode === "count-asc") copy.sort((a, b) => a.models.length - b.models.length);
  else if (mode === "alpha") copy.sort((a, b) => a.title.localeCompare(b.title, "uk"));
  else if (mode === "ours-first") copy.sort((a, b) => (b.hasUs - a.hasUs) || (b.models.length - a.models.length));
  return copy;
}

// ============================================================
// VARIANTS
// ============================================================
function VariantBento({ niches, onOpen, tweaks = {}, gAxes }) {
  const cols = tweaks.columns || 4;
  return (
    <div style={{ padding: 20 }}>
      <Header title="Артилерія БПЛА — ніші, де ми присутні" subtitle="Кожна картка — окрема ніша. Колір окантовки сигналізує статус: акцент = наш продукт у каталозі, пунктир = біла пляма. Клік відкриває розгорнутий список моделей та конкурентів." tweaks={tweaks}/>
      <div style={{ display: "grid", gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: 10 }}>
        {niches.map(n => <window.NicheCard key={n.id} niche={n} onOpen={onOpen} tweaks={tweaks} globalRange={gAxes}/>)}
      </div>
      <Legend accent={tweaks.accent || "#22c55e"}/>
    </div>
  );
}

function VariantClusters({ niches, onOpen, tweaks = {}, gAxes }) {
  const cols = tweaks.columns || 4;
  const accent = tweaks.accent || "#22c55e";
  const clusters = [...new Set(niches.map(n => n.cluster))];
  return (
    <div style={{ padding: 20 }}>
      <Header title="Ландшафт БПЛА — за функціональними кластерами" subtitle="Ніші згруповано за доменом платформи (FPV, коптер, літак, перехоплювач, спеціальні). Це показує, де концентрується конкуренція і де у нас системна присутність." tweaks={tweaks}/>
      {clusters.map(c => {
        const items = niches.filter(n => n.cluster === c);
        if (!items.length) return null;
        const ours = items.filter(n => n.hasUs).length;
        return (
          <section key={c} style={{ marginBottom: 24 }}>
            <div style={{ display: "flex", alignItems: "baseline", gap: 14, marginBottom: 10, paddingBottom: 6, borderBottom: "1px solid rgba(255,255,255,0.08)" }}>
              <h3 style={{ margin: 0, fontSize: 12, textTransform: "uppercase", letterSpacing: 2, color: ours > 0 ? accent : "rgba(255,255,255,0.6)", fontWeight: 700 }}>// {c}</h3>
              <span style={{ fontSize: 10, opacity: 0.5, fontFamily: "var(--mono-num)" }}>{ours} наших · {items.length} ніш</span>
              <div style={{ flex: 1 }}/>
              <div style={{ display: "flex", gap: 2 }}>
                {items.map(n => (
                  <div key={n.id} title={n.title} style={{
                    width: 16, height: 4,
                    background: n.hasUs ? accent : n.isAbsent ? "rgba(217,170,80,0.5)" : "rgba(255,255,255,0.3)",
                  }}/>
                ))}
              </div>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: `repeat(${cols}, 1fr)`, gap: 10 }}>
              {items.map(n => <window.NicheCard key={n.id} niche={n} onOpen={onOpen} size="sm" tweaks={tweaks} globalRange={gAxes}/>)}
            </div>
          </section>
        );
      })}
      <Legend accent={accent}/>
    </div>
  );
}

function VariantMatrix({ niches, onOpen, tweaks = {}, gAxes }) {
  const platforms = ["Крило", "Коптер", "Ракета", "Інше"];
  const purposes = ["Розвідка", "Удар", "Перехоплення", "Носій"];
  const placement = {
    "plane-recon": { p: "Крило", u: "Розвідка" }, "plane-photo": { p: "Крило", u: "Розвідка" },
    "fpv-kamikaze": { p: "Коптер", u: "Удар" }, "fiber": { p: "Коптер", u: "Удар" },
    "plane-kami": { p: "Крило", u: "Удар" }, "copter-bomber": { p: "Коптер", u: "Удар" },
    "fpv-bomber": { p: "Коптер", u: "Удар" }, "plane-bomber": { p: "Крило", u: "Удар" },
    "interceptor-copter": { p: "Коптер", u: "Перехоплення" }, "interceptor-plane": { p: "Крило", u: "Перехоплення" },
    "copter-recon": { p: "Коптер", u: "Розвідка" },
    "mothership": { p: "Крило", u: "Носій" }, "relay": { p: "Крило", u: "Носій" },
    "aerostat": { p: "Інше", u: "Розвідка" }, "decoy": { p: "Інше", u: "Удар" },
  };
  const accent = tweaks.accent || "#22c55e";
  return (
    <div style={{ padding: 20 }}>
      <Header title="Матриця — платформа × призначення" subtitle="Перетин платформи та бойової задачі. Видно, де концентруються коптерні ударні, де крилові носії, і де пусті комірки — потенційні точки входу." tweaks={tweaks}/>
      <div style={{ display: "grid", gridTemplateColumns: `140px repeat(${purposes.length}, 1fr)`, gap: 6 }}>
        <div/>
        {purposes.map(u => (
          <div key={u} style={{
            fontSize: 10, textTransform: "uppercase", letterSpacing: 1.5, opacity: 0.7,
            padding: "8px 4px", borderBottom: "1px solid rgba(255,255,255,0.1)", fontWeight: 700,
            textAlign: "center", color: "#fff",
          }}>{u}</div>
        ))}
        {platforms.map(p => (
          <React.Fragment key={p}>
            <div style={{
              fontSize: 10, textTransform: "uppercase", letterSpacing: 1.5, opacity: 0.7,
              alignSelf: "stretch", display: "flex", alignItems: "center",
              borderRight: "1px solid rgba(255,255,255,0.1)", paddingRight: 10, fontWeight: 700,
            }}>{p}</div>
            {purposes.map(u => {
              const cell = niches.filter(n => placement[n.id]?.p === p && placement[n.id]?.u === u);
              return (
                <div key={u} style={{
                  minHeight: 140, display: "flex", flexDirection: "column", gap: 4, padding: 4,
                  background: cell.length ? "transparent" : "rgba(255,255,255,0.015)",
                }}>
                  {cell.length ? cell.map(n => <window.NicheCard key={n.id} niche={n} onOpen={onOpen} size="sm" tweaks={tweaks} globalRange={gAxes}/>)
                    : <div style={{
                        flex: 1, border: "1px dashed rgba(255,255,255,0.08)",
                        display: "flex", alignItems: "center", justifyContent: "center",
                        fontSize: 10, opacity: 0.3, borderRadius: 4,
                      }}>—</div>}
                </div>
              );
            })}
          </React.Fragment>
        ))}
      </div>
      <Legend accent={accent}/>
    </div>
  );
}

// ============================================================
// TWEAKS DEFAULTS + APP
// ============================================================
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "variant": "bento",
  "accent": "#22c55e",
  "background": "#000000",
  "columns": 4,
  "showCount": true,
  "showSpec": true,
  "showKpi": true,
  "showLeaderboard": true,
  "uppercaseTitles": true
}/*EDITMODE-END*/;

function Dashboard({ variant: initialVariant }) {
  const [t, setTweak] = window.useTweaks(TWEAK_DEFAULTS);
  useEffectV(() => { if (initialVariant) setTweak("variant", initialVariant); }, []);

  const [niche, setNiche] = useStateV("Усі");
  const [maker, setMaker] = useStateV("Усі");
  const [search, setSearch] = useStateV("");
  const [presence, setPresence] = useStateV("all");
  const [sort, setSort] = useStateV("default");
  const [open, setOpen] = useStateV(null);

  // Supabase async load
  const [dataReady, setDataReady] = useStateV(false);
  const [dataError, setDataError] = useStateV(null);
  useEffectV(() => {
    window.loadUAVData()
      .then(() => setDataReady(true))
      .catch(e => setDataError(e.message || String(e)));
  }, []);

  useEffectV(() => { document.body.style.background = t.background; }, [t.background]);

  // Re-build niches whenever data arrives
  const allNiches = useMemoV(() => buildNiches(), [dataReady]);
  const gAxes = useMemoV(() => globalAxes(allNiches), [allNiches]);
  const stats = useMemoV(() => buildStats(allNiches), [allNiches]);

  // counts for filter pill badges (independent of presence filter itself)
  const baseFiltered = useMemoV(() => {
    return allNiches.filter(n => {
      if (niche !== "Усі" && n.title !== niche) return false;
      if (maker !== "Усі") {
        const allModels = [...n.ours, ...n.competitors];
        if (!allModels.some(m => m.maker === maker)) return false;
      }
      if (search) {
        const q = search.toLowerCase();
        const allModels = [...n.ours, ...n.competitors];
        const matchModel = allModels.some(m => m.model.toLowerCase().includes(q) || m.maker.toLowerCase().includes(q));
        if (!matchModel && !n.title.toLowerCase().includes(q)) return false;
      }
      return true;
    });
  }, [allNiches, niche, maker, search]);
  const counts = useMemoV(() => ({
    all: baseFiltered.length,
    ours: baseFiltered.filter(n => n.hasUs).length,
    competitor: baseFiltered.filter(n => !n.hasUs && !n.isAbsent).length,
    absent: baseFiltered.filter(n => n.isAbsent).length,
  }), [baseFiltered]);

  const filtered = useMemoV(() => {
    let arr = baseFiltered;
    if (presence === "ours") arr = arr.filter(n => n.hasUs);
    else if (presence === "absent") arr = arr.filter(n => n.isAbsent);
    else if (presence === "competitor") arr = arr.filter(n => !n.hasUs && !n.isAbsent);
    return sortNiches(arr, sort);
  }, [baseFiltered, presence, sort]);

  const Variant = t.variant === "clusters" ? VariantClusters : t.variant === "matrix" ? VariantMatrix : VariantBento;
  return (
    <div style={{ background: t.background, minHeight: "100%", color: "#fff", "--accent": t.accent }}>
      <CommandBar accent={t.accent}/>
      {dataError && (
        <div style={{
          margin: "16px 20px", padding: "12px 16px", borderRadius: 6,
          border: "1px solid rgba(239,68,68,0.5)", background: "rgba(127,29,29,0.25)",
          fontSize: 13, color: "#fca5a5",
        }}>
          Помилка завантаження: {dataError}
        </div>
      )}
      {!dataReady && !dataError && (
        <div style={{
          display: "flex", alignItems: "center", gap: 10,
          padding: "16px 20px", fontSize: 13, opacity: 0.55,
        }}>
          <div style={{
            width: 14, height: 14, border: `2px solid ${t.accent}`,
            borderTopColor: "transparent", borderRadius: "50%",
            animation: "spin 0.7s linear infinite",
          }}/>
          Завантаження з Supabase…
          <style>{`@keyframes spin{to{transform:rotate(360deg)}}`}</style>
        </div>
      )}
      <ControlBar
        niche={niche} maker={maker} onNiche={setNiche} onMaker={setMaker}
        search={search} onSearch={setSearch}
        presence={presence} onPresence={setPresence}
        sort={sort} onSort={setSort}
        accent={t.accent} counts={counts}
      />
      <div style={{ padding: "20px 20px 0" }}>
        {t.showKpi !== false && <KpiStrip stats={stats} accent={t.accent}/>}
      </div>
      <Variant niches={filtered} onOpen={setOpen} tweaks={t} gAxes={gAxes}/>
      {t.showLeaderboard !== false && dataReady && <MakerLeaderboard accent={t.accent}/>}

      {open && <window.NicheModal niche={open} onClose={() => setOpen(null)} accent={t.accent}/>}

      <window.TweaksPanel title="Tweaks">
        <window.TweakSection label="Вигляд"/>
        <window.TweakRadio label="Layout" value={t.variant}
          options={["bento", "clusters", "matrix"]}
          onChange={v => setTweak("variant", v)}/>
        <window.TweakSlider label="Колонок" value={t.columns} min={2} max={6} step={1}
          onChange={v => setTweak("columns", v)}/>
        <window.TweakSection label="Секції"/>
        <window.TweakToggle label="KPI-стрічка" value={t.showKpi}
          onChange={v => setTweak("showKpi", v)}/>
        <window.TweakToggle label="Spec-бари (ціна/дальн.)" value={t.showSpec}
          onChange={v => setTweak("showSpec", v)}/>
        <window.TweakToggle label="Велика цифра кількості" value={t.showCount}
          onChange={v => setTweak("showCount", v)}/>
        <window.TweakToggle label="Лідерборд виробників" value={t.showLeaderboard}
          onChange={v => setTweak("showLeaderboard", v)}/>
        <window.TweakToggle label="ВЕРХНІЙ РЕГІСТР заголовків" value={t.uppercaseTitles}
          onChange={v => setTweak("uppercaseTitles", v)}/>
        <window.TweakSection label="Кольори"/>
        <window.TweakColor label="Акцент (наші)" value={t.accent}
          options={["#22c55e", "#d97757", "#5ea0ff", "#e3c46b", "#a06fff"]}
          onChange={v => setTweak("accent", v)}/>
        <window.TweakColor label="Фон" value={t.background}
          options={["#000000", "#0a0a0c", "#0f1115", "#171510"]}
          onChange={v => setTweak("background", v)}/>
      </window.TweaksPanel>
    </div>
  );
}

window.Dashboard = Dashboard;
