/* Общий стор: гидрация из RenoDB + авто-персист + производные.
   A1/A2: dataRef (актуальное состояние), функциональные set, replaceEntity. */
window.RD = window.RD || { core: {}, modules: {} };
(function (C) {
  var Ctx = React.createContext(null);
  C.StoreContext = Ctx;
  C.useStore = function () { return React.useContext(Ctx); };

  C.StoreProvider = function (props) {
    var init = { loading: true, role: 'Администратор', user: null, view: 'estimate', theme: 'light', data: {}, toast: null };
    var ref = React.useReducer(function (s, a) { return Object.assign({}, s, a); }, init);
    var state = ref[0], set = ref[1];
    var dataRef = React.useRef(state.data);           // A2: всегда актуальные данные
    dataRef.current = state.data;
    var saveTimer = React.useRef(null);
    var hist = React.useRef([]); var redo = React.useRef([]); var toastTimer = React.useRef(null);

    function showToast(text, kind) { set({ toast: { text: text, kind: kind || 'ok' } }); clearTimeout(toastTimer.current); toastTimer.current = setTimeout(function () { set({ toast: null }); }, 3400); }
    function pushHist() { hist.current.push(JSON.stringify(dataRef.current)); if (hist.current.length > 40) hist.current.shift(); redo.current = []; }
    function undo() { if (!hist.current.length) { showToast('История пуста', 'warn'); return; } redo.current.push(JSON.stringify(dataRef.current)); var d = JSON.parse(hist.current.pop()); dataRef.current = d; set({ data: d }); showToast('Отменено', 'ok'); }
    function redoFn() { if (!redo.current.length) { showToast('Нечего вернуть', 'warn'); return; } hist.current.push(JSON.stringify(dataRef.current)); var d = JSON.parse(redo.current.pop()); dataRef.current = d; set({ data: d }); showToast('Возвращено', 'ok'); }

    React.useEffect(function () {
      RenoDB.getProject().then(function (d) {
        // Normalize works deps
        if (Array.isArray(d.works)) d.works = d.works.map(function (w) { return Object.assign({}, w, { deps: C.normalizeDeps(w.deps) }); });
        
        // FIX #1: Bind spec_items to sections.rows (currently sections.rows are empty)
        if (Array.isArray(d.sections) && Array.isArray(d.spec_items)) {
          d.sections = d.sections.map(function (s) {
            var sectionItems = d.spec_items.filter(function (item) {
              // Group spec_items by category → section mapping
              var catMap = {
                'Оборудование': 's3',
                'Материалы': 's3',
                'Работы': 's3'
              };
              return catMap[item.category] === s.id;
            }).map(function (item, idx) {
              // Transform spec_item to estimate row format
              return {
                id: item.id,
                kind: 'material',
                name: item.name + (item.brand ? ' (' + item.brand + ')' : ''),
                unit: item.unit || 'шт',
                qty: item.qty || 0,
                price: 0, // spec_items don't have price, will be 0
                cost: 0,
                status: item.status || 'planned',
                pct: 0,
                rejected: false,
                note: item.note || ''
              };
            });
            return Object.assign({}, s, { rows: sectionItems.length > 0 ? sectionItems : s.rows || [] });
          });
        }
        
        // FIX #2: Create aliases for legacy field names used by Overview.jsx
        d.tasks = d.works || [];
        d.smeta = [];
        if (Array.isArray(d.sections)) {
          d.sections.forEach(function (s) {
            (s.rows || []).forEach(function (r) { d.smeta.push(r); });
          });
        }
        d.supplies = d.deliveries || [];
        
        dataRef.current = d;
        set({ loading: false, data: d });
      });
    }, []);

    // A1: единый метод замены сущности целиком (для каскада/групп)
    function replaceEntity(entity, list, persistIds) {
      pushHist();
      var nd = Object.assign({}, dataRef.current); nd[entity] = list;
      dataRef.current = nd; set({ data: nd });
      var ids = persistIds || list.map(function (x) { return x.id; });
      clearTimeout(saveTimer.current);
      saveTimer.current = setTimeout(function () { ids.forEach(function (id) { var row = list.find(function (x) { return x.id === id; }); if (row) RenoDB.update(entity, id, row); }); }, 800);
    }
    // правка одной сущности
    function update(entity, id, patch) {
      pushHist();
      var d = dataRef.current; var list = d[entity];
      if (Array.isArray(list)) { var n = list.map(function (x) { return x.id === id ? Object.assign({}, x, patch) : x; }); var nd = Object.assign({}, d); nd[entity] = n; dataRef.current = nd; set({ data: nd }); }
      clearTimeout(saveTimer.current);
      saveTimer.current = setTimeout(function () { RenoDB.update(entity, id, patch); }, 800);
    }
    function createEntity(entity, obj) {
      pushHist();
      var d = dataRef.current; var list = (d[entity] || []).slice(); list.push(obj); var nd = Object.assign({}, d); nd[entity] = list; dataRef.current = nd; set({ data: nd });
      RenoDB.create(entity, obj);
    }
    function setView(v) { set({ view: v }); }
    function setTheme(t) { set({ theme: t }); document.body.setAttribute('data-theme', t); try { localStorage.setItem('rd_theme', t); } catch (e) {} }
    function setRole(r) { set({ role: r }); try { localStorage.setItem('rd_role', r); } catch (e) {} }
    function login(u) { set({ user: u.name, role: u.role }); try { localStorage.setItem('rd_role', u.role); localStorage.setItem('rd_user', u.name); } catch (e) {} }
    function logout() { set({ user: null }); try { localStorage.removeItem('rd_user'); } catch (e) {} }

    var cfg = state.data.config || {};
    var api = {
      state: state, raw: state.data, config: cfg, loading: state.loading,
      perms: C.perms(state.role, cfg),
      vatRate: C.vatRate(cfg),
      update: update, create: createEntity, replaceEntity: replaceEntity,
      setView: setView, setTheme: setTheme, setRole: setRole, login: login, logout: logout,
      toast: state.toast, showToast: showToast, undo: undo, redo: redoFn, pushHist: pushHist
    };
    return React.createElement(Ctx.Provider, { value: api }, props.children);
  };
})(window.RD.core);
