import {
  workoutsApi,
  type AddWorkoutExerciseDto,
  type CompleteWorkoutExerciseDto,
  type CreateWorkoutSessionDto,
  type StartWorkoutDto,
  type StartWorkoutExerciseDto,
  type UpdateWorkoutExerciseDto,
  type WorkoutExercise,
  type WorkoutSession,
  type WorkoutSessionStatsResponse,
} from '@/services/workoutsApi';
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';

export interface WorkoutState {
  // 当前训练会话
  currentSession: WorkoutSession | null;
  exercises: WorkoutExercise[];
  stats: WorkoutSessionStatsResponse | null;

  // 历史训练会话
  sessions: WorkoutSession[];
  sessionsPagination: {
    page: number;
    limit: number;
    total: number;
    totalPages: number;
  } | null;

  // 加载状态
  loading: boolean;
  exerciseLoading: string | null; // 正在操作的exercise ID
  error: string | null;
}

const initialState: WorkoutState = {
  currentSession: null,
  exercises: [],
  stats: null,
  sessions: [],
  sessionsPagination: null,
  loading: false,
  exerciseLoading: null,
  error: null,
};

// ==================== 异步Action定义 ====================

// 获取今日训练
export const loadTodayWorkout = createAsyncThunk(
  'workout/loadTodayWorkout',
  async (_, { rejectWithValue }) => {
    try {
      const session = await workoutsApi.getTodayWorkout();
      return session;
    } catch (error: any) {
      return rejectWithValue(error.message || '获取今日训练失败');
    }
  }
);

// 开始训练会话
export const startWorkoutSession = createAsyncThunk(
  'workout/startSession',
  async ({ sessionId, dto }: { sessionId: string; dto?: StartWorkoutDto }, { rejectWithValue }) => {
    try {
      const session = await workoutsApi.startSession(sessionId, dto);
      return session;
    } catch (error: any) {
      return rejectWithValue(error.message || '开始训练失败');
    }
  }
);

// 开始训练动作
export const startWorkoutExercise = createAsyncThunk(
  'workout/startExercise',
  async ({ sessionId, exerciseId, dto }: {
    sessionId: string;
    exerciseId: string;
    dto?: StartWorkoutExerciseDto
  }, { rejectWithValue }) => {
    try {
      const exercise = await workoutsApi.startExercise(sessionId, exerciseId, dto);
      return exercise;
    } catch (error: any) {
      return rejectWithValue(error.message || '开始动作失败');
    }
  }
);

// 完成训练动作
export const completeWorkoutExercise = createAsyncThunk(
  'workout/completeExercise',
  async ({ sessionId, exerciseId, dto }: {
    sessionId: string;
    exerciseId: string;
    dto: CompleteWorkoutExerciseDto
  }, { rejectWithValue, getState }) => {
    try {
      const exercise = await workoutsApi.completeExercise(sessionId, exerciseId, dto);

      // 完成动作后重新获取会话详情（检查是否自动完成）
      const updatedSession = await workoutsApi.getSessionDetail(sessionId);

      return { exercise, updatedSession };
    } catch (error: any) {
      return rejectWithValue(error.message || '完成动作失败');
    }
  }
);

// 跳过训练动作
export const skipWorkoutExercise = createAsyncThunk(
  'workout/skipExercise',
  async ({ sessionId, exerciseId }: { sessionId: string; exerciseId: string }, { rejectWithValue }) => {
    try {
      const exercise = await workoutsApi.skipExercise(sessionId, exerciseId);

      // 跳过动作后重新获取会话详情（检查是否自动完成）
      const updatedSession = await workoutsApi.getSessionDetail(sessionId);

      return { exercise, updatedSession };
    } catch (error: any) {
      return rejectWithValue(error.message || '跳过动作失败');
    }
  }
);

// 更新训练动作
export const updateWorkoutExercise = createAsyncThunk(
  'workout/updateExercise',
  async ({ sessionId, exerciseId, dto }: {
    sessionId: string;
    exerciseId: string;
    dto: UpdateWorkoutExerciseDto
  }, { rejectWithValue }) => {
    try {
      const exercise = await workoutsApi.updateExercise(sessionId, exerciseId, dto);
      return exercise;
    } catch (error: any) {
      return rejectWithValue(error.message || '更新动作失败');
    }
  }
);

