// portal-state.jsx — Employee self-service data + context. Self-contained
// (the logged-in employee is Marcus Hale, the same RWIC as the field tablet).

const { createContext, useContext, useState, useMemo, useCallback, useEffect, useRef } = React;

const P_money = (n) => (n < 0 ? '-$' : '$') + Math.abs(+n || 0).toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
const P_num = (n, d = 1) => (+n || 0).toLocaleString('en-US', { minimumFractionDigits: d, maximumFractionDigits: d });
const P_date = (iso) => iso ? new Date(iso.length === 10 ? iso + 'T00:00' : iso).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '—';
const P_uid = (() => { let n = 1; return (p = 'p') => `${p}_${n++}`; })();

// ── The logged-in employee ───────────────────────────────────
const ME = {
  id: 'e-2241', name: 'Marcus Hale', first: 'Marcus', badge: 'FLG-2241', avatar: 'MH',
  role: 'RWIC', email: 'mhale@railflagspro.com', phone: '(406) 555-0142',
  baseRate: 38.50, resident: 'MT', payrollFreq: 'Bi-weekly', rrbContributor: true,
  hireDate: '2019-04-12', ssnMasked: '•••-••-1347', ssnFull: '541-22-1347',
  address: { line1: '418 N Black Ave', line2: '', city: 'Bozeman', state: 'MT', zip: '59715' },
  directDeposit: { bank: 'First Interstate Bank', type: 'Checking', routing: '•••••1098', account: '•••••4471', split: 100 },
  emergency: { name: 'Karen Hale', relation: 'Spouse', phone: '(406) 555-0199' },
  ytd: { gross: 41250, tax: 11137, net: 30113 },
};

const EMPLOYER = { name: 'RailFlagsPro LLC', ein: '84-2207715', address: '1200 Rail Yard Rd, Bozeman MT 59715' };

// ── Pay periods (stubs) ──────────────────────────────────────
const PAY_PERIODS = [
  { id: 'pp-12', period: '2026-05-04 — 2026-05-17', payDate: '2026-05-22', reg: 76.0, ot: 11.2, gross: 3570.20, net: 2606.25, status: 'paid' },
  { id: 'pp-11', period: '2026-04-20 — 2026-05-03', payDate: '2026-05-08', reg: 80.0, ot: 8.4,  gross: 3565.40, net: 2602.74, status: 'paid' },
  { id: 'pp-10', period: '2026-04-06 — 2026-04-19', payDate: '2026-04-24', reg: 78.5, ot: 6.0,  gross: 3369.75, net: 2459.92, status: 'paid' },
  { id: 'pp-09', period: '2026-03-23 — 2026-04-05', payDate: '2026-04-10', reg: 80.0, ot: 12.5, gross: 3801.25, net: 2774.91, status: 'paid' },
  { id: 'pp-13', period: '2026-05-18 — 2026-05-31', payDate: '2026-06-05', reg: 49.5, ot: 1.75, gross: 2006.13, net: 1464.48, status: 'pending' },
];

// ── Timecard history (per day) ───────────────────────────────
const MY_TIMECARDS = [
  { date: '2026-05-22', job: 'JOB-24179', codes: ['F10', 'V10'], hrs: 8.75, status: 'pending-ops' },
  { date: '2026-05-21', job: 'JOB-24179', codes: ['F10'], hrs: 10.8, status: 'pending-acct' },
  { date: '2026-05-20', job: 'JOB-24179', codes: ['F10'], hrs: 9.2,  status: 'approved' },
  { date: '2026-05-19', job: 'JOB-24179', codes: ['F10'], hrs: 11.0, status: 'approved' },
  { date: '2026-05-18', job: 'JOB-24179', codes: ['F10'], hrs: 10.5, status: 'approved' },
  { date: '2026-05-17', job: 'JOB-24179', codes: ['F10'], hrs: 10.8, status: 'paid' },
  { date: '2026-05-16', job: 'JOB-24179', codes: ['F10'], hrs: 11.2, status: 'paid' },
];

