import { api, loadPersistedToken, setAuthToken, STORAGE_KEYS } from '@/services/api';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';

export type Gender = 'male' | 'female' | '';

export type UserProfile = {
  name?: string;
  email?: string;
  gender?: Gender;
  birthDate?: string;
  weight?: string;
  height?: string;
  avatar?: string | null;
  dailyStepsGoal?: number; // 每日步数目标（用于 Explore 页等）
  dailyCaloriesGoal?: number; // 每日卡路里消耗目标
  pilatesPurposes?: string[]; // 普拉提目的（多选）
};

export type UserState = {
  token: string | null;
  profile: UserProfile;
  loading: boolean;
  error: string | null;
  privacyAgreed: boolean;
};

export const DEFAULT_MEMBER_NAME = '普拉提星球学员';

const initialState: UserState = {
  token: null,
  profile: {
    name: DEFAULT_MEMBER_NAME,
  },
  loading: false,
  error: null,
  privacyAgreed: false,
};

export type LoginPayload = Record<string, any> & {
  // 可扩展：用户名密码、Apple 身份、短信验证码等
  username?: string;
  password?: string;
  appleIdentityToken?: string;
};

export const login = createAsyncThunk(
  'user/login',
  async (payload: LoginPayload, { rejectWithValue }) => {
    try {
      let data: any = null;
      // 若为 Apple 登录，走新的后端接口 /api/users/auth/apple/login
      if (payload.appleIdentityToken) {
        const appleToken = payload.appleIdentityToken;
        // 智能尝试不同 DTO 键名（identityToken / idToken）以提升兼容性
        const candidates = [
          { identityToken: appleToken },
          { idToken: appleToken },
        ];
        let lastError: any = null;
        for (const body of candidates) {
          try {
            data = await api.post('/api/users/auth/apple/login', body);
            lastError = null;
            break;
          } catch (err: any) {
            lastError = err;
            // 若为 4xx 尝试下一个映射；其他错误直接抛出
            const status = (err as any)?.status;
            if (status && status >= 500) throw err;
          }
        }
        if (!data && lastError) throw lastError;
      } else {
        // 其他登录（如游客/用户名密码）保持原有 '/api/login'
        data = await api.post('/api/login', payload);
      }

      // 兼容多种返回结构
      const token =
        (data as any).token ??
        (data as any).accessToken ??
        (data as any).access_token ??
        (data as any).jwt ??
        (data as any)?.profile?.token ??
        (data as any)?.user?.token ??
        null;

      const profile: UserProfile | null =
        (data as any).profile ??
        (data as any).user ??
        (data as any).account ??
        (data as any);

      if (!token) throw new Error('登录响应缺少 token');

      await AsyncStorage.setItem(STORAGE_KEYS.authToken, token);
      await AsyncStorage.setItem(STORAGE_KEYS.userProfile, JSON.stringify(profile ?? {}));
      await setAuthToken(token);

      return { token, profile } as { token: string; profile: UserProfile };
    } catch (err: any) {
      const message = err?.message ?? '登录失败';
      return rejectWithValue(message);
    }
  }
);

export const rehydrateUser = createAsyncThunk('user/rehydrate', async () => {
  const [token, profileStr, privacyAgreedStr] = await Promise.all([
    loadPersistedToken(),
    AsyncStorage.getItem(STORAGE_KEYS.userProfile),
    AsyncStorage.getItem(STORAGE_KEYS.privacyAgreed),
  ]);
  await setAuthToken(token);
  let profile: UserProfile = {};
  if (profileStr) {
    try { profile = JSON.parse(profileStr) as UserProfile; } catch { profile = {}; }
  }
  const privacyAgreed = privacyAgreedStr === 'true';
  return { token, profile, privacyAgreed } as { token: string | null; profile: UserProfile; privacyAgreed: boolean };
});

export const setPrivacyAgreed = createAsyncThunk('user/setPrivacyAgreed', async () => {
  await AsyncStorage.setItem(STORAGE_KEYS.privacyAgreed, 'true');
  return true;
});

export const logout = createAsyncThunk('user/logout', async () => {
  await Promise.all([
    AsyncStorage.removeItem(STORAGE_KEYS.authToken),
    AsyncStorage.removeItem(STORAGE_KEYS.userProfile),
    AsyncStorage.removeItem(STORAGE_KEYS.privacyAgreed),
  ]);
  await setAuthToken(null);
  return true;
});

// 拉取最新用户信息
export const fetchMyProfile = createAsyncThunk('user/fetchMyProfile', async (_, { rejectWithValue }) => {
  try {
    // 固定使用后端文档的接口：/api/users/info
    const data: any = await api.get('/api/users/info');
    console.log('fetchMyProfile', data);
    const profile: UserProfile = (data as any).profile ?? (data as any).user ?? (data as any).account ?? (data as any);
    await AsyncStorage.setItem(STORAGE_KEYS.userProfile, JSON.stringify(profile ?? {}));
    return profile;
  } catch (err: any) {
    const message = err?.message ?? '获取用户信息失败';
    return rejectWithValue(message);
  }
});

const userSlice = createSlice({
  name: 'user',
  initialState,
  reducers: {
    updateProfile(state, action: PayloadAction<Partial<UserProfile>>) {
      state.profile = { ...(state.profile ?? {}), ...action.payload };
    },
    setDailyStepsGoal(state, action: PayloadAction<number>) {
      state.profile = { ...(state.profile ?? {}), dailyStepsGoal: action.payload };
    },
    setDailyCaloriesGoal(state, action: PayloadAction<number>) {
      state.profile = { ...(state.profile ?? {}), dailyCaloriesGoal: action.payload };
    },
    setPilatesPurposes(state, action: PayloadAction<string[]>) {
      state.profile = { ...(state.profile ?? {}), pilatesPurposes: action.payload };
    },
  },
  extraReducers: (builder) => {
    builder
      .addCase(login.pending, (state) => { state.loading = true; state.error = null; })
      .addCase(login.fulfilled, (state, action) => {
        state.loading = false;
        state.token = action.payload.token;
        state.profile = action.payload.profile;
        if (!state.profile?.name || !state.profile.name.trim()) {
          state.profile.name = DEFAULT_MEMBER_NAME;
        }
      })
      .addCase(login.rejected, (state, action) => {
        state.loading = false;
        state.error = (action.payload as string) ?? '登录失败';
      })
      .addCase(rehydrateUser.fulfilled, (state, action) => {
        state.token = action.payload.token;
        state.profile = action.payload.profile;
        state.privacyAgreed = action.payload.privacyAgreed;
        if (!state.profile?.name || !state.profile.name.trim()) {
          state.profile.name = DEFAULT_MEMBER_NAME;
        }
      })
      .addCase(fetchMyProfile.fulfilled, (state, action) => {
        state.profile = action.payload || {};
        if (!state.profile?.name || !state.profile.name.trim()) {
          state.profile.name = DEFAULT_MEMBER_NAME;
        }
      })
      .addCase(fetchMyProfile.rejected, (state, action) => {
        // 不覆盖现有资料，仅记录错误
        state.error = (action.payload as string) ?? '获取用户信息失败';
      })
      .addCase(logout.fulfilled, (state) => {
        state.token = null;
        state.profile = {};
        state.privacyAgreed = false;
      })
      .addCase(setPrivacyAgreed.fulfilled, (state) => {
        state.privacyAgreed = true;
      });
  },
});

export const { updateProfile, setDailyStepsGoal, setDailyCaloriesGoal, setPilatesPurposes } = userSlice.actions;
export default userSlice.reducer;


