import { create } from 'zustand';
import { api, ApiError } from '../api/client';
import type { EventType, LiveStatus, StatsSummary } from '../api/types';
import { withLiveTime } from '../lib/liveSession';

const POLL_MS = 60_000;
const TICK_MS = 1_000;

interface AttendanceState {
  status: LiveStatus | null;
  stats: StatsSummary | null;
  /** `stats` recomputed against a live clock, cached so it only changes reference on an actual tick. */
  live: StatsSummary | null;
  busy: boolean;
  error: string | null;
  pollTimer: ReturnType<typeof setInterval> | null;
  tickTimer: ReturnType<typeof setInterval> | null;

  load: () => Promise<void>;
  recordEvent: (type: EventType) => Promise<void>;
  startPolling: () => void;
  stopPolling: () => void;
}

const useAttendanceStore = create<AttendanceState>((set, get) => ({
  status: null,
  stats: null,
  live: null,
  busy: false,
  error: null,
  pollTimer: null,
  tickTimer: null,

  load: async () => {
    try {
      const [stateRes, statsRes] = await Promise.all([
        api.get<{ status: LiveStatus }>('/attendance/state'),
        api.get<StatsSummary>('/attendance/me'),
      ]);
      const now = new Date();
      set({ status: stateRes.status, stats: statsRes, live: withLiveTime(statsRes, now), error: null });
    } catch {
      set({ error: 'Nepodařilo se načíst data' });
    }
  },

  recordEvent: async (type) => {
    set({ busy: true, error: null });
    try {
      await api.post('/attendance/event', { type });
      await get().load();
    } catch (err) {
      set({ error: err instanceof ApiError ? err.message : 'Akce se nezdařila' });
    } finally {
      set({ busy: false });
    }
  },

  // Polls the server every minute (so a shift that keeps running stays in sync)
  // and ticks a local clock every second so the on-screen duration counts up
  // smoothly between polls instead of freezing until the next reload.
  startPolling: () => {
    if (get().pollTimer || get().tickTimer) return;
    const poll = setInterval(() => {
      get().load();
    }, POLL_MS);
    const tick = setInterval(() => {
      const { stats } = get();
      if (stats) set({ live: withLiveTime(stats, new Date()) });
    }, TICK_MS);
    set({ pollTimer: poll, tickTimer: tick });
  },

  stopPolling: () => {
    const { pollTimer, tickTimer } = get();
    if (pollTimer) clearInterval(pollTimer);
    if (tickTimer) clearInterval(tickTimer);
    set({ pollTimer: null, tickTimer: null });
  },
}));

export default useAttendanceStore;
