package com.mmc.iuav.user.service.impl;

import com.mmc.iuav.general.CodeUtil;
import com.mmc.iuav.page.PageResult;
import com.mmc.iuav.response.ResultBody;
import com.mmc.iuav.response.ResultEnum;
import com.mmc.iuav.user.auth.PwdUtil;
import com.mmc.iuav.user.dao.CooperationDao;
import com.mmc.iuav.user.dao.UserServiceDao;
import com.mmc.iuav.user.entity.CooperationTagDO;
import com.mmc.iuav.user.entity.UserAccountDO;
import com.mmc.iuav.user.entity.UserRcdDO;
import com.mmc.iuav.user.entity.UserTagDO;
import com.mmc.iuav.user.model.dto.UserAccountSimpleDTO;
import com.mmc.iuav.user.model.qo.BUserAccountQO;
import com.mmc.iuav.user.model.qo.UserAccountQO;
import com.mmc.iuav.user.model.vo.BUserAccountVO;
import com.mmc.iuav.user.model.vo.CompanyAuthVO;
import com.mmc.iuav.user.model.vo.UserAccountVO;
import com.mmc.iuav.user.service.CompanyAuthService;
import com.mmc.iuav.user.service.UserAccountService;
import com.mmc.iuav.user.service.WxService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: zj
 * @Date: 2023/5/16 13:48
 */
@Service
public class UserAccountServiceImpl implements UserAccountService {

    @Autowired
    private UserServiceDao userServiceDao;

    @Autowired
    private CompanyAuthService companyAuthService;

    @Autowired
    private CooperationDao cooperationDao;

    @Autowired
    private WxService wxService;

    @Override
    public UserAccountVO getUserAccountInfoByUnionId(String unionId) {
        UserAccountDO userAccountDO = userServiceDao.getUserAccountInfoByUnionId(unionId);
        if (userAccountDO != null) {
            return userAccountDO.buildUserAccountVO();
        }
        return null;
    }

    @Override
    public void insertUserAccount(UserAccountDO userAccountDO) {
        userServiceDao.insertUserAccount(userAccountDO);
    }

    @Override
    public UserAccountVO getUserAccountById(Integer userAccountId) {
        UserAccountDO userAccountDO = userServiceDao.getUserAccountById(userAccountId);
        if (userAccountDO == null) {
            return null;
        }
        UserAccountVO userAccountVO = userAccountDO.buildUserAccountVO();
        CompanyAuthVO companyAuthVO = companyAuthService.getCompanyAuthByUId(userAccountId);
        if (companyAuthVO != null) {
            userAccountVO.setCompanyAuthStatus(companyAuthVO.getAuthStatus());
        }else {
            userAccountVO.setCompanyAuthStatus(0);
        }
        UserTagDO userTag = cooperationDao.getUserTag(userAccountId);
        if (userTag != null){
            userAccountVO.setCooperationTagId(userTag.getCooperationTagId());
        }
        return userAccountVO;
    }

    @Override
    public ResultBody update(UserAccountVO userAccountVO) {
        UserAccountDO userAccountDO = new UserAccountDO(userAccountVO);
        userServiceDao.update(userAccountDO);
        return ResultBody.success();
    }

    @Override
    public UserAccountSimpleDTO getUserSimpleInfo(Integer userAccountId) {
        UserAccountDO userAccountDO = userServiceDao.getUserAccountById(userAccountId);
        if (userAccountDO == null){
            return null;
        }
        UserAccountSimpleDTO userAccountSimpleDTO = userAccountDO.buildUserAccountSimpleDTO();
        CompanyAuthVO companyAuthVO = companyAuthService.getCompanyAuthByUId(userAccountId);
        if (companyAuthVO != null) {
            userAccountSimpleDTO.setCompanyAuthStatus(companyAuthVO.getAuthStatus());
        }else {
            userAccountSimpleDTO.setCompanyAuthStatus(0);
        }
        UserTagDO userTag = cooperationDao.getUserTag(userAccountId);
        if (userTag != null){
            userAccountSimpleDTO.setCooperationTagId(userTag.getCooperationTagId());
        }
        return userAccountSimpleDTO;
    }

    @Override
    public List<Integer> feignListUserAccountIds(Integer provinceCode, Integer cityCode, Integer districtCode) {
        List<Integer> ids = userServiceDao.listUserAccountIdsByDistrictCode(provinceCode, cityCode, districtCode);
        return ids;
    }

