import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import type { SessionEvent } from '@/domain/entities/agent-session';
import { apiClient } from '@/infrastructure/api/api-client';

interface SessionReplayState {
  sessionId: string | null;
  events: SessionEvent[];
  currentIndex: number;
  isPlaying: boolean;
  playbackSpeed: number;
  loading: boolean;
  error: string | null;
}

const initialState: SessionReplayState = {
  sessionId: null,
  events: [],
  currentIndex: 0,
  isPlaying: false,
  playbackSpeed: 1,
  loading: false,
  error: null,
};

export const fetchSessionEvents = createAsyncThunk(
  'sessionReplay/fetchEvents',
  async (sessionId: string) => {
    const events = await apiClient<SessionEvent[]>(`/api/v1/sessions/${sessionId}/events`);
    return { sessionId, events };
  },
);

export const sessionReplaySlice = createSlice({
  name: 'sessionReplay',
  initialState,
  reducers: {
    play: (state) => {
      state.isPlaying = true;
    },
    pause: (state) => {
      state.isPlaying = false;
    },
    stop: (state) => {
      state.isPlaying = false;
      state.currentIndex = 0;
    },
    stepForward: (state) => {
      if (state.currentIndex < state.events.length - 1) {
        state.currentIndex += 1;
      } else {
        state.isPlaying = false;
      }
    },
    stepBackward: (state) => {
      if (state.currentIndex > 0) {
        state.currentIndex -= 1;
      }
    },
    seekTo: (state, action: PayloadAction<number>) => {
      state.currentIndex = Math.max(0, Math.min(action.payload, state.events.length - 1));
    },
    setPlaybackSpeed: (state, action: PayloadAction<number>) => {
      state.playbackSpeed = action.payload;
    },
    resetReplay: () => initialState,
  },
  extraReducers: (builder) => {
    builder
      .addCase(fetchSessionEvents.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchSessionEvents.fulfilled, (state, action) => {
        state.loading = false;
        state.sessionId = action.payload.sessionId;
        state.events = action.payload.events;
        state.currentIndex = 0;
        state.isPlaying = false;
      })
      .addCase(fetchSessionEvents.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message ?? 'Failed to fetch session events';
      });
  },
});

export const sessionReplayActions = sessionReplaySlice.actions;
