/* PrimaDelta — global store, persistence, router.
   Exposes: window.useStore, window.StoreProvider, window.fmt */
const { createContext, useContext, useState, useEffect, useCallback, useRef } = React;

const LS_KEY = "primadelta_poc_v1";
const PDStore = createContext(null);

/* ---- formatting helpers ---- */
const fmt = {
  money(n) {
    if (n == null) return "—";
    if (n >= 1e6) return "£" + (n / 1e6).toFixed(1) + "M";
    if (n >= 1e3) return "£" + (n / 1e3).toFixed(0) + "K";
    return "£" + n.toLocaleString();
  },
  date(s) {
    if (!s) return "—";
    const d = new Date(s);
    if (isNaN(d)) return s;
    return d.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" });
  },
  rel(s) {
    if (!s) return "—";
    const d = new Date(s.replace(" ", "T"));
    if (isNaN(d)) return s;
    const diff = (Date.now() - d.getTime()) / 86400000;
    if (diff < 1) return "Today";
    if (diff < 2) return "Yesterday";
    if (diff < 7) return Math.floor(diff) + " days ago";
    return fmt.date(s);
  }
};
window.fmt = fmt;

function loadState() {
  try {
    const raw = localStorage.getItem(LS_KEY);
    if (raw) return JSON.parse(raw);
  } catch (e) {}
  const seed = window.PD_SEED;
  return {
    assets: seed.assets.slice(),
    maintenance: seed.maintenance.slice(),
    documents: seed.documents.slice(),
    inbox: seed.inbox.slice()
  };
}

function StoreProvider({ children }) {
  // routing
  const [route, setRoute] = useState({ view: "home", params: {} });
  const [authed, setAuthed] = useState(() => {
    try { return sessionStorage.getItem("pd_auth") === "1"; } catch (e) { return false; }
  });

  // persisted data
  const [data, setData] = useState(loadState);
  const [toasts, setToasts] = useState([]);
  const idc = useRef(1000);

  useEffect(() => {
    try { localStorage.setItem(LS_KEY, JSON.stringify(data)); } catch (e) {}
  }, [data]);

  const nav = useCallback((view, params = {}) => {
    setRoute({ view, params });
    window.scrollTo({ top: 0, behavior: "auto" });
  }, []);

  // Hidden direct-URL entrance for admin (append #admin or #login to the URL).
  // Not linked anywhere on the public site — share this separately.
  useEffect(() => {
    const applyHash = () => {
      const h = (window.location.hash || "").replace(/^#/, "").toLowerCase();
      if (h === "admin" || h === "login") setRoute({ view: "login", params: {} });
    };
    applyHash();
    window.addEventListener("hashchange", applyHash);
    return () => window.removeEventListener("hashchange", applyHash);
  }, []);

  const toast = useCallback((ttl, sub, icon) => {
    const id = ++idc.current;
    setToasts((t) => [...t, { id, ttl, sub, icon }]);
    setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), 4200);
  }, []);

  const login = useCallback(() => {
    setAuthed(true);
    try { sessionStorage.setItem("pd_auth", "1"); } catch (e) {}
  }, []);
  const logout = useCallback(() => {
    setAuthed(false);
    try { sessionStorage.removeItem("pd_auth"); } catch (e) {}
  }, []);

  // ---- mutations ----
  const seqRef = useRef({ ast: 1248, mr: 2062 });

  const addAsset = useCallback((a) => {
    const id = "AST-" + (++seqRef.current.ast);
    setData((d) => ({ ...d, assets: [{ ...a, id }, ...d.assets] }));
    return id;
  }, []);

  const addMaintenance = useCallback((m) => {
    const id = "MR-" + (++seqRef.current.mr);
    const status = m.vendor ? "Assigned" : "Open";
    setData((d) => ({ ...d, maintenance: [{ ...m, id, status, reporter: "Admin" }, ...d.maintenance] }));
    return id;
  }, []);

  const updateMaintenance = useCallback((id, patch) => {
    setData((d) => ({
      ...d,
      maintenance: d.maintenance.map((m) => (m.id === id ? { ...m, ...patch } : m))
    }));
  }, []);

  const addDocument = useCallback((doc) => {
    const id = "d" + (++idc.current);
    setData((d) => ({ ...d, documents: [{ ...doc, id, by: "A. Reyes", restricted: true }, ...d.documents] }));
    return id;
  }, []);

  const removeDocument = useCallback((id) => {
    setData((d) => ({ ...d, documents: d.documents.filter((x) => x.id !== id) }));
  }, []);

  const addInbox = useCallback((c) => {
    const id = "c" + (++idc.current);
    setData((d) => ({ ...d, inbox: [{ ...c, id, read: false, at: nowStamp() }, ...d.inbox] }));
    return id;
  }, []);

  const markInboxRead = useCallback((id) => {
    setData((d) => ({ ...d, inbox: d.inbox.map((c) => (c.id === id ? { ...c, read: true } : c)) }));
  }, []);

  const resetData = useCallback(() => {
    try { localStorage.removeItem(LS_KEY); } catch (e) {}
    const seed = window.PD_SEED;
    setData({
      assets: seed.assets.slice(), maintenance: seed.maintenance.slice(),
      documents: seed.documents.slice(), inbox: seed.inbox.slice()
    });
  }, []);

  const value = {
    route, nav, authed, login, logout,
    data, toasts, toast,
    estates: window.PD_SEED.estates, vendors: window.PD_SEED.vendors,
    addAsset, addMaintenance, updateMaintenance,
    addDocument, removeDocument, addInbox, markInboxRead, resetData
  };

  return React.createElement(PDStore.Provider, { value }, children);
}

function nowStamp() {
  const d = new Date();
  const p = (n) => String(n).padStart(2, "0");
  return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;
}

function useStore() {
  const v = useContext(PDStore);
  if (!v) throw new Error("useStore outside provider");
  return v;
}

window.useStore = useStore;
window.StoreProvider = StoreProvider;