// ── PTO ──────────────────────────────────────────────────────
const PTO_BALANCES = [
  { type: 'Vacation', code: 'L10', accrued: 96, used: 40, pending: 16 },
  { type: 'Sick',     code: 'L30', accrued: 48, used: 8,  pending: 0 },
  { type: 'PTO',      code: 'L60', accrued: 24, used: 0,  pending: 0 },
];
const PTO_REQUESTS = [
  { id: 'pto-1', type: 'Vacation', start: '2026-06-16', end: '2026-06-18', hours: 16, status: 'pending', note: 'Family trip' },
  { id: 'pto-2', type: 'Sick',     start: '2026-04-30', end: '2026-04-30', hours: 8,  status: 'approved', note: '' },
  { id: 'pto-3', type: 'Vacation', start: '2026-03-10', end: '2026-03-14', hours: 40, status: 'approved', note: 'Spring break' },
];

// ── Certifications / training ────────────────────────────────
const MY_CERTS = [
  { name: 'NS Roadway Worker Protection', issuer: 'Norfolk Southern', issued: '2024-09-14', expires: '2026-09-14', status: 'current' },
  { name: 'BNSF Contractor Orientation',  issuer: 'BNSF', issued: '2025-02-01', expires: '2026-02-01', status: 'expired' },
  { name: 'CSX FCI Certification',        issuer: 'CSX', issued: '2025-06-10', expires: '2027-06-10', status: 'current' },
  { name: 'CPR / First Aid',              issuer: 'American Red Cross', issued: '2024-11-20', expires: '2026-08-20', status: 'expiring' },
  { name: 'Roadway Worker FRA 49 CFR 214',issuer: 'RailFlagsPro', issued: '2025-01-15', expires: '2027-01-15', status: 'current' },
];

// ── Reimbursements (per-diem + mileage) ──────────────────────
const REIMBURSEMENTS = [
  { id: 'rb-1', date: '2026-05-21', type: 'Per diem', desc: 'Skykomish lodging + M&IE', amount: 168.00, status: 'approved' },
  { id: 'rb-2', date: '2026-05-20', type: 'Mileage', desc: '212 mi @ $0.67 (Bozeman→Skykomish)', amount: 142.04, status: 'approved' },
  { id: 'rb-3', date: '2026-05-22', type: 'Per diem', desc: 'M&IE day rate', amount: 79.00, status: 'pending' },
  { id: 'rb-4', date: '2026-05-19', type: 'Materials', desc: 'Replacement hi-vis vest', amount: 38.50, status: 'pending' },
];

// ── Documents inbox (company → me, sign/ack) ─────────────────
const DOC_INBOX = [
  { id: 'd-1', title: '2026 Safety Policy Acknowledgement', from: 'Safety Dept', sent: '2026-05-15', action: 'sign', status: 'action-required' },
  { id: 'd-2', title: 'Updated Direct Deposit Authorization', from: 'Payroll', sent: '2026-05-10', action: 'sign', status: 'action-required' },
  { id: 'd-3', title: 'Q1 Performance Summary', from: 'C. Whitehorse', sent: '2026-04-28', action: 'ack', status: 'acknowledged' },
  { id: 'd-4', title: 'Form W-2 (2025) available', from: 'Payroll', sent: '2026-01-28', action: 'view', status: 'viewed' },
  { id: 'd-5', title: 'Holiday schedule 2026', from: 'HR', sent: '2026-01-05', action: 'ack', status: 'acknowledged' },
];

// ── Provider ─────────────────────────────────────────────────
const PortalCtx = createContext(null);

