import {
  fetchExerciseConfig,
  normalizeToLibraryItems,
  type ExerciseCategoryDto,
  type ExerciseConfigResponse,
  type ExerciseLibraryItem,
} from '@/services/exercises';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';

export interface ExerciseLibraryState {
  categories: ExerciseCategoryDto[];
  exercises: ExerciseLibraryItem[];
  loading: boolean;
  error: string | null;
  lastUpdatedAt: number | null;
}

const CACHE_KEY = '@exercise_config_v2';

const initialState: ExerciseLibraryState = {
  categories: [],
  exercises: [],
  loading: false,
  error: null,
  lastUpdatedAt: null,
};

export const loadExerciseLibrary = createAsyncThunk(
  'exerciseLibrary/load',
  async (_: void, { rejectWithValue }) => {
    // 先读本地缓存（最佳体验），随后静默刷新远端
    try {
      const cached = await AsyncStorage.getItem(CACHE_KEY);
      if (cached) {
        const data = JSON.parse(cached) as ExerciseConfigResponse;
        return { source: 'cache' as const, data };
      }
    } catch { }

    try {
      const fresh = await fetchExerciseConfig();
      try { await AsyncStorage.setItem(CACHE_KEY, JSON.stringify(fresh)); } catch { }
      return { source: 'network' as const, data: fresh };
    } catch (error: any) {
      return rejectWithValue(error.message || '加载动作库失败');
    }
  }
);

export const refreshExerciseLibrary = createAsyncThunk(
  'exerciseLibrary/refresh',
  async (_: void, { rejectWithValue }) => {
    try {
      const fresh = await fetchExerciseConfig();
      try { await AsyncStorage.setItem(CACHE_KEY, JSON.stringify(fresh)); } catch { }
      return fresh;
    } catch (error: any) {
      return rejectWithValue(error.message || '刷新动作库失败');
    }
  }
);

const exerciseLibrarySlice = createSlice({
  name: 'exerciseLibrary',
  initialState,
  reducers: {
    clearExerciseLibraryError(state) {
      state.error = null;
    },
    setExerciseLibraryFromData(
      state,
      action: PayloadAction<ExerciseConfigResponse>
    ) {
      const data = action.payload;
      state.categories = (data.categories || []).slice().sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0));
      const sorted: ExerciseConfigResponse = {
        ...data,
        exercises: (data.exercises || []).slice().sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)),
      };
      state.exercises = normalizeToLibraryItems(sorted);
      state.lastUpdatedAt = Date.now();
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(loadExerciseLibrary.pending, (state) => {
        state.loading = true;
        state.error = null;
      })
      .addCase(loadExerciseLibrary.fulfilled, (state, action) => {
        const { data } = action.payload as { source: 'cache' | 'network'; data: ExerciseConfigResponse };
        state.loading = false;
        state.categories = (data.categories || []).slice().sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0));
        const sorted: ExerciseConfigResponse = {
          ...data,
          exercises: (data.exercises || []).slice().sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)),
        };
        state.exercises = normalizeToLibraryItems(sorted);
        state.lastUpdatedAt = Date.now();
      })
      .addCase(loadExerciseLibrary.rejected, (state, action) => {
        state.loading = false;
        state.error = action.payload as string;
      })

      .addCase(refreshExerciseLibrary.fulfilled, (state, action) => {
        const data = action.payload as ExerciseConfigResponse;
        state.categories = (data.categories || []).slice().sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0));
        const sorted: ExerciseConfigResponse = {
          ...data,
          exercises: (data.exercises || []).slice().sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)),
        };
        state.exercises = normalizeToLibraryItems(sorted);
        state.lastUpdatedAt = Date.now();
      })
      .addCase(refreshExerciseLibrary.rejected, (state, action) => {
        state.error = action.payload as string;
      });
  },
});

export const { clearExerciseLibraryError, setExerciseLibraryFromData } = exerciseLibrarySlice.actions;
export default exerciseLibrarySlice.reducer;


