/* store.jsx — 客户端持久化「后端」for 咔嗒Lab
   一个基于 localStorage 的数据层 + 账号/会话系统。首次加载从 KSITE 播种，
   之后所有发帖 / 点赞 / 评论 / 报名 / 上传作品 / 注册登录都会真正读写并保存。

   Exposes:
     window.KadaStore  — 命令式 API（getDB, subscribe, 各业务方法）
     window.useKadaDB() — React hook：订阅变更并触发重渲染，返回 KadaStore
   Requires: components.jsx (KSITE) 已加载，React 全局可用。
*/
(function () {
  const DBKEY = 'kada.db.v1';
  const SKEY = 'kada.session.v1';
  const subs = new Set();
  let db = null;

  const now = () => Date.now();
  const rid = (p) => p + now().toString(36) + Math.random().toString(36).slice(2, 6);
  const HUES = [222, 256, 200, 268, 188, 244, 210, 176];
  const hueFor = (s) => HUES[[...(s || '?')].reduce((a, c) => a + c.charCodeAt(0), 0) % HUES.length];

  /* ---------- 种子评论 ---------- */
  function seedPostComments(i) {
    const banks = [
      [{ name: 'Mia', hue: 210, t: '8 分钟前', text: '语义分块确实比固定窗口稳，我们还加了一层重叠窗口，召回又好了一些。' },
       { name: '老王', hue: 250, t: '20 分钟前', text: '请问分块大小一般设多少？文档很长的时候 embedding 成本会不会爆？' },
       { name: 'Zoe', hue: 188, t: '1 小时前', text: '马克一下，正好在做类似的场景，感谢分享思路 🙏' }],
      [{ name: '阿楷', hue: 244, t: '15 分钟前', text: '已 Star！可视化调试面板这个点太实用了。' },
       { name: 'Nina', hue: 200, t: '40 分钟前', text: '想问下状态回溯是怎么实现的？有没有简单的例子～' }],
      [{ name: '小柯', hue: 268, t: '半小时前', text: '梯度检查点开了吗？还有 optimizer state 也很吃显存，试试 8bit Adam。' }],
      [{ name: '周可', hue: 222, t: '昨天', text: '清单很全，已收藏。期待多模态评测那块也补充一下。' }],
    ];
    return (banks[i] || []).map((c) => ({ id: rid('cm_'), ...c }));
  }
  function seedWorkComments(i) {
    const banks = [
      [{ name: 'Zoe', hue: 188, t: '1 小时前', text: '试了下效果不错，请问支持批量处理吗？' },
       { name: '老王', hue: 250, t: '昨天', text: '感谢分享，已 Star。期待加上多语言支持～' }],
      [{ name: 'Leo', hue: 222, t: '2 小时前', text: '部署很顺，文档清晰，给作者点赞。' }],
    ];
    return (banks[i % banks.length] || []).map((c) => ({ id: rid('cm_'), ...c }));
  }

  /* ---------- 播种 ---------- */
  function buildSeed() {
    const K = window.KSITE || {};
    const posts = (K.posts?.feed || []).map((p, i) => ({
      id: 'p_seed_' + i,
      author: p.author, handle: p.handle, hue: p.hue,
      kind: p.kind, title: p.title, body: p.body, tags: (p.tags || []).slice(),
      time: p.time, ts: now() - (i + 1) * 3.6e6,
      likes: p.likes, likedBy: [],
      comments: seedPostComments(i),
      seed: true,
    }));
    const eventsC = (K.community?.events || []).map((e, i) => ({ id: 'c' + i, scope: 'c', ...e, regs: [], seed: true }));
    const eventsE = (K.enterprise?.events || []).map((e, i) => ({ id: 'e' + i, scope: 'e', ...e, regs: [], seed: true }));
    const works = (K.demo?.items || []).map((it, i) => ({ id: 'w' + i, ...it, likedBy: [], comments: seedWorkComments(i), seed: true }));
    return { v: 1, users: [], session: null, posts, eventsC, eventsE, works, follows: {} };
  }

  /* ---------- 持久化 ---------- */
  function load() {
    try {
      const raw = JSON.parse(localStorage.getItem(DBKEY) || 'null');
      if (raw && raw.v === 1) return raw;
    } catch (e) {}
    return buildSeed();
  }
  function save() {
    try { localStorage.setItem(DBKEY, JSON.stringify(db)); } catch (e) {}
  }
  function ensure() { if (!db) db = load(); return db; }
  function commit() { save(); subs.forEach((fn) => { try { fn(); } catch (e) {} }); }

  /* ---------- 会话 / 账号 ---------- */
  function currentUser() {
    ensure();
    if (!db.session) return null;
    return db.users.find((u) => u.id === db.session) || null;
  }
  function actor() {
    const u = currentUser();
    if (u) return { name: u.name, handle: u.handle, hue: u.hue };
    return { name: '访客', handle: '@guest', hue: 205 };
  }
  function register({ name, email, password }) {
    ensure();
    email = (email || '').trim().toLowerCase();
    name = (name || '').trim();
    if (!name || !email || !password) return { ok: false, error: '请填写完整信息' };
    if (db.users.some((u) => u.email === email)) return { ok: false, error: '该邮箱已注册，去登录吧' };
    const handle = '@' + (email.split('@')[0] || 'user').replace(/[^a-z0-9_]/g, '').slice(0, 16);
    const u = { id: rid('u_'), name, email, password, handle, hue: hueFor(name), joined: now() };
    db.users.push(u); db.session = u.id; commit();
    return { ok: true, user: u };
  }
  function login({ email, password }) {
    ensure();
    email = (email || '').trim().toLowerCase();
    const u = db.users.find((x) => x.email === email);
    if (!u) return { ok: false, error: '账号不存在，先注册一个吧' };
    if (u.password !== password) return { ok: false, error: '密码不正确' };
    db.session = u.id; commit();
    return { ok: true, user: u };
  }
  function logout() { ensure(); db.session = null; commit(); }

  /* ---------- 帖子 ---------- */
  function posts() { return ensure().posts; }
  function getPost(id) { return ensure().posts.find((p) => p.id === id) || null; }
  function postIndex(id) { return ensure().posts.findIndex((p) => p.id === id); }
  function addPost({ kind, title, body, tags }) {
    ensure();
    const a = actor();
    const tagArr = Array.isArray(tags) ? tags
      : String(tags || '').split(/[\s,，]+/).filter(Boolean).map((t) => t[0] === '#' ? t : '#' + t);
    const p = {
      id: rid('p_'), author: a.name, handle: a.handle, hue: a.hue,
      kind: kind || '讨论', title: (title || '').trim(), body: (body || '').trim(),
      tags: tagArr, time: '刚刚', ts: now(), likes: 0, likedBy: [], comments: [], mine: true,
    };
    db.posts.unshift(p); commit();
    return p;
  }
  function isPostLiked(id) {
    const u = currentUser(); const p = getPost(id);
    if (!p) return false;
    return p.likedBy.includes(u ? u.id : 'guest');
  }
  function toggleLikePost(id) {
    const p = getPost(id); if (!p) return;
    const key = (currentUser() || {}).id || 'guest';
    const at = p.likedBy.indexOf(key);
    if (at >= 0) { p.likedBy.splice(at, 1); p.likes = Math.max(0, p.likes - 1); }
    else { p.likedBy.push(key); p.likes += 1; }
    commit();
  }
  function addComment(postId, text) {
    const p = getPost(postId); if (!p) return;
    const a = actor();
    p.comments.unshift({ id: rid('cm_'), name: a.name, hue: a.hue, t: '刚刚', text: text.trim() });
    commit();
  }

  /* ---------- 活动（c=社区 / e=企业） ---------- */
  function events(scope) { ensure(); return scope === 'e' ? db.eventsE : db.eventsC; }
  function getEvent(scope, idx) { const a = events(scope); return a[idx] || null; }
  function addEvent(scope, data) {
    const a = events(scope);
    const e = { id: scope + a.length, scope, regs: [], mine: true, ...data };
    a.push(e); commit();
    return { event: e, idx: a.length - 1 };
  }
  function isRegistered(scope, idx) {
    const e = getEvent(scope, idx); if (!e) return false;
    const key = (currentUser() || {}).id || 'guest';
    return e.regs.some((r) => r.key === key);
  }
  function registerEvent(scope, idx, info) {
    const e = getEvent(scope, idx); if (!e) return { ok: false };
    const key = (currentUser() || {}).id || 'guest';
    e.regs.push({ key, ...info, ts: now() });
    commit();
    return { ok: true };
  }

  /* ---------- 作品（技术广场） ---------- */
  function works() { return ensure().works; }
  function getWork(idx) { return ensure().works[idx] || null; }
  function addWork(data) {
    ensure();
    const a = actor();
    const w = {
      id: rid('w_'), author: (a.handle || '@me').replace(/^@/, ''), org: a.name,
      likes: 0, runs: '0', updated: '刚刚', hue: hueFor(data.name || a.name),
      likedBy: [], comments: [], mine: true, trend: false, ...data,
    };
    db.works.unshift(w); commit();
    return w;
  }
  function isWorkLiked(idx) {
    const w = getWork(idx); if (!w) return false;
    const key = (currentUser() || {}).id || 'guest';
    return w.likedBy.includes(key);
  }
  function toggleLikeWork(idx) {
    const w = getWork(idx); if (!w) return;
    const key = (currentUser() || {}).id || 'guest';
    const at = w.likedBy.indexOf(key);
    if (at >= 0) w.likedBy.splice(at, 1); else w.likedBy.push(key);
    commit();
  }
  function addWorkComment(idx, text) {
    const w = getWork(idx); if (!w) return;
    const a = actor();
    w.comments.unshift({ id: rid('cm_'), name: a.name, hue: a.hue, t: '刚刚', text: text.trim() });
    commit();
  }

  /* ---------- 关注 ---------- */
  function isFollowing(handle) { return !!ensure().follows[handle]; }
  function toggleFollow(handle) { ensure(); db.follows[handle] = !db.follows[handle]; commit(); }

  /* ---------- 调试：重置 ---------- */
  function reset() { db = buildSeed(); commit(); }

  window.KadaStore = {
    subscribe(fn) { subs.add(fn); return () => subs.delete(fn); },
    getDB: ensure,
    currentUser, actor, register, login, logout,
    posts, getPost, postIndex, addPost, isPostLiked, toggleLikePost, addComment,
    events, getEvent, addEvent, isRegistered, registerEvent,
    works, getWork, addWork, isWorkLiked, toggleLikeWork, addWorkComment,
    isFollowing, toggleFollow, reset,
  };

  window.useKadaDB = function useKadaDB() {
    const [, force] = React.useReducer((n) => n + 1, 0);
    React.useEffect(() => window.KadaStore.subscribe(force), []);
    return window.KadaStore;
  };
})();
