import {
  scheduleExerciseApi,
  type CreateScheduleExerciseDto,
  type ReorderExercisesDto,
  type ScheduleExercise,
  type UpdateScheduleExerciseDto
} from '@/services/scheduleExerciseApi';
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';

export type ScheduleExerciseState = {
  exercises: ScheduleExercise[];
  loading: boolean;
  error: string | null;
  currentPlanId: string | null;
};

const initialState: ScheduleExerciseState = {
  exercises: [],
  loading: false,
  error: null,
  currentPlanId: null,
};

// 加载训练计划的所有项目
export const loadExercises = createAsyncThunk(
  'scheduleExercise/loadExercises',
  async (planId: string, { rejectWithValue }) => {
    try {
      const exercises = await scheduleExerciseApi.list(planId);
      return { exercises, planId };
    } catch (error: any) {
      return rejectWithValue(error.message || '加载训练项目失败');
    }
  }
);

// 添加训练项目
export const addExercise = createAsyncThunk(
  'scheduleExercise/addExercise',
  async ({ planId, dto }: { planId: string; dto: CreateScheduleExerciseDto }, { rejectWithValue }) => {
    try {
      const exercise = await scheduleExerciseApi.create(planId, dto);
      return { exercise };
    } catch (error: any) {
      return rejectWithValue(error.message || '添加训练项目失败');
    }
  }
);

// 更新训练项目
export const updateExercise = createAsyncThunk(
  'scheduleExercise/updateExercise',
  async ({
    planId,
    exerciseId,
    dto
  }: {
    planId: string;
    exerciseId: string;
    dto: UpdateScheduleExerciseDto;
  }, { rejectWithValue }) => {
    try {
      const exercise = await scheduleExerciseApi.update(planId, exerciseId, dto);
      return { exercise };
    } catch (error: any) {
      return rejectWithValue(error.message || '更新训练项目失败');
    }
  }
);

// 删除训练项目
export const deleteExercise = createAsyncThunk(
  'scheduleExercise/deleteExercise',
  async ({ planId, exerciseId }: { planId: string; exerciseId: string }, { rejectWithValue }) => {
    try {
      await scheduleExerciseApi.delete(planId, exerciseId);
      return { exerciseId };
    } catch (error: any) {
      return rejectWithValue(error.message || '删除训练项目失败');
    }
  }
);

// 重新排序训练项目
export const reorderExercises = createAsyncThunk(
  'scheduleExercise/reorderExercises',
  async ({ planId, dto }: { planId: string; dto: ReorderExercisesDto }, { rejectWithValue }) => {
    try {
      await scheduleExerciseApi.reorder(planId, dto);
      // 重新加载排序后的列表
      const exercises = await scheduleExerciseApi.list(planId);
      return { exercises };
    } catch (error: any) {
      return rejectWithValue(error.message || '重新排序失败');
    }
  }
);

// 更新完成状态
export const toggleCompletion = createAsyncThunk(
  'scheduleExercise/toggleCompletion',
  async ({
    planId,
    exerciseId,
    completed
  }: {
    planId: string;
    exerciseId: string;
    completed: boolean;
  }, { rejectWithValue }) => {
    try {
      const exercise = await scheduleExerciseApi.updateCompletion(planId, exerciseId, completed);
      return { exercise };
    } catch (error: any) {
      return rejectWithValue(error.message || '更新完成状态失败');
    }
  }
);

const scheduleExerciseSlice = createSlice({
  name: 'scheduleExercise',
  initialState,
  reducers: {
    clearError(state) {
      state.error = null;
    },
    clearExercises(state) {
      state.exercises = [];
      state.currentPlanId = null;
    },
    // 本地更新排序（用于拖拽等即时反馈）
    updateLocalOrder(state, action: PayloadAction<string[]>) {
      const newOrder = action.payload;
      const orderedExercises = newOrder.map(id =>
        state.exercises.find(ex => ex.id === id)
      ).filter(Boolean) as ScheduleExercise[];
      state.exercises = orderedExercises;
    },
  },
  extraReducers: (builder) => {
    builder
      // loadExercises
      .addCase(loadExercises.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(loadExercises.fulfilled, (state, action) => {
        state.loading = false;
        state.exercises = action.payload.exercises;
        state.currentPlanId = action.payload.planId;
      })
      .addCase(loadExercises.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload as string;
      })

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

      // updateExercise
      .addCase(updateExercise.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(updateExercise.fulfilled, (state, action) => {
        state.loading = false;
        const index = state.exercises.findIndex(ex => ex.id === action.payload.exercise.id);
        if (index !== -1) {
          state.exercises[index] = action.payload.exercise;
        }
      })
      .addCase(updateExercise.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload as string;
      })

      // deleteExercise
      .addCase(deleteExercise.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(deleteExercise.fulfilled, (state, action) => {
        state.loading = false;
        state.exercises = state.exercises.filter(ex => ex.id !== action.payload.exerciseId);
      })
      .addCase(deleteExercise.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload as string;
      })

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

      // toggleCompletion
      .addCase(toggleCompletion.pending, (state) => {
        state.error = null;
      })
      .addCase(toggleCompletion.fulfilled, (state, action) => {
        const index = state.exercises.findIndex(ex => ex.id === action.payload.exercise.id);
        if (index !== -1) {
          state.exercises[index] = action.payload.exercise;
        }
      })
      .addCase(toggleCompletion.rejected, (state, action) => {
        state.error = action.payload as string;
      });
  },
});

export const { clearError, clearExercises, updateLocalOrder } = scheduleExerciseSlice.actions;
export default scheduleExerciseSlice.reducer;
