import { create } from 'zustand';
import { api } from '../api/client';
import type {
  Session,
  Exercise,
  SessionLog,
  LastLogResponse,
  CreateLogRequest,
  UpdateLogRequest,
} from '../types';
import { useToastStore } from './toastStore';

interface ActiveSessionState {
  session: Session | null;
  exercises: Exercise[];
  lastLogs: Map<number, LastLogResponse>;
  timerSeconds: number;
  timerTarget: number;
  timerInterval: ReturnType<typeof setInterval> | null;

  startSession: (setId: number, exercises: Exercise[]) => Promise<boolean>;
  loadSession: (sessionId: number) => Promise<boolean>;
  addLog: (data: CreateLogRequest) => Promise<SessionLog | null>;
  updateLog: (logId: number, data: UpdateLogRequest) => Promise<SessionLog | null>;
  deleteLog: (logId: number) => Promise<boolean>;
  endSession: (note?: string) => Promise<boolean>;
  fetchLastLog: (exerciseId: number) => Promise<LastLogResponse | null>;
  copyLastValues: (exerciseId: number) => LastLogResponse | null;
  startTimer: (seconds: number) => void;
  stopTimer: () => void;
  clearSession: () => void;
}

export const useActiveSessionStore = create<ActiveSessionState>((set, get) => ({
  session: null,
  exercises: [],
  lastLogs: new Map(),
  timerSeconds: 0,
  timerTarget: 0,
  timerInterval: null,

  startSession: async (setId, exercises) => {
    try {
      const session = await api.sessions.create({ set_id: setId });
      set({ session, exercises });

      // Lade letzte Logs für alle Übungen
      for (const ex of exercises) {
        await get().fetchLastLog(ex.id);
      }

      return true;
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Fehler beim Starten';
      useToastStore.getState().addToast('error', message);
      return false;
    }
  },

  loadSession: async (sessionId) => {
    try {
      const session = await api.sessions.get(sessionId);
      set({ session });
      return true;
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Session nicht gefunden';
      useToastStore.getState().addToast('error', message);
      return false;
    }
  },

  addLog: async (data) => {
    const { session } = get();
    if (!session) return null;
    try {
      const log = await api.sessions.createLog(session.id, data);
      // Reload session to get updated logs
      const updated = await api.sessions.get(session.id);
      set({ session: updated });
      return log;
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Fehler beim Speichern';
      useToastStore.getState().addToast('error', message);
      return null;
    }
  },

  updateLog: async (logId, data) => {
    const { session } = get();
    if (!session) return null;
    try {
      const log = await api.sessions.updateLog(session.id, logId, data);
      const updated = await api.sessions.get(session.id);
      set({ session: updated });
      return log;
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Fehler beim Aktualisieren';
      useToastStore.getState().addToast('error', message);
      return null;
    }
  },

  deleteLog: async (logId) => {
    const { session } = get();
    if (!session) return false;
    try {
      await api.sessions.deleteLog(session.id, logId);
      const updated = await api.sessions.get(session.id);
      set({ session: updated });
      useToastStore.getState().addToast('success', 'Satz gelöscht');
      return true;
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Fehler beim Löschen';
      useToastStore.getState().addToast('error', message);
      return false;
    }
  },

  endSession: async (note) => {
    const { session } = get();
    if (!session) return false;
    try {
      await api.sessions.end(session.id, note);
      get().stopTimer();
      set({ session: null, exercises: [], lastLogs: new Map() });
      useToastStore.getState().addToast('success', 'Training beendet');
      return true;
    } catch (err) {
      const message = err instanceof Error ? err.message : 'Fehler beim Beenden';
      useToastStore.getState().addToast('error', message);
      return false;
    }
  },

  fetchLastLog: async (exerciseId) => {
    try {
      const lastLog = await api.exercises.lastLog(exerciseId);
      set((state) => {
        const newMap = new Map(state.lastLogs);
        newMap.set(exerciseId, lastLog);
        return { lastLogs: newMap };
      });
      return lastLog;
    } catch {
      // 404 = noch kein Log vorhanden
      return null;
    }
  },

  copyLastValues: (exerciseId) => {
    return get().lastLogs.get(exerciseId) || null;
  },

  startTimer: (seconds) => {
    const { timerInterval } = get();
    if (timerInterval) clearInterval(timerInterval);

    set({ timerTarget: seconds, timerSeconds: seconds });
    const interval = setInterval(() => {
      const current = get().timerSeconds;
      if (current <= 1) {
        clearInterval(interval);
        set({ timerSeconds: 0, timerInterval: null });
      } else {
        set({ timerSeconds: current - 1 });
      }
    }, 1000);
    set({ timerInterval: interval });
  },

  stopTimer: () => {
    const { timerInterval } = get();
    if (timerInterval) clearInterval(timerInterval);
    set({ timerSeconds: 0, timerTarget: 0, timerInterval: null });
  },

  clearSession: () => {
    get().stopTimer();
    set({ session: null, exercises: [], lastLogs: new Map() });
  },
}));
