/* KitRate — app shell, routing, tweaks */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#1F3A8F",
  "fonts": "newsreader",
  "kitTemplate": "editorial",
  "kitDensity": "comfortable",
  "hoverLift": "subtle",
  "pressFx": "springy",
  "navUnderline": true,
  "countup": "share",
  "reveal": true
}/*EDITMODE-END*/;

const ACCENTS = ["#1F3A8F", "#B4540A", "#1F5C40", "#7A2E2E"];

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  /* expose interaction tweaks to non-React readers (kit document motion gating) */
  window.KR_TWEAKS = t;
  const publicPath = KitRateAPI.resolvePublicPath(location.pathname);
  const initialHash = KitRateProduct.resolveKitHash(location.hash);
  const [route, setRoute] = useState(() => publicPath ? "public" : initialHash.route || localStorage.getItem("kitrate.route.v1") || "landing");
  const [shareBrand, setShareBrand] = useState(() => {
    if (!initialHash.brandSlug) return null;
    return loadBrandLinks().find(l => brandSlug(l.brand) === initialHash.brandSlug) || null;
  });
  const [profile, setProfileRaw] = useState(() => window.loadProfile());
  const [bm, setBmRaw] = useState(() => window.loadBenchmarks());
  const [serverState, setServerState] = useState({ ready: false, available: false, updatedAt: null });
  const [integrations, setIntegrations] = useState({
    instagram: { connected: false, configured: false, provider: "instagram" },
    youtube: { connected: false, configured: false, provider: "youtube" },
    tiktok: { connected: false, configured: false, provider: "tiktok" }
  });
  const [publicKit, setPublicKit] = useState(null);
  const [publicError, setPublicError] = useState(null);
  const [publishedSlug, setPublishedSlug] = useState(() => localStorage.getItem("kitrate.published-slug.v1") || "");
  const [kitAnalytics, setKitAnalytics] = useState(null);
  const [deals, setDeals] = useState(() => {
    try { return JSON.parse(localStorage.getItem("kitrate.deals.v1") || "[]"); }
    catch (e) { return []; }
  });
  const importRef = useRef(null);
  const hydratedRef = useRef(false);
  const [kitConfig, setKitConfigRaw] = useState(() => {
    try {
      const raw = localStorage.getItem("kitrate.kitconfig.v1");
      if (raw) {
        const c = JSON.parse(raw);
        /* migration: configs saved before new sections shipped */
        KIT_SECTIONS.forEach(s => {
          if (!c.order.includes(s.id)) {
            const after = c.order.indexOf("metrics");
            c.order.splice(after >= 0 ? after + 1 : c.order.length, 0, s.id);
          }
        });
        if (!c.showcaseKpi) c.showcaseKpi = "smart";
        /* migration: 4th package ("Testing the Waters") prepended in front of the rates-based three */
        if (Array.isArray(c.packageNames) && c.packageNames.length === 3) {
          c.packageNames = ["Testing the Waters", ...c.packageNames];
        }
        return c;
      }
    } catch (e) {}
    return JSON.parse(JSON.stringify(DEFAULT_KIT_CONFIG));
  });

  const setProfile = (p) => { setProfileRaw(p); window.saveProfile(p); };
  const setBm = (b) => { setBmRaw(b); window.saveBenchmarks(b); };
  const setKitConfig = (c) => { setKitConfigRaw(c); localStorage.setItem("kitrate.kitconfig.v1", JSON.stringify(c)); };
  const go = (r) => {
    setRoute(r);
    localStorage.setItem("kitrate.route.v1", r);
    if (location.pathname.startsWith("/k/")) {
      history.replaceState(null, "", "/KitRate#" + r);
    } else if (r !== "share") {
      history.replaceState(null, "", "#" + r);
    }
    window.scrollTo(0, 0);
  };

  useEffect(() => {
    let cancelled = false;
    const start = async () => {
      if (publicPath) {
        try {
          const kit = await KitRateAPI.getPublicKit(publicPath.slug, publicPath.brandSlug);
          if (cancelled) return;
          setPublicKit(kit);
          setPublicError(null);
        } catch (error) {
          if (!cancelled) setPublicError(error.message);
        }
        return;
      }

      const result = await KitRateAPI.bootstrap();
      if (cancelled) return;
      if (result.available) {
        const remote = result.workspace || {};
        if (remote.profile && remote.config) {
          setProfile(remote.profile);
          setKitConfig(remote.config);
        } else {
          await KitRateAPI.saveWorkspace(profile, kitConfig);
        }
        setIntegrations((current) => ({ ...current, ...(result.integrations || {}) }));
        try {
          const response = await KitRateAPI.listDeals();
          setDeals(response.deals || []);
        } catch (e) {}
        setServerState({ ready: true, available: true, updatedAt: remote.updatedAt || null });
      } else {
        setServerState({ ready: true, available: false, updatedAt: null });
      }
      hydratedRef.current = true;
    };
    start();
    return () => { cancelled = true; };
  }, []);

  useEffect(() => {
    if (!serverState.ready || !serverState.available || !hydratedRef.current || publicPath) return;
    const timer = setTimeout(async () => {
      try {
        const result = await KitRateAPI.saveWorkspace(profile, kitConfig);
        setServerState((current) => ({ ...current, updatedAt: result.updatedAt || current.updatedAt }));
      } catch (e) {
        setServerState((current) => ({ ...current, available: false }));
      }
    }, 500);
    return () => clearTimeout(timer);
  }, [profile, kitConfig, serverState.ready]);

  useEffect(() => {
    if (!serverState.ready || publicPath) return;
    const params = new URLSearchParams(location.search);
    const provider = ["instagram", "youtube", "tiktok"].find((name) => params.get(name));
    if (!provider) return;
    history.replaceState(null, "", location.pathname + "#build");
    setRoute("build");
    KitRateAPI.bootstrap().then((result) => {
      if (!result.available) return;
      if (result.workspace?.profile) setProfile(result.workspace.profile);
      setIntegrations((current) => ({ ...current, ...(result.integrations || {}) }));
    }).catch(() => {});
  }, [serverState.ready]);

  useEffect(() => {
    localStorage.setItem("kitrate.deals.v1", JSON.stringify(deals));
  }, [deals]);

  useEffect(() => {
    const onHash = () => {
      const next = KitRateProduct.resolveKitHash(location.hash);
      if (next.route === "share") {
        setShareBrand(next.brandSlug ? loadBrandLinks().find(l => brandSlug(l.brand) === next.brandSlug) || null : null);
        setRoute("share");
        return;
      }
      if (next.route) {
        setShareBrand(null);
        setRoute(next.route);
        localStorage.setItem("kitrate.route.v1", next.route);
      }
    };
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);

  const resetKitConfig = () => {
    const fresh = JSON.parse(JSON.stringify(DEFAULT_KIT_CONFIG));
    setKitConfig(fresh);
    localStorage.removeItem("kitrate.versions.v1");
  };

  const startBlank = () => {
    setProfile(JSON.parse(JSON.stringify(window.KITRATE_EMPTY_PROFILE)));
    resetKitConfig();
    go("build");
  };

  const loadSample = () => {
    setProfile(JSON.parse(JSON.stringify(window.KITRATE_SAMPLE_PROFILE)));
    resetKitConfig();
    go("kit");
  };

  const connectIntegration = (provider) => {
    try { KitRateAPI.connectIntegration(provider); }
    catch (error) { alert(error.message); }
  };

  const syncIntegration = async (provider) => {
    const result = await KitRateAPI.syncIntegration(provider);
    if (result.profile) setProfile(result.profile);
    const status = await KitRateAPI.integrationStatus(provider);
    setIntegrations((current) => ({ ...current, [provider]: status }));
    return result;
  };

  const disconnectIntegration = async (provider) => {
    const result = await KitRateAPI.disconnectIntegration(provider);
    if (result.profile) setProfile(result.profile);
    setIntegrations((current) => ({
      ...current,
      [provider]: {
        connected: false,
        configured: !!current[provider]?.configured,
        provider
      }
    }));
  };

  const saveDeal = async (input) => {
    const deal = {
      id: input.id || (crypto.randomUUID ? crypto.randomUUID() : String(Date.now())),
      brandName: input.brandName || "Unnamed brand",
      campaignName: input.campaignName || "",
      stage: input.stage || "lead",
      amount: input.amount ?? null,
      currency: input.currency || "USD",
      fitScore: input.fitScore ?? null,
      deliverables: input.deliverables || [],
      rights: input.rights || {},
      outcome: input.outcome || {},
      updatedAt: new Date().toISOString()
    };
    setDeals((current) => {
      const exists = current.some((row) => row.id === deal.id);
      return exists ? current.map((row) => row.id === deal.id ? deal : row) : [deal, ...current];
    });
    if (serverState.available) {
      try {
        const response = await KitRateAPI.saveDeal(deal);
        setDeals((current) => current.map((row) => row.id === deal.id ? response.deal : row));
        return response.deal;
      } catch (e) {}
    }
    return deal;
  };

  const removeDeal = async (id) => {
    setDeals((current) => current.filter((row) => row.id !== id));
    if (serverState.available) {
      try { await KitRateAPI.deleteDeal(id); } catch (e) {}
    }
  };

  const exportWorkspace = () => {
    const payload = KitRateProduct.serializeKitData(profile, bm, kitConfig, rates);
    KitRateProduct.downloadText(
      KitRateProduct.slugify(profile.name || "kitrate-media-kit") + "-kitrate-data.json",
      JSON.stringify(payload, null, 2),
      "application/json;charset=utf-8"
    );
  };

  const importWorkspace = (file) => {
    if (!file) return;
    file.text().then((text) => {
      const payload = JSON.parse(text);
      if (payload.schema !== "kitrate.creator-kit.v1" || !payload.profile || !payload.config) {
        throw new Error("Not a KitRate export");
      }
      setProfile(payload.profile);
      setKitConfig(payload.config);
      go("kit");
    }).catch(() => alert("That file does not look like a valid KitRate export."));
  };

  /* live rates — recompute whenever profile OR benchmarks change */
  const rates = useMemo(() => KitRateEngine.computeRates(profile, bm), [profile, bm]);

  const publishShare = async (link, navigate = true) => {
    if (serverState.available) {
      const result = await KitRateAPI.publishKit(profile, kitConfig, rates, link ? {
        name: link.brand,
        note: link.note || ""
      } : null);
      setPublishedSlug(result.slug);
      localStorage.setItem("kitrate.published-slug.v1", result.slug);
      if (navigate) location.href = result.url;
      return result.url;
    }
    const url = KitRateProduct.buildPublicKitUrl({
      origin: location.origin || "file://",
      pathname: location.pathname,
      profileName: profile.name,
      brandName: link ? link.brand : null
    });
    if (navigate) {
      setShareBrand(link || null);
      location.hash = url.split("#")[1] || "share";
    }
    return url;
  };

  const refreshKitAnalytics = async () => {
    if (!publishedSlug || !serverState.available) {
      setKitAnalytics(null);
      return null;
    }
    const result = await KitRateAPI.getKitAnalytics(publishedSlug);
    setKitAnalytics(result);
    return result;
  };

  /* tweaks → CSS vars / kit template */
  useEffect(() => {
    const root = document.documentElement;
    root.style.setProperty("--accent", t.accent);
    const soft = { "#1F3A8F": ["#ECEFF9", "#C5CDE8"], "#B4540A": ["#F8EDE2", "#E8CDB2"], "#1F5C40": ["#E7F1EA", "#BDD8C7"], "#7A2E2E": ["#F5E7E5", "#E0BFBA"] }[t.accent] || ["#ECEFF9", "#C5CDE8"];
    root.style.setProperty("--accent-soft", soft[0]);
    root.style.setProperty("--accent-line", soft[1]);
    root.setAttribute("data-fonts", t.fonts === "newsreader" ? "" : t.fonts);
  }, [t.accent, t.fonts]);

  /* interaction tweaks → data attrs on <html> (see kitrate.css "interaction tweaks") */
  useEffect(() => {
    const root = document.documentElement;
    root.setAttribute("data-hover", t.hoverLift);
    root.setAttribute("data-press", t.pressFx);
    if (t.navUnderline) root.setAttribute("data-nav-underline", "");
    else root.removeAttribute("data-nav-underline");
  }, [t.hoverLift, t.pressFx, t.navUnderline]);

  useEffect(() => {
    if (t.kitTemplate !== kitConfig.templateId || t.kitDensity !== kitConfig.density) {
      setKitConfig({ ...kitConfig, templateId: t.kitTemplate, density: t.kitDensity });
    }
  }, [t.kitTemplate, t.kitDensity]);

  const navItems = [
    ["build", "Build"],
    ["rates", "Rates"],
    ["kit", "Media kit"],
    ["intelligence", "Deal intelligence"]
  ];

  if (route === "public") {
    if (publicError) {
      return <div style={{ maxWidth: 680, margin: "90px auto", padding: 32 }}><EmptyState icon="warn" title="Kit unavailable" desc={publicError} /></div>;
    }
    if (!publicKit) {
      return <div style={{ maxWidth: 680, margin: "90px auto", padding: 32 }}><EmptyState icon="clock" title="Loading media kit" desc="Fetching the creator's published snapshot." /></div>;
    }
    return <BrandShareView profile={publicKit.profile} rates={publicKit.rates} config={publicKit.config}
      brand={publicKit.brand} publicMode publicSlug={publicKit.slug} publicBrandSlug={publicPath.brandSlug} />;
  }

  return (
    <div>
      {route !== "share" && (
      <nav className="kr-topnav kr-no-print">
        <div className="kr-wordmark" onClick={() => go("landing")}>Kit<em>Rate</em></div>
        <div style={{ display: "flex", gap: 20, flex: 1 }}>
          {navItems.map(([r, lbl]) => (
            <button key={r} className={"kr-navlink" + (route === r ? " active" : "")} onClick={() => go(r)}>{lbl}</button>
          ))}
        </div>
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <input ref={importRef} type="file" accept="application/json,.json" style={{ display: "none" }} onChange={(e) => importWorkspace(e.target.files && e.target.files[0])} />
          <button className="kr-btn kr-btn-ghost kr-btn-sm" onClick={startBlank}><KrIcon d={ICONS.plus} size={13} /> New</button>
          <button className="kr-btn kr-btn-ghost kr-btn-sm" onClick={() => importRef.current && importRef.current.click()}>Import</button>
          <button className="kr-btn kr-btn-ghost kr-btn-sm" onClick={exportWorkspace}>Export</button>
          <span className={"kr-chip " + (serverState.available ? "kr-chip-good" : "")} style={{ fontSize: 9.5 }}>
            {serverState.available ? "Cloud saved" : "Device draft"}
          </span>
          <span className="kr-avatar" style={{ width: 30, height: 30, fontSize: 13 }}>{(profile.name || "K").charAt(0)}</span>
        </div>
      </nav>
      )}

      {route === "landing" && <Landing profile={profile} onStart={startBlank} onSample={loadSample} />}
      {route === "build" && (
        <Wizard profile={profile} setProfile={setProfile} bm={bm}
          onFinish={() => go("rates")} onExit={() => go("landing")}
          integrations={integrations} onConnectIntegration={connectIntegration}
          onSyncIntegration={syncIntegration} onDisconnectIntegration={disconnectIntegration} />
      )}
      {route === "rates" && (
        <RatesDashboard profile={profile} rates={rates} bm={bm}
          onEditMetrics={() => go("build")} onOpenKit={() => go("kit")}
          onOpenIntelligence={() => go("intelligence")} onOpenAdmin={() => go("admin")} />
      )}
      {route === "kit" && (
        <KitEditor profile={profile} setProfile={setProfile} rates={rates} config={kitConfig} setConfig={setKitConfig}
          onBackToRates={() => go("rates")} onPreviewShare={(link) => publishShare(link, true)}
          onPublishShare={(link) => publishShare(link, false)} />
      )}
      {route === "share" && (
        <BrandShareView profile={profile} rates={rates} config={kitConfig} brand={shareBrand} onExit={() => { setShareBrand(null); go("kit"); }} />
      )}
      {route === "intelligence" && (
        <IntelligenceDashboard profile={profile} rates={rates} deals={deals} setDeals={setDeals}
          saveDeal={saveDeal} removeDeal={removeDeal} publishedSlug={publishedSlug}
          analytics={kitAnalytics} onRefreshAnalytics={refreshKitAnalytics} />
      )}
      {route === "admin" && <Admin bm={bm} setBm={setBm} profile={profile} />}

      <div className="kr-no-print">
      <TweaksPanel>
        <TweakSection label="Brand" />
        <TweakColor label="Accent" value={t.accent} options={ACCENTS} onChange={(v) => setTweak("accent", v)} />
        <TweakSelect label="Font pairing" value={t.fonts}
          options={[
            { value: "newsreader", label: "Newsreader + Schibsted" },
            { value: "caslon", label: "Libre Caslon + Archivo" },
            { value: "grotesk", label: "All Schibsted Grotesk" }
          ]}
          onChange={(v) => setTweak("fonts", v)} />
        <TweakSection label="Media kit" />
        <TweakSelect label="Template" value={t.kitTemplate}
          options={KIT_THEMES.map(th => ({ value: th.id, label: th.label }))}
          onChange={(v) => setTweak("kitTemplate", v)} />
        <TweakRadio label="Density" value={t.kitDensity} options={["comfortable", "compact"]} onChange={(v) => setTweak("kitDensity", v)} />
        <TweakSection label="Interaction" />
        <TweakRadio label="Card hover" value={t.hoverLift} options={["off", "subtle", "lifted"]} onChange={(v) => setTweak("hoverLift", v)} />
        <TweakRadio label="Buttons" value={t.pressFx} options={["standard", "springy"]} onChange={(v) => setTweak("pressFx", v)} />
        <TweakToggle label="Nav underline slide" value={t.navUnderline} onChange={(v) => setTweak("navUnderline", v)} />
        <TweakRadio label="Count-up numbers" value={t.countup} options={["off", "share", "everywhere"]} onChange={(v) => setTweak("countup", v)} />
        <TweakToggle label="Kit reveal on scroll" value={t.reveal} onChange={(v) => setTweak("reveal", v)} />
      </TweaksPanel>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