function PortalProvider({ children }) {
  const [authed, setAuthed] = useState(() => {
    try { const s = window.RFP && RFP.session(); return !!(s && s.app === 'portal'); } catch (e) { return false; }
  });

  // Live employee data loaded from Supabase (null = not loaded)
  const [liveMe, setLiveMe] = useState(null);

  // Load employee profile from Supabase when authed
  useEffect(() => {
    if (!authed || !window._rfpSupabase) return;
    let cancelled = false;
    async function loadProfile() {
      try {
        const { data: { user } } = await window._rfpSupabase.auth.getUser();
        if (!user || cancelled) return;
        // Look up employee by user_id
        const { data: empData } = await window._rfpSupabase.from("employees")
          .select("*, users(email, role, company_id)")
          .eq("user_id", user.id)
          .single();
        if (empData && !cancelled) {
          setLiveMe({
            id: empData.id,
            name: [empData.first_name, empData.last_name].filter(Boolean).join(" "),
            first: empData.first_name || '',
            badge: empData.employee_number || '',
            avatar: ([empData.first_name, empData.last_name].filter(Boolean).map(n => n[0]).join('')).toUpperCase(),
            role: 'RWIC',
            email: empData.email || (empData.users && empData.users.email) || '',
            phone: empData.phone || '',
            baseRate: empData.base_rate || 0,
            resident: empData.resident_state || empData.state || 'MT',
            payrollFreq: 'Bi-weekly',
            rrbContributor: empData.rrb_contributor || false,
            hireDate: empData.hire_date || '',
            ssnMasked: '•••-••-****',
            ssnFull: '',
            address: { line1: '', line2: '', city: '', state: empData.state || '', zip: '' },
            directDeposit: ME.directDeposit,
            emergency: ME.emergency,
            ytd: ME.ytd,
          });
        }
      } catch (e) {
        console.warn("Portal: Supabase profile load failed, using static data.", e);
      }
    }
    loadProfile();
    return () => { cancelled = true; };
  }, [authed]);
  const [ptoReqs, setPtoReqs] = useState(PTO_REQUESTS);
  const [reimb, setReimb] = useState(REIMBURSEMENTS);
  const [inbox, setInbox] = useState(DOC_INBOX);
  const [activeDoc, setActiveDoc] = useState(null);
  const [toasts, setToasts] = useState([]);

  const toast = useCallback((text, kind = 'info', ms = 2600) => {
    const id = P_uid('t');
    setToasts(t => [...t, { id, text, kind }]);
    setTimeout(() => setToasts(t => t.filter(x => x.id !== id)), ms);
  }, []);

  const addPto = useCallback((req) => {
    setPtoReqs(r => [{ id: P_uid('pto'), status: 'pending', ...req }, ...r]);
    toast('Time-off request submitted for approval', 'success');
  }, [toast]);

  const addReimb = useCallback((r) => {
    setReimb(prev => [{ id: P_uid('rb'), status: 'pending', ...r }, ...prev]);
    toast('Reimbursement submitted', 'success');
  }, [toast]);

  const actOnDoc = useCallback((id, status) => {
    setInbox(d => d.map(x => x.id === id ? { ...x, status } : x));
    toast(status === 'acknowledged' ? 'Document acknowledged' : 'Document signed', 'success');
  }, [toast]);

  const value = useMemo(() => ({
    authed, setAuthed,
    me: liveMe || ME, employer: EMPLOYER,
    payPeriods: PAY_PERIODS, timecards: MY_TIMECARDS,
    ptoBalances: PTO_BALANCES, ptoReqs, addPto,
    certs: MY_CERTS, reimb, addReimb,
    inbox, actOnDoc,
    activeDoc, setActiveDoc,
    toasts, toast,
  }), [authed, liveMe, ptoReqs, addPto, reimb, addReimb, inbox, actOnDoc, activeDoc, toasts, toast]);

  return <PortalCtx.Provider value={value}>{children}</PortalCtx.Provider>;
}
const usePortal = () => useContext(PortalCtx);

Object.assign(window, {
  PortalCtx, PortalProvider, usePortal,
  ME, EMPLOYER, PAY_PERIODS, MY_TIMECARDS, PTO_BALANCES, PTO_REQUESTS,
  MY_CERTS, REIMBURSEMENTS, DOC_INBOX,
  P_money, P_num, P_date, P_uid,
});
