/* store.jsx — model + reducer. ADAPTADO PARA API.
 *
 * Mudanças vs. versão localStorage:
 *   - Nada de SEED_TASKS local: o estado começa vazio e é populado pela API.
 *   - reducer continua sendo a fonte de UI state, mas todas as mutações
 *     reais (CRUD) passam por window.Api e voltam via REPLACE_TASKS /
 *     UPDATE_TASK_FROM_SERVER.
 *   - localStorage só guarda preferências leves (mute, tweaks).
 */

const uid = () => Math.random().toString(36).slice(2, 9);
const todayStr = () => {
  const d = new Date();
  return `${String(d.getDate()).padStart(2,"0")}/${String(d.getMonth()+1).padStart(2,"0")}/${d.getFullYear()}`;
};
const dayKey = (d = new Date()) => `${d.getFullYear()}-${d.getMonth()+1}-${d.getDate()}`;

const CATEGORIES = {
  bug:      { label: "Bug",      color: "var(--c-bug)",      bg: "var(--c-bug-bg)",      icon: "Bug" },
  projeto:  { label: "Projeto",  color: "var(--accent)",     bg: "rgba(var(--accent-rgb),0.14)", icon: "Folder" },
  feature:  { label: "Feature",  color: "var(--c-feature)",  bg: "var(--c-feature-bg)",  icon: "Bolt" },
  melhoria: { label: "Melhoria", color: "var(--c-melhoria)", bg: "var(--c-melhoria-bg)", icon: "TrendUp" },
};
const PRIORITIES = {
  baixa: { label: "Baixa", color: "var(--c-baixa)", bg: "var(--c-baixa-bg)" },
  alta:  { label: "Alta",  color: "var(--c-alta)",  bg: "var(--c-alta-bg)" },
};
const COLUMNS = [
  { id: "todo",  title: "A Fazer",   dot: "var(--txt-3)" },
  { id: "doing", title: "Fazendo",   dot: "var(--accent)" },
  { id: "done",  title: "Concluído", dot: "var(--c-melhoria)" },
];
const REINFORCE = [
  { e: "🔥", t: "Mandou bem!" }, { e: "⚡", t: "Tá voando hoje!" },
  { e: "💪", t: "Mais uma fora!" }, { e: "🚀", t: "Imparável!" },
  { e: "🎯", t: "Na mosca!" }, { e: "✨", t: "Caprichou!" },
  { e: "🏆", t: "Lendário!" }, { e: "😎", t: "Suave demais!" },
];

const xpForTask = (t) => {
  let base = { baixa: 14, alta: 30 }[t.priority] ?? 18;
  if (t.category === "bug") base += 6;
  return base;
};
const levelNeed = (lvl) => 90 + lvl * 50;
function levelInfo(xp) {
  let lvl = 1, rem = xp;
  while (rem >= levelNeed(lvl)) { rem -= levelNeed(lvl); lvl++; }
  const need = levelNeed(lvl);
  return { level: lvl, into: rem, need, pct: Math.round((rem / need) * 100) };
}
const taskProgress = (t) => {
  if (t.checklist && t.checklist.length)
    return Math.round((t.checklist.filter(c => c.done).length / t.checklist.length) * 100);
  return t.progress ?? 0;
};

/* ---------- shape normal do task vindo do server → shape de UI ---------- */
function normalizeTask(t) {
  return {
    id: t.id,
    title: t.title,
    desc: t.description || "",
    status: t.status,
    category: t.category,
    priority: t.priority,
    progress: Number(t.progress) || 0,
    checklist: (t.checklist || []).map(c => ({ id: c.id, text: c.text, done: !!c.done })),
    images: t.images || [],
    videos: t.videos || [],
    attachments: (t.images || []).length,
    thumb: t.thumb || null,
    createdBy: t.creator_name || "—",
    createdAt: t.created_at ? t.created_at.slice(0,10).split("-").reverse().join("/") : todayStr(),
    assignedTo: t.assigned_to || null,
    assigneeName: t.assignee_name || null,
  };
}

function defaultState() {
  return {
    loading: true,
    loggedIn: false,
    user: null,
    tasks: [],
    game: { xp: 0, streak: 1, todayCount: 0, totalDone: 0, weekCount: 0 },
  };
}

function reducer(state, action) {
  switch (action.type) {
    case "BOOT":
      return { ...state, loading: false, loggedIn: !!action.user, user: action.user || null };

    case "SET_USER":
      return { ...state, user: action.user };

    case "SET_TASKS":
      return { ...state, tasks: (action.tasks || []).map(normalizeTask) };

    case "UPSERT_TASK": {
      const t = normalizeTask(action.task);
      const idx = state.tasks.findIndex(x => x.id === t.id);
      const tasks = idx >= 0
        ? state.tasks.map((x,i) => i===idx ? t : x)
        : [t, ...state.tasks];
      return { ...state, tasks };
    }

    case "REMOVE_TASK":
      return { ...state, tasks: state.tasks.filter(t => t.id !== action.id) };

    case "SET_GAME":
      return { ...state, game: { ...state.game, ...action.game } };

    case "LOGIN":
      return { ...state, loggedIn: true, user: action.user };

    case "LOGOUT":
      return { ...defaultState(), loading: false };

    default:
      return state;
  }
}

// XP local (efeito visual imediato; backend ainda não persiste XP — pode ser feito depois)
function applyLocalXp(state, delta) {
  return { ...state, game: { ...state.game, xp: Math.max(0, (state.game.xp || 0) + delta) } };
}

window.Store = {
  uid, todayStr, dayKey,
  CATEGORIES, PRIORITIES, COLUMNS, REINFORCE,
  xpForTask, levelInfo, levelNeed, taskProgress,
  reducer, defaultState, normalizeTask, applyLocalXp,
};
