// App state — auth, navigation, user picks, crowd counters, dream history, etc.
// Single global store so all screens share state.

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

// ─────────────────────────────────────────────
// Helper: thai date formatting
// ─────────────────────────────────────────────
window.thaiMonths = ['ม.ค.','ก.พ.','มี.ค.','เม.ย.','พ.ค.','มิ.ย.','ก.ค.','ส.ค.','ก.ย.','ต.ค.','พ.ย.','ธ.ค.'];
window.formatThaiDate = (d) => {
  if (!d) return '';
  const date = new Date(d);
  return `${date.getDate()} ${thaiMonths[date.getMonth()]} ${date.getFullYear() + 543}`;
};

// Countdown helper — target time HH:MM today (or next occurrence)
window.useCountdown = (closeTime) => {
  const [remaining, setRemaining] = useState(() => computeRemaining(closeTime));
  useEffect(() => {
    const id = setInterval(() => setRemaining(computeRemaining(closeTime)), 1000);
    return () => clearInterval(id);
  }, [closeTime]);
  return remaining;
};
function computeRemaining(closeTime) {
  const [h, m] = closeTime.split(':').map(Number);
  const now = new Date();
  const target = new Date(now);
  target.setHours(h, m, 0, 0);
  if (target <= now) target.setDate(target.getDate() + 1);
  const diff = Math.max(0, target - now);
  const hh = Math.floor(diff / 3600000);
  const mm = Math.floor((diff % 3600000) / 60000);
  const ss = Math.floor((diff % 60000) / 1000);
  return { hh, mm, ss, totalMs: diff, text: `${String(hh).padStart(2,'0')}:${String(mm).padStart(2,'0')}:${String(ss).padStart(2,'0')}` };
}

// ─────────────────────────────────────────────
// Global store (context)
// ─────────────────────────────────────────────
const AppContext = React.createContext(null);
window.useApp = () => React.useContext(AppContext);

// Hash routing — parse + serialize URL hash
function parseHash() {
  const raw = (window.location.hash || '').replace(/^#\/?/, '');
  if (!raw) return { name: 'login', params: {} };
  const [name, qs] = raw.split('?');
  const params = {};
  if (qs) qs.split('&').forEach(p => {
    const [k, v] = p.split('=');
    if (k) params[k] = decodeURIComponent(v || '');
  });
  return { name: name || 'login', params };
}
function serializeHash(name, params = {}) {
  const keys = Object.keys(params);
  const qs = keys.length ? '?' + keys.map(k => `${k}=${encodeURIComponent(params[k])}`).join('&') : '';
  return `#/${name}${qs}`;
}

window.AppProvider = function AppProvider({ children, tweaks }) {
  // Restore session on boot if token + user exist in storage
  const [user, setUser] = useState(() => {
    try {
      const t = localStorage.getItem(window.LOTTERY_TOKEN_KEY);
      const u = localStorage.getItem(window.LOTTERY_USER_KEY);
      if (t && u) return JSON.parse(u);
    } catch (e) {}
    return null;
  });
  const [route, setRoute] = useState(() => parseHash());
  const [crowdExtra, setCrowdExtra] = useState({});
  const [dreamHistory, setDreamHistory] = useState([]);
  const [ocrHistory, setOcrHistory] = useState([]);
  const [luckyResult, setLuckyResult] = useState(null);
  const [adminSection, setAdminSection] = useState('dashboard');
  const [speakerOn, setSpeakerOn] = useState(false);
  const [lotteriesVersion, setLotteriesVersion] = useState(0);

  const go = useCallback((name, params = {}) => {
    setRoute({ name, params });
    const newHash = serializeHash(name, params);
    if (window.location.hash !== newHash) {
      window.location.hash = newHash;
    }
  }, []);

  useEffect(() => {
    const handler = () => setRoute(parseHash());
    window.addEventListener('hashchange', handler);
    return () => window.removeEventListener('hashchange', handler);
  }, []);

  // Fetch lotteries from API and replace MOCK_LOTTERIES; bump version to re-render consumers.
  const refreshLotteries = useCallback(async () => {
    try {
      const data = await window.api.lotteries();
      if (Array.isArray(data) && data.length > 0) {
        window.MOCK_LOTTERIES = data.map(window.mapLottery);
        setLotteriesVersion(v => v + 1);
      }
      return { ok: true };
    } catch (e) {
      if (e.status === 401) {
        setUser(null);
        go('login');
      }
      return { ok: false, error: e };
    }
  }, [go]);

  // On boot or user change, if logged in, refresh lotteries
  useEffect(() => {
    if (user) refreshLotteries();
  }, [user, refreshLotteries]);

  const login = useCallback(async (phone, pin) => {
    const cleanPhone = (phone || '').replace(/\D/g, '');
    if (cleanPhone.length !== 10) return { ok: false, error: 'เบอร์โทรต้องมี 10 หลัก' };
    const cleanPin = (pin || '').replace(/\D/g, '');
    if (cleanPin.length !== 6) return { ok: false, error: 'PIN ต้องมี 6 หลัก' };
    try {
      const data = await window.api.login(cleanPhone, cleanPin);
      const u = {
        id: data.user.id,
        phone: data.user.phone,
        name: data.user.display_name || cleanPhone,
        isAdmin: !!data.user.is_admin,
        birth: data.user.birth_date || null,
      };
      localStorage.setItem(window.LOTTERY_TOKEN_KEY, data.token);
      localStorage.setItem(window.LOTTERY_USER_KEY, JSON.stringify(u));
      setUser(u);
      go(u.isAdmin ? 'admin' : 'home');
      return { ok: true };
    } catch (e) {
      const msg = e.code === 'INVALID_CREDENTIALS' ? 'เบอร์หรือ PIN ไม่ถูกต้อง'
        : e.code === 'ACCOUNT_LOCKED' ? 'บัญชีถูกล็อก กรุณารอสักครู่'
        : e.code === 'INVALID_FORMAT' ? 'รูปแบบเบอร์หรือ PIN ไม่ถูกต้อง'
        : e.code === 'NETWORK_ERROR' ? 'เชื่อมต่อเซิร์ฟเวอร์ไม่ได้ ลองใหม่อีกครั้ง'
        : (e.message || 'เข้าสู่ระบบไม่สำเร็จ');
      return { ok: false, error: msg };
    }
  }, [go]);

  const logout = useCallback(() => {
    window.api.logout().finally(() => {
      setUser(null);
      go('login');
    });
  }, [go]);

  const bumpCrowd = useCallback((slug, num) => {
    setCrowdExtra(prev => {
      const s = { ...(prev[slug] || {}) };
      s[num] = (s[num] || 0) + 1;
      return { ...prev, [slug]: s };
    });
  }, []);

  const addDream = useCallback((entry) => {
    setDreamHistory(prev => [entry, ...prev].slice(0, 10));
  }, []);

  const addOcr = useCallback((entry) => {
    setOcrHistory(prev => [entry, ...prev].slice(0, 5));
  }, []);

  const value = useMemo(() => ({
    user, route, go, login, logout,
    crowdExtra, bumpCrowd,
    dreamHistory, addDream,
    ocrHistory, addOcr,
    luckyResult, setLuckyResult,
    adminSection, setAdminSection,
    speakerOn, setSpeakerOn,
    lotteriesVersion, refreshLotteries,
    tweaks,
  }), [user, route, go, login, logout, crowdExtra, bumpCrowd, dreamHistory, addDream, ocrHistory, addOcr, luckyResult, adminSection, speakerOn, lotteriesVersion, refreshLotteries, tweaks]);

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