    @Override
    public ResultBody insertBAccount(BUserAccountVO bUserAccountVO) {
        if (!bUserAccountVO.getPassWord().equals(bUserAccountVO.getAlertPwd())) {
            // 两次密码不一致
            return ResultBody.error(ResultEnum.PWD_ALERT_ERROR);
        }
        // 获取新增的账户名是否已经存在
        int count = userServiceDao.countUserAccountNo(null, bUserAccountVO.getAccountNo());
        if (count > 0) {
            return ResultBody.error(ResultEnum.ADD_USER_ACCOUNT_NAME_EXISTS);
        }
        UserAccountDO userAccountDO = new UserAccountDO(bUserAccountVO);
        try {
            userAccountDO.setPassword(PwdUtil.securityPwd(bUserAccountVO.getPassWord()));
        } catch (NoSuchAlgorithmException e) {
            return ResultBody.error(ResultEnum.PWD_CREATE_ERROR);
        }

        userAccountDO.setUid(CodeUtil.generateUserUID());
        userAccountDO.setAccountType(0);
        userAccountDO.setPortType(0);
        userAccountDO.setOpenId(userAccountDO.getUid());
        userAccountDO.setUnionId(userAccountDO.getUid());
        userServiceDao.insertUserAccount(userAccountDO);
        return ResultBody.success();
    }

    @Override
    public ResultBody removeBAccount(Integer userAccountId) {
        String removeNO = CodeUtil.removeUserAccount();
        userServiceDao.removeUserAccount(removeNO, userAccountId);
        return ResultBody.success();
    }

    @Override
    public ResultBody listBAccountPage(BUserAccountQO param) {
        int count = userServiceDao.countListBAccountPage(param);
        if (count == 0) {
            return ResultBody.success(PageResult.buildPage(param.getPageNo(), param.getPageSize(), count));
        }
        Integer pageNo = param.getPageNo();
        param.buildCurrentPage();
        List<UserAccountDO> users = userServiceDao.listBAccountPage(param);
        List<UserAccountVO> collect = users.stream().map(UserAccountDO::buildUserAccountVO).collect(Collectors.toList());
        return ResultBody.success(PageResult.buildPage(pageNo, param.getPageSize(), count, collect));
    }

    @Override
    public UserAccountDO getUserLoginInfo(String accountNo, String passWord) {
        UserAccountDO userAccountDO = userServiceDao.getUserLoginInfo(accountNo, passWord);
        return userAccountDO;
    }

    @Override
    public List<UserAccountSimpleDTO> feignListBAccountPage(BUserAccountQO bUserAccountQO) {
        List<UserAccountDO> list = userServiceDao.feignListBAccountPage(bUserAccountQO);
        if (list == null) {
            return null;
        }
        List<UserAccountSimpleDTO> accountSimpleDTOS = list.stream().map(UserAccountDO::buildUserAccountSimpleDTO).collect(Collectors.toList());
        return accountSimpleDTOS;
    }

    @Override
    public ResultBody updateBAccount(BUserAccountVO bUserAccountVO) {
        // 判断账号是否重复
        if (!StringUtils.isEmpty(bUserAccountVO.getAccountNo())) {
            // 如果传入的名字不为空，就查找数据库，看名字是否重复
            int count = userServiceDao.countUserAccountNo(bUserAccountVO.getId(), bUserAccountVO.getAccountNo());
            if (count > 0) {
                return ResultBody.error(ResultEnum.UPDATE_USER_ACCOUNT_REPEAT);
            }
        }
        UserAccountDO userAccountDO = new UserAccountDO(bUserAccountVO);
        userServiceDao.update(userAccountDO);
        return ResultBody.success();
    }

    @Override
    public ResultBody updatePassword(BUserAccountVO account) {
        if (!account.getPassWord().equals(account.getAlertPwd())) {
            return ResultBody.error(ResultEnum.PASSWORD_INCONSISTENT);
        }
        try {
            account.setPassWord(PwdUtil.securityPwd(account.getPassWord()));
            userServiceDao.updatePassword(account.getId(), account.getPassWord());
        } catch (NoSuchAlgorithmException e) {
            return ResultBody.error(ResultEnum.PWD_CONPARED_ERROR);
        }
//        RoleInfoDO roleInfo = roleInfoDao.getRoleInfoByUser(account.getId());// 查询账号的角色信息
//        this.disableOneToken(account.getId(), roleInfo.getId(), JwtConstant.SXTB_ACCOUNT_TOKEN);
        return ResultBody.success();
    }

