import { buildDefaultCustomFromPlan, DayPlan, ExerciseCustomConfig, generatePilates30DayPlan, PilatesLevel } from '@/utils/pilatesPlan';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';

export type DayStatus = 'locked' | 'available' | 'completed';

export type ChallengeDayState = {
  plan: DayPlan;
  status: DayStatus;
  completedAt?: string | null; // ISO
  notes?: string;
  custom?: ExerciseCustomConfig[]; // 用户自定义：启用/禁用、组数、时长
};

export type ChallengeState = {
  startedAt?: string | null;
  level: PilatesLevel;
  days: ChallengeDayState[]; // 1..30
  streak: number; // 连续天数
};

const STORAGE_KEY = '@pilates_challenge_30d';

const initialState: ChallengeState = {
  startedAt: null,
  level: 'beginner',
  days: [],
  streak: 0,
};

function computeStreak(days: ChallengeDayState[]): number {
  // 连续从第1天开始的已完成天数
  let s = 0;
  for (let i = 0; i < days.length; i += 1) {
    if (days[i].status === 'completed') s += 1; else break;
  }
  return s;
}

export const initChallenge = createAsyncThunk(
  'challenge/init',
  async (_: void, { getState }) => {
    const persisted = await AsyncStorage.getItem(STORAGE_KEY);
    if (persisted) {
      try {
        const parsed = JSON.parse(persisted) as ChallengeState;
        return parsed;
      } catch {}
    }
    // 默认生成
    const level: PilatesLevel = 'beginner';
    const plans = generatePilates30DayPlan(level);
    const days: ChallengeDayState[] = plans.map((p, idx) => ({
      plan: p,
      status: idx === 0 ? 'available' : 'locked',
      custom: buildDefaultCustomFromPlan(p),
    }));
    const state: ChallengeState = {
      startedAt: new Date().toISOString(),
      level,
      days,
      streak: 0,
    };
    await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(state));
    return state;
  }
);

export const persistChallenge = createAsyncThunk(
  'challenge/persist',
  async (_: void, { getState }) => {
    const s = (getState() as any).challenge as ChallengeState;
    await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(s));
    return true;
  }
);

export const completeDay = createAsyncThunk(
  'challenge/completeDay',
  async (dayNumber: number, { getState, dispatch }) => {
    const state = (getState() as any).challenge as ChallengeState;
    const idx = dayNumber - 1;
    const days = [...state.days];
    if (!days[idx] || days[idx].status === 'completed') return state;
    days[idx] = { ...days[idx], status: 'completed', completedAt: new Date().toISOString() };
    if (days[idx + 1]) {
      days[idx + 1] = { ...days[idx + 1], status: 'available' };
    }
    const next: ChallengeState = {
      ...state,
      days,
      streak: computeStreak(days),
    };
    await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(next));
    return next;
  }
);

const challengeSlice = createSlice({
  name: 'challenge',
  initialState,
  reducers: {
    setLevel(state, action: PayloadAction<PilatesLevel>) {
      state.level = action.payload;
    },
    setNote(state, action: PayloadAction<{ dayNumber: number; notes: string }>) {
      const idx = action.payload.dayNumber - 1;
      if (state.days[idx]) state.days[idx].notes = action.payload.notes;
    },
    setCustom(state, action: PayloadAction<{ dayNumber: number; custom: ExerciseCustomConfig[] }>) {
      const idx = action.payload.dayNumber - 1;
      if (state.days[idx]) state.days[idx].custom = action.payload.custom;
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(initChallenge.fulfilled, (_state, action) => {
        return action.payload as ChallengeState;
      })
      .addCase(completeDay.fulfilled, (_state, action) => {
        return action.payload as ChallengeState;
      });
  },
});

export const { setLevel, setNote, setCustom } = challengeSlice.actions;
export default challengeSlice.reducer;


