import React, { useEffect, useState } from "react";
import { login, refresh, fetchPacks, fetchLearnerState, putLearnerState, createRenderJob, listRenderJobs, listArtifacts, updateRetention, exportKnowledge } from "./api";
import { loadAuth, saveAuth, clearAuth } from "./authStore";

function LoginView({ onAuth }) {
  const [username, setUsername] = useState("wesley");
  const [password, setPassword] = useState("demo-pass");
  const [error, setError] = useState("");
  async function doLogin() {
    try {
      const result = await login(username, password);
      saveAuth(result);
      onAuth(result);
    } catch { setError("Login failed"); }
  }
  return (
    <div className="page narrow-page">
      <section className="card narrow">
        <h1>Didactopus login</h1>
        <label>Username<input value={username} onChange={(e) => setUsername(e.target.value)} /></label>
        <label>Password<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} /></label>
        <button className="primary" onClick={doLogin}>Login</button>
        {error ? <div className="error">{error}</div> : null}
      </section>
    </div>
  );
}

export default function App() {
  const [auth, setAuth] = useState(loadAuth());
  const [packs, setPacks] = useState([]);
  const [learnerId] = useState("wesley-learner");
  const [packId, setPackId] = useState("");
  const [jobs, setJobs] = useState([]);
  const [artifacts, setArtifacts] = useState([]);
  const [knowledge, setKnowledge] = useState(null);
  const [format, setFormat] = useState("gif");
  const [fps, setFps] = useState(2);
  const [message, setMessage] = useState("");

  async function refreshAuthToken() {
    if (!auth?.refresh_token) return null;
    try {
      const result = await refresh(auth.refresh_token);
      saveAuth(result);
      setAuth(result);
      return result;
    } catch {
      clearAuth();
      setAuth(null);
      return null;
    }
  }

  async function guarded(fn) {
    try { return await fn(auth.access_token); }
    catch {
      const next = await refreshAuthToken();
      if (!next) throw new Error("auth failed");
      return await fn(next.access_token);
    }
  }

  async function reloadLists() {
    setJobs(await guarded((token) => listRenderJobs(token, learnerId)));
    setArtifacts(await guarded((token) => listArtifacts(token, learnerId)));
  }

  useEffect(() => {
    if (!auth) return;
    async function load() {
      const p = await guarded((token) => fetchPacks(token));
      setPacks(p);
      setPackId(p[0]?.id || "");
      await reloadLists();
    }
    load();
  }, [auth]);

  async function generateDemo() {
    let state = await guarded((token) => fetchLearnerState(token, learnerId));
    const base = Date.now();
    const events = [
      ["intro", 0.30, "exercise", 0],
      ["intro", 0.78, "review", 1000],
      ["second", 0.42, "exercise", 2000],
      ["second", 0.72, "review", 3000],
      ["third", 0.25, "exercise", 4000],
      ["branch", 0.60, "exercise", 5000],
    ];
    const latest = {};
    for (const [cid, score, kind, offset] of events) {
      const ts = new Date(base + offset).toISOString();
      state.history.push({ concept_id: cid, dimension: "mastery", score, confidence_hint: 0.6, timestamp: ts, kind, source_id: `demo-${cid}-${offset}` });
      latest[cid] = { concept_id: cid, dimension: "mastery", score, confidence: Math.min(0.9, score), evidence_count: (latest[cid]?.evidence_count || 0) + 1, last_updated: ts };
    }
    state.records = Object.values(latest);
    await guarded((token) => putLearnerState(token, learnerId, state));
    setMessage("Demo state generated.");
  }

  async function createJob() {
    const result = await guarded((token) => createRenderJob(token, learnerId, packId, { learner_id: learnerId, pack_id: packId, format, fps, theme: "default", retention_class: "standard", retention_days: 30 }));
    setMessage(`Render job ${result.job_id} queued.`);
    setTimeout(() => reloadLists(), 500);
  }

  async function changeRetention(artifactId) {
    await guarded((token) => updateRetention(token, artifactId, { retention_class: "archive", retention_days: 365 }));
    await reloadLists();
    setMessage(`Artifact ${artifactId} retention updated.`);
  }

  async function runKnowledgeExport() {
    const result = await guarded((token) => exportKnowledge(token, learnerId, packId, { learner_id: learnerId, pack_id: packId, export_kind: "knowledge_snapshot" }));
    setKnowledge(result);
    setMessage("Knowledge export generated.");
  }

  if (!auth) return <LoginView onAuth={setAuth} />;

  return (
    <div className="page">
      <header className="hero">
        <div>
          <h1>Didactopus artifact lifecycle + knowledge export</h1>
          <p>Manage artifact retention and turn learner state into reusable knowledge outputs.</p>
          <div className="muted">{message}</div>
        </div>
        <div className="controls">
          <label>Pack
            <select value={packId} onChange={(e) => setPackId(e.target.value)}>
              {packs.map((p) => <option key={p.id} value={p.id}>{p.title}</option>)}
            </select>
          </label>
          <label>Format
            <select value={format} onChange={(e) => setFormat(e.target.value)}>
              <option value="gif">GIF</option>
              <option value="mp4">MP4</option>
            </select>
          </label>
          <label>FPS
            <input type="number" value={fps} onChange={(e) => setFps(Number(e.target.value || 2))} />
          </label>
          <button onClick={generateDemo}>Generate demo state</button>
          <button onClick={createJob}>Create render job</button>
          <button onClick={runKnowledgeExport}>Export knowledge</button>
          <button onClick={reloadLists}>Refresh lists</button>
          <button onClick={() => { clearAuth(); setAuth(null); }}>Logout</button>
        </div>
      </header>

      <main className="layout threecol">
        <section className="card">
          <h2>Render jobs</h2>
          <pre className="prebox">{JSON.stringify(jobs, null, 2)}</pre>
        </section>
        <section className="card">
          <h2>Artifacts</h2>
          <pre className="prebox">{JSON.stringify(artifacts, null, 2)}</pre>
          {artifacts[0] ? <button onClick={() => changeRetention(artifacts[0].artifact_id)}>Archive newest artifact</button> : null}
        </section>
        <section className="card">
          <h2>Knowledge export</h2>
          <pre className="prebox">{JSON.stringify(knowledge, null, 2)}</pre>
        </section>
      </main>
    </div>
  );
}
