import { create } from 'zustand';
import type { TimingRecord, LapTime } from '@/types';
import { timingApi } from '@/lib/apiClient';

interface TimingState {
  isRunning: boolean;
  elapsedMs: number;
  laps: LapTime[];
  records: TimingRecord[];
  startTimer: () => void;
  stopTimer: () => void;
  resetTimer: () => void;
  recordLap: () => void;
  tick: () => void;
  fetchRecords: () => Promise<void>;
  saveTiming: (data: { studentId: number; distance: string; time: string; date: string; notes?: string }) => Promise<void>;
}

// No demo data - starts empty
const demoRecords: TimingRecord[] = [];

function mapApiRecord(r: Record<string, unknown>): TimingRecord {
  return {
    id: Number(r.id ?? 0),
    studentId: Number(r.student_id ?? r.studentId ?? 0),
    studentName: String(r.student_name ?? r.studentName ?? ''),
    distance: String(r.distance ?? '500m') as '500m' | '1lap' | '1000m' | '1500m' | '3000m',
    timeSeconds: Number(r.time_seconds ?? r.timeSeconds ?? 0),
    timeDisplay: String(r.time_display ?? r.timeDisplay ?? '00:00.00'),
    recordDate: String(r.record_date ?? r.recordDate ?? ''),
    notes: r.notes ? String(r.notes) : undefined,
    improvement: r.improvement ? Number(r.improvement) : undefined,
  };
}

export const useTimingStore = create<TimingState>((set, get) => ({
  isRunning: false,
  elapsedMs: 0,
  laps: [],
  records: [],

  startTimer: () => {
    set({ isRunning: true });
    const interval = setInterval(() => {
      const state = get();
      if (!state.isRunning) { clearInterval(interval); return; }
      set({ elapsedMs: state.elapsedMs + 10 });
    }, 10);
  },

  stopTimer: () => set({ isRunning: false }),

  resetTimer: () => set({ isRunning: false, elapsedMs: 0, laps: [] }),

  recordLap: () => {
    const state = get();
    const totalMs = state.elapsedMs;
    const mins = Math.floor(totalMs / 60000);
    const secs = Math.floor((totalMs % 60000) / 1000);
    const ms = Math.floor((totalMs % 1000) / 10);
    const timeStr = `${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}.${String(ms).padStart(2, '0')}`;

    const prevLap = state.laps[state.laps.length - 1];
    let delta = '';
    if (prevLap) {
      const prevMs = state.laps.reduce((acc, l, i) => {
        if (i === state.laps.length - 1) {
          const parts = l.totalTime.split(':');
          const m = parseInt(parts[0]) * 60000;
          const s = parseInt(parts[1].split('.')[0]) * 1000;
          const ms2 = parseInt(parts[1].split('.')[1]) * 10;
          return acc + (m + s + ms2);
        }
        return acc;
      }, 0);
      const diff = totalMs - prevMs;
      const sign = diff >= 0 ? '+' : '-';
      const dSecs = Math.floor(Math.abs(diff) / 1000);
      const dMs = Math.floor((Math.abs(diff) % 1000) / 10);
      delta = `${sign}${String(dSecs).padStart(2, '0')}.${String(dMs).padStart(2, '0')}`;
    }

    set({
      laps: [...state.laps, { lapNumber: state.laps.length + 1, time: timeStr, totalTime: timeStr, delta: delta || undefined }],
    });
  },

  tick: () => set(state => ({ elapsedMs: state.elapsedMs + 10 })),

  fetchRecords: async () => {
    try {
      const data = await timingApi.getAll();
      if (Array.isArray(data)) {
        set({ records: data.map(mapApiRecord) });
      }
    } catch {
      set({ records: demoRecords });
    }
  },

  saveTiming: async (data) => {
    await new Promise(r => setTimeout(r, 400));
    try {
      await timingApi.create(data);
      await get().fetchRecords();
    } catch {
      // Offline fallback - add to local state
      const state = get();
      const parts = data.time.split(':');
      const mins = parseInt(parts[0]) * 60;
      const secs = parseFloat(parts[1]);
      const totalSeconds = mins + secs;

      const newRecord: TimingRecord = {
        id: Math.max(...state.records.map(r => r.id), 0) + 1,
        studentId: data.studentId,
        distance: data.distance as '500m' | '1lap' | '1000m' | '1500m' | '3000m',
        timeSeconds: totalSeconds,
        timeDisplay: data.time,
        recordDate: data.date,
        notes: data.notes,
      };
      set({ records: [...state.records, newRecord] });
    }
  },
}));
