import { request } from 'utils/fetch';
import { api } from 'constants/config';
import { publickey } from 'constants/publickey';
import message from 'components/message';
import { actionTypes } from 'constants/action-types';
import { UserState } from './user.types';
import { Dispatch } from 'redux';
import { RootState } from 'models';
import cloneDeep from 'lodash/cloneDeep';
import JSEncrypt from 'jsencrypt/bin/jsencrypt';
import { auths } from 'constants/authority';

const encryptor = new JSEncrypt();
encryptor.setPublicKey(publickey);

export function updateCaptcha() {
  return async (dispatch: Dispatch, getState: () => RootState) => {
    // 切换验证码
    // TODO loginCaptcha
    const result = await request(api.loginCaptcha, undefined, undefined, undefined);

    return result;
  };
}

export function getUserInfo() {
  return async (dispatch: Dispatch, getState: () => RootState) => {
    const { user } = getState();
    const islocal = window.appConfig.LOCAL;
    const { userInfo = {} } = user;
    if (userInfo?.userId) {
      return userInfo;
    }

    let code;
    const result = await request(api.userGet, undefined, undefined, undefined, {
      error: () => {
        // 为选择租户
        code = 1;
      }
    });

    let userResult = cloneDeep(result) as UserState['userInfo'];
    let isAdmin = false;
    let isRenew = false;
    let isPerson = false;
    let userType = '';
    let authority = [];
    if (!islocal && result) {
      const resultUserInfo = await request(api.userInfo, undefined, undefined, undefined, {
        error: () => {
          message.error('获取用户信息失败');
        }
      });
      userType = resultUserInfo.type;
      const permissionList = await request(api.usersMePermissions, undefined, undefined, undefined);
      const t = Date.now();
      const permissions = permissionList?.filter((e) => e.type === 1 && new Date(e.expiredAt).getTime() > t) || [];
      isRenew = resultUserInfo?.currentAccountRenewable;
      userResult = {
        ...userResult,
        skuId: permissions.sort((a, b) => b.id - a.id)[0].id,
        isRenew
      };
      isPerson = userResult.skuId ? [7, 8].includes(userResult.skuId) : false;
      isAdmin = userResult.isAccountOwner || permissionList?.filter((e) => e.type === 0 && e.introduction === '管理员权限').length > 0;
      const authKey = userResult.edition?.id || '';
      authority = auths[authKey];
    }

    if (islocal) {
      isAdmin = userResult.isAccountOwner ?? false;
      if (userResult.type === 'lifelong') {
        userResult = {
          ...userResult,
          type: 'enterprise'
        };
      }
      const authKey = userResult.type;
      if (authKey) {
        authority = auths[authKey];
      }
    }

    // 拿到用户信息，且拥有产品权限
    if (result) {
      // 用户锁定时跳转缺省页
      if (result.isLocked) {
        window.location.href = BASENAME + '/userLock';
        return;
      }
      dispatch({
        type: actionTypes.GET_USER_INFO,
        payload: {
          userInfo: userResult,
          isAdmin,
          isRenew,
          isRoot: userResult.role === 2,
          isPerson,
          authority,
          userType
        }
      });
      return result;
    } else {
      // 没有产品权限的时候会引导用户到落地页sku页面，引导购买
      // window.location.href = window.appConfig.HOME_URL + '/overdue';
    }

    return code;
  };
}

export function getTenants(name = '') {
  return async (dispatch: Dispatch) => {
    const result = await request(api.userTenants, undefined, { name: name, limit: 999 });

    if (result) {
      dispatch({
        type: actionTypes.GET_TENANTS,
        payload: result
      });
    }

    return result;
  };
}

export function loginOut() {
  return async (dispatch: Dispatch) => {
    localStorage.removeItem('spaceId');
    localStorage.removeItem('migrate');
    if (window.appConfig.USER_ENV === 'op') {
      window.location.href = '/logout';
    } else {
      const result = await request(api.userLogout, { id: 'self' });

      if (result) {
        dispatch({
          type: actionTypes.LOGIN_OUT,
          payload: {
            userInfo: {}
          }
        });

        window.location.href = window.appConfig.LOGOUT_URL ? window.appConfig.LOGOUT_URL : '/login';
      }

      return result;
    }
  };
}

export function login(param, callback, onError) {
  return async () => {
    const result = await request(
      api.userLogin,
      undefined,
      undefined,
      JSON.stringify({
        username: param.name,
        code: param.code,
        svg: param.svg,
        password: encryptor.encrypt(param.password)
      })
    );

    if (result) {
      callback && callback();
    } else {
      onError?.();
    }

    return result;
  };
}

export function getUsers() {
  return async (dispatch: Dispatch) => {
    const result = await request(api.userList, undefined, { limit: 999 });

    if (result) {
      dispatch({
        type: actionTypes.GET_USERS,
        payload: result
      });
    }

    return result;
  };
}

