// Store: state, persistence, helpers

const TODAY = new Date();

const STATES = {
  todo: { label: "À faire", color: "var(--todo)", bg: "var(--todo-bg)", icon: "circle" },
  progress: { label: "En cours", color: "var(--progress)", bg: "var(--progress-bg)", icon: "halfcircle" },
  done: { label: "Fait", color: "var(--done)", bg: "var(--done-bg)", icon: "check" },
  postponed: { label: "Reportée", color: "var(--postpone)", bg: "var(--postpone-bg)", icon: "arrow" },
  cancelled: { label: "Annulée", color: "var(--cancel)", bg: "var(--cancel-bg)", icon: "cross" },
};

const PRIORITIES = {
  low:  { label: "Faible",  color: "var(--prio-low)"  },
  mid:  { label: "Moyenne", color: "var(--prio-mid)"  },
  high: { label: "Élevée",  color: "var(--prio-high)" },
};

const KINDS = {
  task:        { label: "Tâche",        color: "var(--terracotta)", bg: "var(--terracotta-tint)" },
  birthday:    { label: "Anniversaire", color: "var(--birthday)",   bg: "var(--birthday-bg)"     },
  appointment: { label: "Rendez-vous",  color: "var(--event)",      bg: "var(--event-bg)"        },
  family:      { label: "Famille",      color: "#8E6A4A",           bg: "#F0E4D4"                },
  event:       { label: "Événement",    color: "#5E7A8C",           bg: "#DCE6EC"                },
};

// --- date helpers ---
const pad = (n) => String(n).padStart(2, "0");
const ymd = (d) => `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())}`;
const fromYmd = (s) => { const [y,m,d] = s.split("-").map(Number); return new Date(y, m-1, d); };
const sameDay = (a, b) => a.getFullYear()===b.getFullYear() && a.getMonth()===b.getMonth() && a.getDate()===b.getDate();
const addDays = (d, n) => { const x = new Date(d); x.setDate(x.getDate()+n); return x; };
const startOfMonth = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
const endOfMonth = (d) => new Date(d.getFullYear(), d.getMonth()+1, 0);
const isBefore = (a, b) => ymd(a) < ymd(b);
const isAfter  = (a, b) => ymd(a) > ymd(b);

const MONTHS = ["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"];
const DAYS_LONG = ["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"];
const DAYS_SHORT = ["dim.","lun.","mar.","mer.","jeu.","ven.","sam."];
const DAYS_ONE = ["D","L","M","M","J","V","S"];

const fmtFull = (d) => `${DAYS_LONG[d.getDay()]} ${d.getDate()} ${MONTHS[d.getMonth()]} ${d.getFullYear()}`;
const fmtShort = (d) => `${d.getDate()} ${MONTHS[d.getMonth()].slice(0,3)}`;
const fmtRel = (d) => {
  const diff = Math.round((fromYmd(ymd(d)) - fromYmd(ymd(TODAY))) / 86400000);
  if (diff === 0) return "Aujourd'hui";
  if (diff === 1) return "Demain";
  if (diff === -1) return "Hier";
  if (diff > 1 && diff < 7) return `Dans ${diff} j`;
  if (diff < 0 && diff > -7) return `Il y a ${-diff} j`;
  return fmtShort(d);
};

// --- recurrence ---
// recurrence: { kind: 'none'|'daily'|'weekly'|'monthly'|'custom', days?: [...ymd], weekday?: 0..6 }
function occursOn(item, date) {
  const r = item.recurrence || { kind: "none" };
  const start = fromYmd(item.date);
  if (isBefore(date, start)) return false;

  if (r.kind === "none") return sameDay(date, start);
  if (r.kind === "daily") return true;
  if (r.kind === "weekly") return date.getDay() === start.getDay();
  if (r.kind === "monthly") return date.getDate() === start.getDate();
  if (r.kind === "yearly") return date.getDate() === start.getDate() && date.getMonth() === start.getMonth();
  if (r.kind === "custom") return (r.days || []).includes(ymd(date));
  return false;
}

// Returns the per-day status for an item on a given date (overrides take precedence)
function statusOn(item, date) {
  const k = ymd(date);
  if (item.overrides && item.overrides[k]) return item.overrides[k];
  // For non-recurring items, default to the item's status
  if ((item.recurrence?.kind || "none") === "none") return item.status || "todo";
  return "todo"; // recurring items reset to "todo" each day
}

// --- seed data (empty — no defaults) ---
const seed = () => [];

// --- store hook ---
function useStore() {
  const [items, setItems] = React.useState(() => {
    try {
      const raw = localStorage.getItem("maisonnee:items");
      if (raw) return JSON.parse(raw);
    } catch (e) {}
    return seed();
  });

  React.useEffect(() => {
    try { localStorage.setItem("maisonnee:items", JSON.stringify(items)); } catch (e) {}
  }, [items]);

  const upsert = (item) => {
    setItems(prev => {
      const i = prev.findIndex(x => x.id === item.id);
      if (i === -1) return [...prev, { overrides: {}, ...item }];
      const copy = [...prev]; copy[i] = { ...prev[i], ...item }; return copy;
    });
  };
  const remove = (id) => setItems(prev => prev.filter(x => x.id !== id));
  const setStatusOn = (id, dateStr, status) => {
    setItems(prev => prev.map(x => {
      if (x.id !== id) return x;
      // For non-recurring items, also update top-level status
      if ((x.recurrence?.kind || "none") === "none") {
        if (status === "not_today") {
          // reschedule to next day
          return { ...x, date: ymd(addDays(fromYmd(x.date), 1)) };
        }
        return { ...x, status };
      }
      // Recurring: store an override for that day
      if (status === "not_today") {
        // mark today cancelled-style and add a one-off task tomorrow? Easier: add a custom day.
        const next = ymd(addDays(fromYmd(dateStr), 1));
        const newOverrides = { ...(x.overrides || {}), [dateStr]: "cancelled" };
        // Add tomorrow as a one-shot occurrence via recurrence custom merge:
        // simplest: keep recurrence as-is; we represent "moved to tomorrow" with an override on tomorrow = "todo"
        // and a "ghost" via extraDays
        const extraDays = Array.from(new Set([...(x.extraDays||[]), next]));
        return { ...x, overrides: newOverrides, extraDays };
      }
      const newOverrides = { ...(x.overrides || {}), [dateStr]: status };
      return { ...x, overrides: newOverrides };
    }));
  };

  return { items, setItems, upsert, remove, setStatusOn };
}

// --- queries ---
function itemsOnDate(items, date) {
  const k = ymd(date);
  return items.filter(it => occursOn(it, date) || (it.extraDays || []).includes(k));
}

// Expose to window for cross-script access
Object.assign(window, {
  TODAY, STATES, PRIORITIES, KINDS,
  ymd, fromYmd, sameDay, addDays, startOfMonth, endOfMonth, isBefore, isAfter,
  MONTHS, DAYS_LONG, DAYS_SHORT, DAYS_ONE,
  fmtFull, fmtShort, fmtRel,
  occursOn, statusOn, useStore, itemsOnDate, seed,
});
