// record-store.jsx — store + hash router + localStorage for PulseChart Record.
// Holds: mode (standalone/integrated), doctor identity, active sessions,
// signature captures, generated documents.

const RSTORE_KEY = 'pcrecord.v1';

function rInitialState() {
  return {
    mode: 'integrated',          // 'integrated' | 'standalone'
    doctorName: 'Dr. Anand Krishnan',
    doctorReg: 'KMC-12847',
    // Sessions keyed by id; each is a counseling or discharge session
    sessions: {},
    // Cross-link registry: patientAdmissionId -> { counselingId, dischargeId }
    links: {},
    toast: null,
  };
}

function rLoad() {
  try {
    const raw = localStorage.getItem(RSTORE_KEY);
    if (!raw) return null;
    const p = JSON.parse(raw);
    if (p && p.version === 1) return p.state;
  } catch (e) {}
  return null;
}
function rPersist(state) {
  try {
    const { toast, ...rest } = state;
    localStorage.setItem(RSTORE_KEY, JSON.stringify({ version: 1, state: rest }));
  } catch (e) {}
}

const RStoreCtx = React.createContext(null);

function RStoreProvider({ children }) {
  const [state, setRaw] = React.useState(() => {
    const persisted = rLoad();
    return persisted ? { ...rInitialState(), ...persisted, toast: null } : rInitialState();
  });

  const set = React.useCallback((updater) => {
    setRaw(prev => {
      const next = typeof updater === 'function' ? updater(prev) : updater;
      rPersist(next);
      return next;
    });
  }, []);

  const api = React.useMemo(() => ({
    state,
    setMode(mode) { set(s => ({ ...s, mode })); },

    // ── Sessions ──────────────────────────────────────────
    getSession(id) { return state.sessions[id]; },

    createSession(module, seed = {}) {
      const id = module.slice(0,3).toUpperCase() + '-' + Math.random().toString(36).slice(2,7).toUpperCase();
      const session = {
        id, module,                         // 'counseling' | 'discharge'
        doctorName: state.doctorName, doctorReg: state.doctorReg,
        createdAt: Date.now(),
        signatures: [],
        ...seed,
      };
      set(s => ({ ...s, sessions: { ...s.sessions, [id]: session } }));
      return id;
    },

    updateSession(id, patch) {
      set(s => ({
        ...s,
        sessions: {
          ...s.sessions,
          [id]: { ...s.sessions[id], ...(typeof patch === 'function' ? patch(s.sessions[id]) : patch) },
        },
      }));
    },

    addSignature(id, sig) {
      set(s => ({
        ...s,
        sessions: {
          ...s.sessions,
          [id]: { ...s.sessions[id], signatures: [...(s.sessions[id].signatures || []), sig] },
        },
      }));
    },

    // ── Cross-module link ─────────────────────────────────
    linkForDischarge(counselingSessionId) {
      // Register a patientAdmissionId linking a counseling session for later discharge
      const pid = 'PADM-' + Math.random().toString(36).slice(2,7).toUpperCase();
      set(s => ({
        ...s,
        sessions: { ...s.sessions, [counselingSessionId]: { ...s.sessions[counselingSessionId], patientAdmissionId: pid } },
        links: { ...s.links, [pid]: { counselingId: counselingSessionId } },
      }));
      return pid;
    },

    recentCounselingSessions() {
      return Object.values(state.sessions)
        .filter(s => s.module === 'counseling' && s.patientAdmissionId)
        .sort((a,b) => b.createdAt - a.createdAt);
    },

    // ── UI ────────────────────────────────────────────────
    toast(t) {
      const id = Math.random();
      setRaw(s => ({ ...s, toast: { id, ...t } }));
      setTimeout(() => setRaw(s => (s.toast && s.toast.id === id ? { ...s, toast: null } : s)), 3500);
    },
    clearToast() { setRaw(s => ({ ...s, toast: null })); },

    reset() { localStorage.removeItem(RSTORE_KEY); window.__prTourDischargeId = null; window.__prTourCounselingId = null; setRaw(rInitialState()); window.location.hash = '#/'; },
  }), [state, set]);

  React.useEffect(() => {
    window.__prStore = api;

    // Actions the guided demo triggers directly, so each beat lands on the real payoff.
    // Discharge targets the Total Knee Replacement journey (Mr. Suresh Kumar Yadav, J-TKR-A);
    // counselling targets the hip-fracture profile (Mr. Arvind Pillai, C-HIP-A).
    function orthoJourney() {
      const J = (window.PRD && window.PRD.journeys) || [];
      return J.find(x => x.id === 'J-TKR-A')
        || J.find(x => /suresh/i.test((x.profile && x.profile.patientIdentifier) || ''))
        || J.find(x => x.specialty === 'ORTHO') || J[0];
    }
    function ensureDischargeSession() {
      const j = orthoJourney(); if (!j) return null;
      if (window.__prTourDischargeId && api.state.sessions[window.__prTourDischargeId]) return window.__prTourDischargeId;
      const existing = Object.values(api.state.sessions).find(s => s.module === 'discharge' && s.journeyId === j.id);
      if (existing) { window.__prTourDischargeId = existing.id; return existing.id; }
      const id = api.createSession('discharge', {
        journeyId: j.id, specialty: j.specialty, procedure: j.procedure,
        profile: { ...j.profile },
        progressNotes: (j.progressNotes || []).map(n => ({ ...n })),
        labResults: j.labResults, medications: j.medications,
        step: 1, summary: null, edits: {}, omitLabs: false, linkedCounseling: null,
      });
      window.__prTourDischargeId = id;
      return id;
    }
    // Build the synthesised summary the same way DStepSynthesis.runSynthesis does.
    function buildSummary(omit) {
      const j = orthoJourney(); if (!j || !window.PRD) return null;
      const summary = JSON.parse(JSON.stringify(window.PRD.summaryFor(j.id)));
      if (omit) summary.investigations = '[INSUFFICIENT DATA: no lab results were entered for this admission. Enter investigations to complete this section — values were not invented.]';
      return summary;
    }
    function ensureCounselingSession() {
      const P = (window.PRC && window.PRC.profiles) || [];
      const p = P.find(x => x.id === 'C-HIP-A')
        || P.find(x => x.specialty === 'ORTHO' && /hip/i.test(x.procedure || ''))
        || P.find(x => x.specialty === 'ORTHO') || P[0];
      if (!p) return null;
      if (window.__prTourCounselingId && api.state.sessions[window.__prTourCounselingId]) return window.__prTourCounselingId;
      const existing = Object.values(api.state.sessions).find(s => s.module === 'counseling' && s.profileId === p.id);
      if (existing) { window.__prTourCounselingId = existing.id; return existing.id; }
      const id = api.createSession('counseling', {
        profileId: p.id, specialty: p.specialty, procedure: p.procedure, counselingMode: 'ROUTINE',
        profile: { ...p.profile }, narrative: p.narrative, note: null, step: 1, confirmed: false,
      });
      window.__prTourCounselingId = id;
      return id;
    }

    // The pre-validated 12-field counselling note for the hip-fracture profile.
    function counselNote() {
      const P = (window.PRC && window.PRC.profiles) || [];
      const p = P.find(x => x.id === 'C-HIP-A') || P.find(x => x.specialty === 'ORTHO') || P[0];
      return p && p.note ? { ...p.note } : null;
    }

    window.PC_DEMO_ACTIONS = {
      toggleMode() { api.setMode(api.state.mode === 'integrated' ? 'standalone' : 'integrated'); },
      // ── Discharge flow ──
      dischargePick() { const id = ensureDischargeSession(); if (id) rNav('#/discharge/' + id); },
      dischargeProgress() { const id = ensureDischargeSession(); if (id) { api.updateSession(id, { step: 2 }); rNav('#/discharge/' + id); } },
      // Auto-run synthesis so the buyer lands on the finished 10-section summary, not the "ready" screen.
      dischargeSynthesiseRun() { const id = ensureDischargeSession(); if (id) { api.updateSession(id, { omitLabs: false, summary: buildSummary(false), edits: {}, step: 3 }); rNav('#/discharge/' + id); } },
      // Guardrail: omit labs, synthesise, land on the [INSUFFICIENT DATA] flag.
      dischargeGuardrail() { const id = ensureDischargeSession(); if (id) { api.updateSession(id, { omitLabs: true, summary: buildSummary(true), edits: {}, step: 3 }); rNav('#/discharge/' + id); } },
      // Generate the bilingual PDF preview.
      dischargePdf() { const id = ensureDischargeSession(); if (id) { api.updateSession(id, s => ({ ...s, summary: s.summary || buildSummary(false), step: 4, pdfGenerated: true, completed: true })); rNav('#/discharge/' + id); } },
      // ── Counselling flow ──
      counselingPick() { const id = ensureCounselingSession(); if (id) rNav('#/counseling/' + id); },
      counselingRecord() { const id = ensureCounselingSession(); if (id) { api.updateSession(id, { step: 2 }); rNav('#/counseling/' + id); } },
      counselingReview() { const id = ensureCounselingSession(); if (id) { api.updateSession(id, { note: counselNote(), step: 3 }); rNav('#/counseling/' + id); } },
      counselingConsent() { const id = ensureCounselingSession(); if (id) { api.updateSession(id, s => ({ ...s, note: s.note || counselNote(), step: 4 })); rNav('#/counseling/' + id); } },
    };
  }, [api]);

  return <RStoreCtx.Provider value={api}>{children}</RStoreCtx.Provider>;
}