// 获取训练统计
export const loadWorkoutStats = createAsyncThunk(
  'workout/loadStats',
  async (sessionId: string, { rejectWithValue }) => {
    try {
      const stats = await workoutsApi.getSessionStats(sessionId);
      return stats;
    } catch (error: any) {
      return rejectWithValue(error.message || '获取统计数据失败');
    }
  }
);

// 获取训练会话列表
export const loadWorkoutSessions = createAsyncThunk(
  'workout/loadSessions',
  async ({ page = 1, limit = 10, append = false }: { page?: number; limit?: number; append?: boolean } = {}, { rejectWithValue }) => {
    try {
      const result = await workoutsApi.getSessions(page, limit);
      return { ...result, append };
    } catch (error: any) {
      return rejectWithValue(error.message || '获取训练列表失败');
    }
  }
);

// 添加动作到训练会话
export const addWorkoutExercise = createAsyncThunk(
  'workout/addExercise',
  async ({ sessionId, dto }: { sessionId: string; dto: AddWorkoutExerciseDto }, { rejectWithValue }) => {
    try {
      const exercise = await workoutsApi.addExercise(sessionId, dto);
      return exercise;
    } catch (error: any) {
      return rejectWithValue(error.message || '添加动作失败');
    }
  }
);

// 创建训练会话
export const createWorkoutSession = createAsyncThunk(
  'workout/createSession',
  async (dto: CreateWorkoutSessionDto, { rejectWithValue }) => {
    try {
      console.log('createWorkoutSession', dto);
      const session = await workoutsApi.createSession(dto);
      return session;
    } catch (error: any) {
      return rejectWithValue(error.message || '创建训练会话失败');
    }
  }
);

// 删除训练会话
export const deleteWorkoutSession = createAsyncThunk(
  'workout/deleteSession',
  async (sessionId: string, { rejectWithValue }) => {
    try {
      await workoutsApi.deleteSession(sessionId);
      return sessionId;
    } catch (error: any) {
      return rejectWithValue(error.message || '删除训练会话失败');
    }
  }
);

// ==================== Slice定义 ====================

