import Taro from '@tarojs/taro';

import { CacheKey } from '@/constants/cache-key';
import http from '@/http';
import { API } from '@/http/api';
import store from '@/store';
import { setUserInfo, setBindPhone } from '@/store/actions';
import { selectUserInfo } from '@/store/selector';
import {
  FollowGroupRequest,
  SetPhoneRequest,
  UpdateUserInfoRequest,
  UpdateUserInfoResponse,
  UserInfo,
} from '@/types/user';
import { logWithPrefix } from '@/utils/common';
import Toast from '@/utils/toast';

let lastOpenMiniProgramTime: number | null = null;
const SHOW_LOGIN_GUIDE_OFFSET = 1 * 60 * 60 * 1000;
// const SHOW_LOGIN_GUIDE_OFFSET = 60 * 1000;
// const SHOW_MATERIAL_GUIDE_OFFSET = 1 * 1000;
const log = logWithPrefix('user-utils');
let showLoginGuide: boolean | null = null;

export const getUserInfo = () => selectUserInfo(store.getState());

export const getUserId = () => getUserInfo().userId;

// 无效则说明还没拉到数据
export const isValidUserInfo = (info: UserInfo) => !!info.userId;

export const isNeedLogin = (info: UserInfo) => !info.isBindPhone;
// export const isNeedLogin = (info: UserInfo) => !info.isBindPhone || info.userId === '534740874077898752';

export const updateLastLoginTime = () => {
  lastOpenMiniProgramTime = Taro.getStorageSync<number>(CacheKey.LAST_OPEN_MINI_PROGRAM_TIME) ?? null;
  const now = Date.now();
  log(`updateLastLoginTime: lastOpenMiniProgramTime=${lastOpenMiniProgramTime}, now=${now}`);
  Taro.setStorageSync(CacheKey.LAST_OPEN_MINI_PROGRAM_TIME, now);
};

/**
 * 登录引导
 * 非首次打开小程序后，如果没有绑定手机号，在打开小程序时自动弹出一次
 * 指定时间间隔内只出现一次
 * @param info
 * @returns
 */
export const shouldShowLoginGuide = (info: UserInfo) => {
  // if (1 < 2) {
  //   return true;
  // }
  if (!isValidUserInfo(info) || !isNeedLogin(info)) {
    return false;
  }
  if (typeof showLoginGuide === 'boolean') {
    return showLoginGuide;
  }
  if (!lastOpenMiniProgramTime) {
    // 第一次打开不强制提示
    showLoginGuide = false;
  } else {
    showLoginGuide = Date.now() - lastOpenMiniProgramTime > SHOW_LOGIN_GUIDE_OFFSET;
  }
  return showLoginGuide;
};

// export const shouldShowLoginDialog = (info: UserInfo) => {
//   if (!isValidUserInfo(info) || !isNeedLogin(info)) {
//     return false;
//   }
//   const cache = Taro.getStorageSync<boolean>(CacheKey.SHOW_LOGIN_DIALOG);
//   return !cache;
// };

// export const setAlreadyShowLoginDialog = () => Taro.setStorageSync(CacheKey.SHOW_LOGIN_DIALOG, '1');

export const isNeedCreateMaterial = async () => {
  let info = getUserInfo();
  if (!isValidUserInfo(info)) {
    info = await requestUserInfo();
  }
  return !info.isCreateResume;
};

export const ensureUserInfo = async (info: UserInfo, toast = true) => {
  if (!isValidUserInfo(info)) {
    try {
      await requestUserInfo();
    } catch (e) {
      toast && Toast.error('请稍后再试');
      return false;
    }
  }
  return true;
};

export const dispatchUpdateUser = (userInfo: Partial<UserInfo>) => store.dispatch(setUserInfo(userInfo));

export async function requestUserInfo() {
  const userInfo = await http.post<UserInfo>(API.USER);
  dispatchUpdateUser(userInfo);
  return userInfo;
}

export async function setPhoneNumber(params: SetPhoneRequest) {
  try {
    await http.post<string>(API.SET_PHONE, { data: params });
    store.dispatch(setBindPhone(true));
  } catch (e) {
    Taro.showToast({ title: '绑定失败', icon: 'error' });
  }
}

export async function updateUserInfo(params: Omit<UpdateUserInfoRequest, 'userId'>) {
  try {
    const data = { ...params, userId: getUserId() };
    const {
      avatarUrl,
      nickName,
      imAcctNo = params.imAcctNo,
    } = await http.post<UpdateUserInfoResponse>(API.USER_UPDATE, { data });
    const userInfoPayload: Partial<UserInfo> = { imAcctNo };
    if (avatarUrl) {
      userInfoPayload.avatarUrl = avatarUrl;
      userInfoPayload.isDefaultAvatar = false;
    }
    if (nickName) {
      userInfoPayload.nickName = nickName;
      userInfoPayload.isDefaultNickname = false;
    }
    store.dispatch(setUserInfo(userInfoPayload));
  } catch (e) {
    Taro.showToast({ title: '更新失败', icon: 'error' });
  }
}

export async function followGroup(blGroupId: FollowGroupRequest['blGroupId']) {
  try {
    const data: FollowGroupRequest = { blGroupId, userId: getUserId() };
    await http.post(API.FOLLOW_GROUP, { data });
    return true;
  } catch (e) {
    Taro.showToast({ title: '出错了，请重试', icon: 'error' });
    return false;
  }
}