function useRStore() {
  const ctx = React.useContext(RStoreCtx);
  if (!ctx) throw new Error('useRStore outside provider');
  return ctx;
}

// ── Router ────────────────────────────────────────────────
// #/                              home (module selection)
// #/discharge                     discharge: pick patient / new
// #/discharge/:sessionId          discharge workspace
// #/counseling                    counseling: pick patient / mode
// #/counseling/:sessionId         counseling workspace
function rParse(hash) {
  const path = (hash || '#/').replace(/^#/, '');
  const parts = path.split('/').filter(Boolean);
  if (parts.length === 0) return { name:'home' };
  if (parts[0] === 'discharge') return { name:'discharge', sessionId: parts[1] || null };
  if (parts[0] === 'counseling') return { name:'counseling', sessionId: parts[1] || null };
  return { name:'home' };
}
function useRRoute() {
  const [hash, setHash] = React.useState(typeof window !== 'undefined' ? window.location.hash : '#/');
  React.useEffect(() => {
    const on = () => setHash(window.location.hash || '#/');
    window.addEventListener('hashchange', on);
    return () => window.removeEventListener('hashchange', on);
  }, []);
  return rParse(hash);
}
function rNav(path) { window.location.hash = path; }

Object.assign(window, { RStoreProvider, useRStore, useRRoute, rNav });