export function changeUsersPage(page) {
  return {
    type: actionTypes.USERS_PAGE_CHANGE,
    payload: page
  };
}

export function searchUsers(search) {
  return {
    type: actionTypes.USERS_SEARCH,
    payload: search
  };
}

export function resetUsers() {
  return {
    type: actionTypes.USERS_RESET
  };
}

export function createUser(param, callback) {
  return async (dispatch: Dispatch) => {
    const result = await request(
      api.userCreate,
      undefined,
      undefined,
      JSON.stringify({
        username: param.name,
        password: encryptor.encrypt(param.password),
        spaceId: param.spaceId
      })
    );

    if (result) {
      dispatch({
        type: actionTypes.USER_CREATE,
        payload: {
          ...param,
          ...result
        }
      });
      callback && callback();
    }
  };
}

export function deleteUser(id) {
  return async (dispatch: Dispatch) => {
    const result = await request(api.userDelete, { id });

    if (result) {
      message.success('用户移除成功');
      dispatch({
        type: actionTypes.USER_DELETE,
        payload: id
      });
      return result;
    }
    message.error('用户移除失败');
    return result;
  };
}

export function resetPassword(id) {
  return async () => {
    const result = await request(api.userReset, { id }, undefined, JSON.stringify({ password: encryptor.encrypt('abc1234') }));

    if (result) {
      message.success('重置密码成功，初始密码为abc1234');
    }

    return result;
  };
}

export function editPassword(values, callback) {
  return async () => {
    const result = await request(
      api.userEdit,
      { id: values.id },
      undefined,
      JSON.stringify({ oldPwd: encryptor.encrypt(values.oldPassword), newPwd: encryptor.encrypt(values.newPassword) })
    );

    if (result) {
      callback && callback(result);
      message.success('修改成功');
      return result;
    } else {
      message.error('修改失败');
      return result;
    }
  };
}

export function switchUser(id, callback) {
  return async () => {
    const result = await request(api.userSwitch, undefined, undefined, JSON.stringify({ tenantId: id }));

    if (result) {
      callback && callback();
    }

    return result;
  };
}

export function updateNonentityModule(id) {
  return async (dispatch: Dispatch) => {
    dispatch({
      type: actionTypes.USER_NONENTITY_MODULE,
      payload: id
    });
  };
}

const initialState: UserState = {
  userInfo: {},
  nonentityModule: [],
  tenants: [],
  users: {
    search: '',
    page: 1,
    pageSize: 20,
    list: []
  },
  isAdmin: false,
  isRoot: false,
  isRenew: false,
  isPerson: false,
  authority: []
};

export default function reducer(state = initialState, { type, payload }): UserState {
  switch (type) {
    case actionTypes.GET_TENANTS: {
      return { ...state, tenants: payload };
    }
    case actionTypes.GET_USER_INFO: {
      return {
        ...state,
        userInfo: { ...state.userInfo, ...payload.userInfo },
        isAdmin: payload.isAdmin,
        isRoot: payload.isRoot,
        isRenew: payload.isRenew,
        isPerson: payload.isPerson,
        userType: payload.userType,
        authority: payload.authority
      };
    }
    case actionTypes.LOGIN_OUT: {
      return { ...state, userInfo: { ...state.userInfo, ...payload.userInfo } };
    }
    case actionTypes.GET_USERS: {
      const rootUser = payload.filter((d) => d.id === 1);
      const users = payload.filter((d) => d.id !== 1);
      const newList = rootUser.concat(users);
      return {
        ...state,
        users: {
          ...state.users,
          list: newList
        }
      };
    }
    case actionTypes.USER_NONENTITY_MODULE: {
      return {
        ...state,
        nonentityModule: [payload, ...state.nonentityModule]
      };
    }
    case actionTypes.USERS_PAGE_CHANGE: {
      return { ...state, users: { ...state.users, page: payload } };
    }
    case actionTypes.USERS_SEARCH: {
      return { ...state, users: { ...state.users, search: payload } };
    }
    case actionTypes.USERS_RESET: {
      return { ...state, users: { ...state.users, search: '', page: 1 } };
    }
    case actionTypes.USER_CREATE: {
      const rootUser = state.users.list.filter((d) => d.id === 1);
      const users = state.users.list.filter((d) => d.id !== 1);
      const newList = rootUser.concat(payload).concat(users);
      return { ...state, users: { ...state.users, list: newList } };
    }
    case actionTypes.USER_DELETE: {
      const rootUser = state.users.list.filter((d) => d.id === 1);
      const deletedUsers = state.users.list.filter((d) => d.id !== 1 && d.id != payload);
      const newList = rootUser.concat(deletedUsers);
      return { ...state, users: { ...state.users, list: newList } };
    }
    default:
      return state;
  }
}