    @Override
    public ResultBody feignAuthUserPwd(Integer id, String authPwd) {
        UserAccountDO account = userServiceDao.getUserAuthPwdInfo(id);
        if (account == null) {
            return ResultBody.error(ResultEnum.LOGIN_ACCOUNT_NOT_EXIT_ERROR);
        }
        String pwd = "";
        try {
            pwd = PwdUtil.securityPwd(authPwd);
        } catch (NoSuchAlgorithmException e) {
            return ResultBody.error(ResultEnum.PWD_CREATE_ERROR);
        }
        if (!pwd.equals(account.getPassword())) {
            return ResultBody.error(ResultEnum.PWD_CONPARED_ERROR);
        }
        return ResultBody.success();
    }

    @Override
    public ResultBody getUserPhoneNumber(Integer id, String code) {
        String userPhoneNumber = wxService.getUserPhoneNumber(id, code);
        if (StringUtils.isBlank(userPhoneNumber)){
            return ResultBody.error(ResultEnum.AUTH_PHONE_NUMBER_ERROR);
        }
        UserAccountDO userAccount = new UserAccountDO();
        userAccount.setId(id);
        userAccount.setPhoneNum(userPhoneNumber);
        userServiceDao.update(userAccount);
        return ResultBody.success();
    }

    @Override
    public List<UserAccountSimpleDTO> feignListUserAccountByIds(List<Integer> ids) {
        List<UserAccountDO> userAccountDOS = userServiceDao.listUserAccountByIds(ids);
        if (!CollectionUtils.isEmpty(userAccountDOS)){
            List<UserAccountSimpleDTO> userAccountSimpleDTOS = userAccountDOS.stream().map(UserAccountDO::buildUserAccountSimpleDTO).collect(Collectors.toList());
            return userAccountSimpleDTOS;
        }
        return null;
    }

    @Override
    public List<UserAccountSimpleDTO> feignListRcdUserInfo(List<Integer> userIds) {
        List<UserAccountDO> userAccountDOS = userServiceDao.feignListRcdUserInfo(userIds);
        if (!CollectionUtils.isEmpty(userAccountDOS)){
            List<UserAccountSimpleDTO> userAccountSimpleDTOS = userAccountDOS.stream().map(UserAccountDO::buildUserAccountSimpleDTO).collect(Collectors.toList());
            return userAccountSimpleDTOS;
        }
        return null;
    }

    @Override
    public Integer feignGetSuperiorRef(Integer userAccountId) {
        UserRcdDO userRcdDO = userServiceDao.getUserRcdDO(userAccountId);
        if (userRcdDO != null){
            return userRcdDO.getId();
        }
        return null;
    }

    @Override
    public UserAccountSimpleDTO feignGetUserRcdInfo(Integer userAccountId) {
        UserAccountDO rcdAccountDO = userServiceDao.getUserRcdByAccountId(userAccountId);
        if (rcdAccountDO != null){
            return rcdAccountDO.buildUserAccountSimpleDTO();
        }
        return null;
    }

    @Override
    public ResultBody listAppUser(UserAccountQO param) {
        int count = userServiceDao.countListAppUser(param);
        if (count == 0){
            return ResultBody.success(PageResult.buildPage(param.getPageNo(), param.getPageSize(), count));
        }
        int pageNo = param.getPageNo();
        param.buildCurrentPage();
        List<UserAccountDO> userAccountDOList = userServiceDao.listAppUser(param);
        List<UserAccountDO> res = buildTagInfo(userAccountDOList);
        List<UserAccountVO> userAccountVOS = res.stream().map(UserAccountDO::buildUserAccountVO).collect(Collectors.toList());
        return ResultBody.success(PageResult.buildPage(pageNo, param.getPageSize(), count, userAccountVOS));
    }

    private List<UserAccountDO> buildTagInfo(List<UserAccountDO> userAccountDOList) {
        List<CooperationTagDO> cooperationTagDOS = cooperationDao.listTags();
        Map<Integer, CooperationTagDO> cooperationTagDOMap = cooperationTagDOS.stream().collect(Collectors.toMap(CooperationTagDO::getId, d -> d, (k1, k2) -> k2));
        for (UserAccountDO userAccountDO : userAccountDOList) {
            CooperationTagDO cooperationTagDO = cooperationTagDOMap.get(userAccountDO.getCooperationTagId());
            if (cooperationTagDO != null){
                userAccountDO.setTagName(cooperationTagDO.getTagName());
            }
        }
        return userAccountDOList;
    }


}