const workoutSlice = createSlice({
  name: 'workout',
  initialState,
  reducers: {
    clearWorkoutError(state) {
      state.error = null;
    },
    clearCurrentWorkout(state) {
      state.currentSession = null;
      state.exercises = [];
      state.stats = null;
    },
    // 本地更新exercise状态（用于乐观更新）
    updateExerciseLocally(state, action: PayloadAction<Partial<WorkoutExercise> & { id: string }>) {
      const { id, ...updates } = action.payload;
      const exerciseIndex = state.exercises.findIndex(ex => ex.id === id);
      if (exerciseIndex !== -1) {
        Object.assign(state.exercises[exerciseIndex], updates);
      }
    },
  },
  extraReducers: (builder) => {
    builder
      // loadTodayWorkout
      .addCase(loadTodayWorkout.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(loadTodayWorkout.fulfilled, (state, action) => {
        state.loading = false;
        if (action.payload) {
          state.currentSession = action.payload;
          state.exercises = action.payload.exercises || [];
        }
      })
      .addCase(loadTodayWorkout.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload as string;
      })

      // startWorkoutSession
      .addCase(startWorkoutSession.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(startWorkoutSession.fulfilled, (state, action) => {
        state.loading = false;
        state.currentSession = action.payload;
      })
      .addCase(startWorkoutSession.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload as string;
      })

      // startWorkoutExercise
      .addCase(startWorkoutExercise.pending, (state, action) => {
        state.exerciseLoading = action.meta.arg.exerciseId;
        state.error = null;
      })
      .addCase(startWorkoutExercise.fulfilled, (state, action) => {
        state.exerciseLoading = null;
        const exerciseIndex = state.exercises.findIndex(ex => ex.id === action.payload.id);
        if (exerciseIndex !== -1) {
          state.exercises[exerciseIndex] = action.payload;
        }
      })
      .addCase(startWorkoutExercise.rejected, (state, action) => {
        state.exerciseLoading = null;
        state.error = action.payload as string;
      })

      // completeWorkoutExercise
      .addCase(completeWorkoutExercise.pending, (state, action) => {
        state.exerciseLoading = action.meta.arg.exerciseId;
        state.error = null;
      })
      .addCase(completeWorkoutExercise.fulfilled, (state, action) => {
        state.exerciseLoading = null;
        const { exercise, updatedSession } = action.payload;

        // 更新exercise
        const exerciseIndex = state.exercises.findIndex(ex => ex.id === exercise.id);
        if (exerciseIndex !== -1) {
          state.exercises[exerciseIndex] = exercise;
        }

        // 更新session（可能已自动完成）
        state.currentSession = updatedSession;
      })
      .addCase(completeWorkoutExercise.rejected, (state, action) => {
        state.exerciseLoading = null;
        state.error = action.payload as string;
      })

      // skipWorkoutExercise
      .addCase(skipWorkoutExercise.pending, (state, action) => {
        state.exerciseLoading = action.meta.arg.exerciseId;
        state.error = null;
      })
      .addCase(skipWorkoutExercise.fulfilled, (state, action) => {
        state.exerciseLoading = null;
        const { exercise, updatedSession } = action.payload;

        // 更新exercise
        const exerciseIndex = state.exercises.findIndex(ex => ex.id === exercise.id);
        if (exerciseIndex !== -1) {
          state.exercises[exerciseIndex] = exercise;
        }

        // 更新session（可能已自动完成）
        state.currentSession = updatedSession;
      })
      .addCase(skipWorkoutExercise.rejected, (state, action) => {
        state.exerciseLoading = null;
        state.error = action.payload as string;
      })

      // updateWorkoutExercise
      .addCase(updateWorkoutExercise.pending, (state, action) => {
        state.exerciseLoading = action.meta.arg.exerciseId;
        state.error = null;
      })
      .addCase(updateWorkoutExercise.fulfilled, (state, action) => {
        state.exerciseLoading = null;
        const exerciseIndex = state.exercises.findIndex(ex => ex.id === action.payload.id);
        if (exerciseIndex !== -1) {
          state.exercises[exerciseIndex] = action.payload;
        }
      })
      .addCase(updateWorkoutExercise.rejected, (state, action) => {
        state.exerciseLoading = null;
        state.error = action.payload as string;
      })

      // loadWorkoutStats
      .addCase(loadWorkoutStats.fulfilled, (state, action) => {
        state.stats = action.payload;
      })

      // loadWorkoutSessions
      .addCase(loadWorkoutSessions.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(loadWorkoutSessions.fulfilled, (state, action) => {
        state.loading = false;
        if (action.payload.append) {
          // 追加数据（分页加载更多）
          state.sessions = [...state.sessions, ...action.payload.sessions];
        } else {
          // 替换数据（刷新或首次加载）
          state.sessions = action.payload.sessions;
        }
        state.sessionsPagination = action.payload.pagination;
      })
      .addCase(loadWorkoutSessions.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload as string;
      })

      // addWorkoutExercise
      .addCase(addWorkoutExercise.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(addWorkoutExercise.fulfilled, (state, action) => {
        state.loading = false;
        // 将新添加的动作添加到exercises列表末尾
        state.exercises.push(action.payload);
      })
      .addCase(addWorkoutExercise.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload as string;
      })

      // createWorkoutSession
      .addCase(createWorkoutSession.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(createWorkoutSession.fulfilled, (state, action) => {
        state.loading = false;
        // 将新创建的会话添加到列表开头
        state.sessions.unshift(action.payload);
        // 设置为当前会话
        state.currentSession = action.payload;
        state.exercises = action.payload.exercises || [];
      })
      .addCase(createWorkoutSession.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload as string;
      })

      // deleteWorkoutSession
      .addCase(deleteWorkoutSession.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(deleteWorkoutSession.fulfilled, (state, action) => {
        state.loading = false;
        const deletedSessionId = action.payload;

        // 如果删除的是当前会话，清空当前会话数据
        if (state.currentSession?.id === deletedSessionId) {
          state.currentSession = null;
          state.exercises = [];
          state.stats = null;
        }

        // 从会话列表中移除已删除的会话
        state.sessions = state.sessions.filter(session => session.id !== deletedSessionId);
      })
      .addCase(deleteWorkoutSession.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload as string;
      });
  },
});

export const { clearWorkoutError, clearCurrentWorkout, updateExerciseLocally } = workoutSlice.actions;

export default workoutSlice.reducer;
