package cn.com.ty.lift.system.user.service.impl;

import cn.com.ty.lift.common.constants.ApiConstants;
import cn.com.ty.lift.common.constants.CommonEnum;
import cn.com.ty.lift.common.utils.ProjectUtils;
import cn.com.ty.lift.system.settings.dao.entity.MaintenanceCompany;
import cn.com.ty.lift.system.settings.service.IMaintenanceCompanyService;
import cn.com.ty.lift.system.user.dao.entity.*;
import cn.com.ty.lift.system.user.dao.entity.model.*;
import cn.com.ty.lift.system.user.service.*;
import cn.com.ty.lift.system.utils.PasswordUtils;
import cn.com.xwy.boot.web.dto.RestResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author huangyuan
 * @date 2019-11-29
 * @description 用户接口
 */
@Service
public class UserService implements IUserService {

    @Resource
    private IUserAccountService userAccountService;

    @Resource
    private IUserInfoService userInfoService;

    @Resource
    private IMtCompanyUserService mtCompanyUserService;

    @Resource
    private IRoleService roleService;

    @Resource
    private IMenuService menuService;

    @Resource
    private IMaintenanceCompanyService maintenanceCompanyService;

    @Resource
    private IProjectService projectService;

    @Resource
    private ILoginService loginService;

    @Resource
    private IUserRoleService userRoleService;

    @Override
    @Transactional
    public UserAccount saveUserInfo(UserRequest userRequest) {
        String password = userRequest.getPassword();
        UserAccount userAccount = new UserAccount();
        userAccount.setMobile(userRequest.getMobile());
        //设置账号(小梯号)
        userAccount.setAccount(userRequest.getAccount());
        userAccount.setCreateDate(LocalDateTime.now());
        //设置用户类型
        userAccount.setType(ApiConstants.UserConstants.TYPE_USER);
        //判断用户是否为物管端注册用户
        if (ApiConstants.ACCESS_TYPE_PUBLIC == userRequest.getMobileType()) {
            //用户类型设置为物管端用户
            userAccount.setType(ApiConstants.UserConstants.PUBLIC_TYPE_USER);
        }
        //设置用户微信openId
        userAccount.setWechatOpenId(userRequest.getWeChatOpenId());
        UserInfo userInfo = new UserInfo();
        userInfo.setMobile(userRequest.getMobile());
        userInfo.setName(userRequest.getName());

        //前端传递MD5加密密码，然后进行密码加密
        //1.生成16位随机码
        String salt = PasswordUtils.randomCode();
        //2.对密码进行加盐处理，并对加盐的密码进行哈希加密
        password = PasswordUtils.generatePassword(password, salt);
        userAccount.setSalt(salt);
        userAccount.setPassword(password);

        //保存用户账户
        boolean insertAccountFlag = userAccountService.save(userAccount);
        //保存用户信息
        userInfo.setUserId(userAccount.getUserId());
        boolean insertInfoFlag = userInfoService.save(userInfo);
        if (!insertAccountFlag || !insertInfoFlag) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return null;
        }
        return userAccount;
    }

    @Override
    public RestResponse list(UserRequest userRequest) {
        IPage userAccountPage = new Page<>(userRequest.getPageNum(), userRequest.getPageSize());
        userAccountPage = userAccountService.page(userAccountPage, new QueryWrapper<UserAccount>()
                //通过用户名模糊查询
                .like(StringUtils.isNotBlank(userRequest.getQueryCondition()), "account",
                        userRequest.getQueryCondition())
                .or()
                //通过用户手机号模糊查询
                .like(StringUtils.isNotBlank(userRequest.getQueryCondition()), "mobile",
                        userRequest.getQueryCondition())
                .eq("delete_flag", ApiConstants.DELETE_NO)
        );
        List<UserAccount> userAccountList = userAccountPage.getRecords();
        if (userAccountList != null && userAccountList.size() > 0) {
            List<Long> userIdList = ProjectUtils.getAttrList(userAccountList, "userId", null);
            Map<Long, UserInfo> userIdToUserInfo = userInfoService.userIdToInfo(userIdList);
            List<UserResponse> userResponseList = new ArrayList<>(10);
            if (userIdToUserInfo != null && userIdToUserInfo.size() > 0) {
                userAccountList.forEach(userAccount -> {
                    UserResponse userResponse = new UserResponse();
                    UserInfo userInfo = userIdToUserInfo.get(userAccount.getUserId());
                    userResponse.setUserId(userAccount.getUserId());
                    userResponse.setName(userInfo.getName());
                    userResponse.setMobile(userInfo.getMobile());
                    userResponse.setCreateTime(userAccount.getCreateDate());
                    userResponseList.add(userResponse);
                });
            }
            userAccountPage.setRecords(userResponseList);
        }
        return RestResponse.success(userAccountPage, "获取用户信息成功");
    }

    @Override
    public RestResponse addUser(UserRequest userRequest) {
        if (StringUtils.isBlank(userRequest.getMobile())) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "用户手机号为空");
        }
        UserAccount userAccount = userAccountService.getByMobile(userRequest.getMobile());
        if (userAccount != null) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "手机号已经存在");
        }
        //保存用户信息，成功返回用户账户信息，失败返回空
        userAccount = this.saveUserInfo(userRequest);
        if (userAccount == null) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "新增用户失败");
        }
        return RestResponse.success(userAccount, ApiConstants.RESULT_SUCCESS, "新增用户成功");
    }

    @Override
    @Transactional
    public RestResponse updateUser(UserRequest userRequest) {
        UserAccount userAccount = userAccountService.getByUserId(userRequest.getUserId());
        UserInfo userInfo = userInfoService.getByUserId(userRequest.getUserId());
        userAccount.setMobile(userRequest.getMobile());
        userAccount.setAccount(userRequest.getAccount());
        userInfo.setName(userRequest.getName());
        userInfo.setMobile(userRequest.getMobile());
        //重置密码
        if (StringUtils.isNotBlank(userRequest.getPassword())) {
            String salt = PasswordUtils.randomCode();
            String newPassword = PasswordUtils.generatePassword(userRequest.getPassword(), salt);
            userAccount.setSalt(salt);
            userAccount.setPassword(newPassword);
        }
        boolean updateAccountFlag = userAccountService.updateUserAccount(userAccount);
        boolean updateInfoFlag = userInfoService.updateUserInfo(userInfo);
        if (!updateAccountFlag || !updateInfoFlag) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "更新用户信息失败");
        }
        return RestResponse.success(null, ApiConstants.RESULT_SUCCESS, "更新用户信息成功");
    }

    @Override
    @Transactional
    public RestResponse deleteUser(UserRequest userRequest) {
        UserAccount userAccount = userAccountService.getByUserId(userRequest.getUserId());
        UserInfo userInfo = userInfoService.getByUserId(userRequest.getUserId());
        if (userAccount != null && userInfo != null) {
            userAccount.setDeleteFlag(ApiConstants.DELETE_YES);
            userInfo.setDeleteFlag(ApiConstants.DELETE_YES);
            boolean updateAccountFlag = userAccountService.updateUserAccount(userAccount);
            boolean updateInfoFlag = userInfoService.updateUserInfo(userInfo);
            if (updateAccountFlag && updateInfoFlag) {
                return RestResponse.success(null, ApiConstants.RESULT_SUCCESS, "删除用户成功");
            }
        }
        return RestResponse.fail(ApiConstants.RESULT_ERROR, "用户不存在无法删除");
    }

    @Override
    public UserResponse getLoginUserInfo(Long userId) {
        UserResponse userResponse = getBaseUserInfo(userId);
        //获取用所在公司列表
        List<MtCompanyUser> mtCompanyUserList = mtCompanyUserService.list(new QueryWrapper<MtCompanyUser>()
                .eq("user_id", userId)
                .eq("status", ApiConstants.ApplicationConstants.APPLY_PASS)
                .eq("delete_flag", ApiConstants.DELETE_NO)
        );
        //获取上一次用户登录公司列表
        List<MtCompanyUser> currentCompanyUserList = mtCompanyUserService.list(new QueryWrapper<MtCompanyUser>()
                .eq("user_id", userId)
                .eq("status", ApiConstants.ApplicationConstants.APPLY_PASS)
                .eq("delete_flag", ApiConstants.DELETE_NO)
                .eq("is_current_company", 1)
        );
        //获取用户所在公司的id列表
        List<Long> companyIds = ProjectUtils.getAttrList(mtCompanyUserList, "mtCompanyId", null);
        if (companyIds.size() > 0) {
            List<MaintenanceCompany> maintenanceCompanyList = (List<MaintenanceCompany>) maintenanceCompanyService.listByIds(companyIds);
            //设置团队成员人数
            maintenanceCompanyService.setCompanyUserNum(maintenanceCompanyList);
            userResponse.setCompanyList(maintenanceCompanyList);
            //用户进入后的默认团队信息
            if (maintenanceCompanyList != null && maintenanceCompanyList.size() > 0) {
                MaintenanceCompany currentCompany = getCurrentCompany(currentCompanyUserList, maintenanceCompanyList);
                mtCompanyUserService.updateLoginCompanyFlag(userId, currentCompany.getId());
                userResponse.setMaintenanceCompany(currentCompany);
                //获取用户在默认团队中的角色信息
                Role role = roleService.getRoleByUserIdAndCompanyId(userId, currentCompany.getId());
                userResponse.setRole(role);
                //获取用户在当前企业下的菜单
                if (role != null) {
                    List<Menu> menus = menuService.getByRoleId(role.getId());
                    menus = menuService.getMenuTree(menus);
                    userResponse.setMenus(menus);
                }
            }
        }
        return userResponse;
    }

    /**
     * @param currentCompanyUserList 用户所在当前公司列表
     * @return 当前公司
     * @description 获取当前公司
     * @date 2020/5/22 3:11 下午
     */
    private MaintenanceCompany getCurrentCompany(List<MtCompanyUser> currentCompanyUserList,
                                                 List<MaintenanceCompany> maintenanceCompanyList) {
        if (currentCompanyUserList != null && currentCompanyUserList.size() > 0) {
            long currentCompanyId = currentCompanyUserList.get(0).getMtCompanyId();
            List<MaintenanceCompany> currentCompanyList = maintenanceCompanyList.stream().filter(maintenanceCompany ->
                    maintenanceCompany.getId() == currentCompanyId).collect(Collectors.toList());
            if (currentCompanyList.size() > 0) {
                return currentCompanyList.get(0);
            }
        }
        return maintenanceCompanyList.get(0);
    }

    @Override
    public Map<Long, UserResponse> getUserResponseByUserIdList(List<Long> userIdList) {
        Map<Long, UserResponse> userIdToUserResponse = new HashMap<>();
        if (userIdList != null && userIdList.size() > 0) {
            //获取用户账号信息
            List<UserAccount> userAccountList = (List<UserAccount>) userAccountService.listByIds(userIdList);
            //获取用户基本信息
            List<UserInfo> userInfoList = (List<UserInfo>) userInfoService.listByIds(userIdList);
            //将数据转化为userId -> 用户信息的map
            Map<Long, UserAccount> userIdToUserAccount = ProjectUtils.attrToObjMap(userAccountList, "userId", null);
            Map<Long, UserInfo> userIdToUserInfo = ProjectUtils.attrToObjMap(userInfoList, "userId", null);
            for (Long userId : userIdList) {
                UserAccount userAccount = userIdToUserAccount.get(userId);
                UserInfo userInfo = userIdToUserInfo.get(userId);
                UserResponse userResponse = new UserResponse();
                userResponse.setUserId(userId);
                if (userAccount != null) {
                    //设置用户手机号和用户类型
                    userResponse.setMobile(userAccount.getMobile());
                    userResponse.setType(userAccount.getType());
                }
                if (userInfo != null) {
                    //设置用户名和用户头像
                    userResponse.setAvatarUrl(userInfo.getAvatarUrl());
                    userResponse.setName(userInfo.getName());
                }
                userIdToUserResponse.put(userId, userResponse);
            }
        }
        return userIdToUserResponse;
    }

    @Override
    public List<Long> getIdListByQueryCondition(String queryCondition) {
        List<UserAccount> userAccountList = userAccountService.list(new QueryWrapper<UserAccount>()
                .select("user_id")
                //通过手机号模糊查找
                .like("mobile", queryCondition));
        List<UserInfo> userInfoList = userInfoService.list(new QueryWrapper<UserInfo>()
                .select("user_id")
                //通过用户名模糊查找
                .like("name", queryCondition)
        );
        //获取通过手机号模糊查询出来的用户id
        List<Long> accountUserIdList = ProjectUtils.getAttrList(userAccountList, "userId", null);
        //获取通过用户名模糊查询出来的用户id
        List<Long> infoUserIdList = ProjectUtils.getAttrList(userInfoList, "userId", null);
        //合并去重
        accountUserIdList.addAll(infoUserIdList);
        ProjectUtils.removeDuplicateWithOrder(accountUserIdList);
        return accountUserIdList;
    }

    @Override
    public RestResponse getUserInfo(UserRequest userRequest) {
        Long userId = userRequest.getUserId();
        Long companyId = userRequest.getCompanyId();
        if (userId == null) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "获取用户信息失败");
        }
        UserInfoResponse userInfoResponse = new UserInfoResponse();
        //设置用户基础信息
        UserAccount account = userAccountService.getByUserId(userId);
        UserInfo info = userInfoService.getByUserId(userId);
        if (account == null || info == null) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "用户信息不存在");
        }
        //设置是否微信绑定
        userInfoResponse.setWxBindFlag(StringUtils.isNotBlank(account.getWechatOpenId()));
        userInfoResponse.setBalance(info.getBalance());
        userInfoResponse.setUserName(info.getName());
        userInfoResponse.setAvatarUrl(info.getAvatarUrl());
        userInfoResponse.setRemarks(info.getRemarks());
        userInfoResponse.setMobile(account.getMobile());
        //设置角色信息
        Role role = roleService.getRoleByUserIdAndCompanyId(userId, companyId);
        if (role != null) {
            userInfoResponse.setRoleCode(role.getCode());
            userInfoResponse.setRoleName(role.getName());
        }
        //设置公司信息
        MaintenanceCompany maintenanceCompany = maintenanceCompanyService.getById(companyId);
        if (maintenanceCompany != null) {
            userInfoResponse.setCompanyName(maintenanceCompany.getName());
        }
        //设置操作证信息
        LiftCertificate liftCertificate = projectService.getLiftCertificateByUserIdAndCompanyId(new ProjectUser(userId, companyId));
        if (liftCertificate != null) {
            userInfoResponse.setCertificateStatus(liftCertificate.getStatus());
        }
        return RestResponse.success(userInfoResponse, ApiConstants.RESULT_SUCCESS, "获取用户信息成功");
    }

    @Override
    @Transactional
    public RestResponse changeMobile(ChangeMobileRequest changeMobileRequest, HttpSession session) {
        //非空校验
        if (StringUtils.isBlank(changeMobileRequest.getOldMobile())) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "旧手机号为空");
        }
        if (StringUtils.isBlank(changeMobileRequest.getNewMobile())) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "新手机号为空");
        }
        //验证手机号验证码
        RestResponse restResponse = loginService.verifySmsCode(changeMobileRequest.getNewMobile(),
                changeMobileRequest.getNewMobileSmsCode());
        if (restResponse != null) {
            return restResponse;
        }
        //验证用户原来手机号是否有效
        UserAccount oldUserAccount = userAccountService.getByMobile(changeMobileRequest.getOldMobile());
        if (oldUserAccount == null) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "原手尚未注册无法");
        }
        //校验新手机号是否已经存在
        UserAccount newUserAccount = userAccountService.getByMobile(changeMobileRequest.getNewMobile());
        if (newUserAccount != null) {
            return RestResponse.fail(ApiConstants.RESULT_ERROR, "新手机号已经被注册，无法更换");
        }
        //校验通过，更换手机号
        oldUserAccount.setMobile(changeMobileRequest.getNewMobile());
        UserInfo userInfo = userInfoService.getByUserId(oldUserAccount.getUserId());
        userInfo.setMobile(changeMobileRequest.getNewMobile());
        userAccountService.updateById(oldUserAccount);
        userInfoService.updateById(userInfo);
        //将用户在系统中登出，用户更换手机号后需要重新登录
        loginService.blankingUserInfoIntoRedis(changeMobileRequest.getOldMobile(), changeMobileRequest.getToken(), session);
        return RestResponse.success(ApiConstants.RESULT_SUCCESS, "更换手机号成功");
    }

    @Override
    public RestResponse personalCenter(UserRequest userRequest) {
        Long userId = userRequest.getUserId();
        Long companyId = userRequest.getCompanyId();
        //获取用户信息
        UserAccount userAccount = userAccountService.getByUserId(userId);
        UserInfo userInfo = userInfoService.getByUserId(userId);
        //获取公司信息
        List<MtCompanyUser> mtCompanyUserList = mtCompanyUserService.list(new QueryWrapper<MtCompanyUser>()
                .select("mt_company_id")
                .eq("user_id", userId)
                .eq("delete_flag", ApiConstants.DELETE_NO)
        );
        //获取角色信息
        Role role = roleService.getRoleByUserIdAndCompanyId(userId, companyId);
        List<Long> mtCompanyIdList = ProjectUtils.getAttrList(mtCompanyUserList, "mtCompanyId", null);
        List<MaintenanceCompany> maintenanceCompanyList = maintenanceCompanyService.list(new QueryWrapper<MaintenanceCompany>()
                .in(mtCompanyIdList.size() > 0, "id", mtCompanyIdList)
        );
        PersonalCenterResponse personalCenterResponse = new PersonalCenterResponse();
        //设置用户信息
        personalCenterResponse.setAccount(userAccount.getAccount());
        personalCenterResponse.setMobile(userAccount.getMobile());
        personalCenterResponse.setRemarks(userInfo.getRemarks());
        personalCenterResponse.setName(userInfo.getName());
        //设置角色信息
        if (role != null) {
            personalCenterResponse.setRoleName(role.getName());
        }
        //设置团队信息
        personalCenterResponse.setMaintenanceCompanyList(maintenanceCompanyList);
        return RestResponse.success(personalCenterResponse, "获取用户信息成功");
    }

    @Override
    public RestResponse modifyAccount(UserRequest userRequest) {
        UserAccount userAccount = userAccountService.getByUserId(userRequest.getUserId());
        userAccount.setAccount(userRequest.getAccount());
        userAccountService.updateUserAccount(userAccount);
        return RestResponse.success(null, ApiConstants.RESULT_SUCCESS, "修改帐号成功");
    }

    @Override
    public RestResponse modifyRemarks(UserRequest userRequest) {
        UserInfo userInfo = userInfoService.getByUserId(userRequest.getUserId());
        userInfo.setRemarks(userRequest.getRemarks());
        userInfoService.updateUserInfo(userInfo);
        return RestResponse.success(null, ApiConstants.RESULT_SUCCESS, "修改描述成功");
    }

    @Override
    public UserResponse getAppletUserInfo(Long userId) {
        List<Role> roleList = roleService.getRoleByUserIdAndRoleCode(userId, CommonEnum.DefaultRole.HIGH_DIRECTOR.getCode());
        if (roleList != null && roleList.size() > 0) {
            UserResponse userResponse = getBaseUserInfo(userId);
            //当前角色
            Role currentRole = roleList.get(0);
            userResponse.setRole(currentRole);
            userResponse.setRoleCode(currentRole.getCode());
            userResponse.setMaintenanceCompany(maintenanceCompanyService.getById(currentRole.getCompanyId()));
            return userResponse;
        }
        return null;
    }

    @Override
    public RestResponse modifyAvatar(UserRequest userRequest) {
        UserInfo userInfo = userInfoService.getByUserId(userRequest.getUserId());
        userInfo.setAvatarUrl(userRequest.getAvatarUrl());
        userInfoService.updateById(userInfo);
        return RestResponse.success(ApiConstants.RESULT_SUCCESS, "修改用户头像成功");
    }

    @Override
    public RestResponse modifyName(UserRequest userRequest) {
        UserInfo userInfo = userInfoService.getByUserId(userRequest.getUserId());
        userInfo.setName(userRequest.getName());
        userInfoService.updateById(userInfo);
        return RestResponse.success(ApiConstants.RESULT_SUCCESS, "修改用户昵称成功");
    }

    @Override
    public List<Long> getUserIdByCompanyIdAndRoleCode(long companyId, String roleCode) {
        List<Long> userIdList = new ArrayList<>();
        Role role = roleService.getOne(new QueryWrapper<Role>()
                .eq("company_id", companyId)
                .eq("code", roleCode)
        );
        if (role != null) {
            List<UserRole> userRoleList = userRoleService.list(new QueryWrapper<UserRole>()
                    .select("user_id")
                    .eq("role_id", role.getId())
            );
            if (userRoleList != null && userRoleList.size() > 0) {
                userRoleList.forEach(userRole -> {
                    userIdList.add(userRole.getUserId());
                });
            }
        }
        return userIdList;
    }

    /**
     * @param userId 获取用户基本信息
     * @return 用户信息
     * @description 用户信息
     * @date 2020/4/27 1:18 下午
     */
    private UserResponse getBaseUserInfo(Long userId) {
        UserResponse userResponse = new UserResponse();
        userResponse.setUserId(userId);
        //获取用户的基本信息
        UserAccount userAccount = userAccountService.getByUserId(userId);
        UserInfo userInfo = userInfoService.getByUserId(userId);
        userResponse.setName(userInfo.getName());
        userResponse.setMobile(userAccount.getMobile());
        userResponse.setExpertFlag(userAccount.getExpertFlag());
        userResponse.setBalance(userInfo.getBalance());
        userResponse.setAvatarUrl(userInfo.getAvatarUrl());
        userResponse.setType(userAccount.getType());
        return userResponse;
    }

}
