package com.dk.mdm.service.mst;

import com.dk.common.exception.BaseBusinessException;
import com.dk.common.infrastructure.annotaiton.Pagination;
import com.dk.common.infrastructure.constant.Constant;
import com.dk.common.infrastructure.enums.ErrorCodeEnum;
import com.dk.common.model.pojo.PageList;
import com.dk.common.model.pojo.mst.StaffPurview;
import com.dk.common.model.pojo.mst.StaffRight;
import com.dk.common.model.vo.core.StaffEntity;
import com.dk.common.response.ResponseCodeEnum;
import com.dk.common.response.ResponseResultUtil;
import com.dk.common.response.ResponseResultVO;
import com.dk.mdm.feign.CompanyFeign;
import com.dk.mdm.feign.UserFeign;
import com.dk.mdm.infrastructure.convert.mst.StaffConvert;
import com.dk.mdm.infrastructure.util.AuthUtils;
import com.dk.mdm.mapper.common.CommonMapper;
import com.dk.mdm.mapper.mst.ComMenuMapper;
import com.dk.mdm.model.pojo.mst.*;
import com.dk.mdm.mapper.mst.StaffMapper;
import com.dk.common.service.BaseService;
import com.dk.common.mapper.BaseMapper;
import com.dk.mdm.model.query.mst.ComMenuQuery;
import com.dk.mdm.model.query.mst.StaffQuery;
import com.dk.common.model.response.mst.StaffResponse;
import com.dk.common.model.vo.mst.StaffVO;
import com.dk.mdm.service.common.CommonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author : 姜永辉
 * @desc : 员工API接口
 * @date : 2023/1/4 9:25
 */
@Service
@Slf4j
public class StaffService extends BaseService<Staff> {
    @Resource
    private CompanyFeign companyFeign;
    @Resource
    private UserFeign userFeign;

    @Override
    public BaseMapper<Staff> getRepository() {
        return staffMapper;
    }

    /**
     * @desc : 重写主键
     * @author : 姜永辉
     * @date : 2023/1/9 10:39
     */
    @Override
    public String getPrimaryKey() {
        return "staff_id";
    }

    @Autowired
    private StaffMapper staffMapper;

    @Autowired
    private StaffConvert staffConvert;

    @Autowired
    private StaffRightService staffRightService;

    @Autowired
    private StaffPurviewService staffPurviewService;

    @Autowired
    private CommonService commonService;

    @Autowired
    private CommonMapper commonMapper;

    @Autowired
    private ComMenuService comMenuService;

    @Autowired
    private AuthUtils authUtils;

    /**
     * @desc : 条件查询
     * @author : 姜永辉
     * @date : 2023/1/9 10:40
     */
    @Pagination
    public ResponseResultVO<PageList<StaffResponse>> selectByCond(StaffQuery staffQuery) {
        // 获取当前公司的cpId
        if (staffQuery.getCpId()==null){
            Integer cpId = authUtils.getStaff().getCpId();
            staffQuery.setCpId(cpId);
        }
        return super.mergeListWithCount(staffQuery, staffMapper.selectByCond(staffQuery),
                staffMapper.countByCond(staffQuery));
    }

    /**
     * @desc : 保存方法
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> insert(StaffVO staffVO) {
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        // 获取当前公司的cpId
        Integer cpId = authUtils.getStaff().getCpId();
        // 校验同一个公司的电话不能重复
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setStaffPhone(staff.getStaffPhone());
        staffQuery.setCpId(cpId);
        staff.setCpId(cpId);
        List<StaffResponse> staffResponses = staffMapper.selectByCond(staffQuery);
        if (staffResponses != null && staffResponses.size() > 0) {
            return ResponseResultUtil.error(ResponseCodeEnum.ERROR_STAFF_PHONE_EXIST);
        }

        staffQuery.setStaffPhone(null);
        staffQuery.setStaffCode(staff.getStaffCode());
        staffResponses = staffMapper.selectByCondByCode(staffQuery);
        if (staffResponses != null && staffResponses.size() > 0) {
            return ResponseResultUtil.error(ResponseCodeEnum.ERROR_STAFF_CODE_EXIST);
        }

        // 获取编码和主键UuId
        Map<String, Object> codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.STAFF.getName(), false);
        staff.setStaffId(codeMap.get("outId").toString());
//        staff.setStaffCode(codeMap.get("outNote").toString());
        super.insert(staff);
        // 讲电话和名称插入微信用户表里
        Map<String, Object> collectQuery = new HashMap<>();
        collectQuery.put("currentCp", staff.getCpId());
        collectQuery.put("userName", staff.getStaffName());
        collectQuery.put("userPhone", staff.getStaffPhone());
        ResponseResultVO<?> resultVO = userFeign.registerFeign(collectQuery);
        Map<String, Object> m = new HashMap<>();

        // 如果没有成功返回，状态设置为待审
        if (resultVO.getCode() != ResponseCodeEnum.SUCCESS.getCode()) {
            // 无用户
            throw new BaseBusinessException(ErrorCodeEnum.USER_REGISTER_ERROR.getCode(),
                    ErrorCodeEnum.USER_REGISTER_ERROR.getMessage());
        } else {
            m = (Map<String, Object>) resultVO.getData();
        }
        staff.setWxUserId(m.get("userId").toString());
        super.updateByUuid(staff);
        return ResponseResultUtil.success(staff);
    }

    /**
     * @desc : 保存方法
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> insertFeignStaff(StaffVO staffVO) {
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        // 校验同一个公司的电话不能重复
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setCpId(staff.getCpId());
        staffQuery.setStaffPhone(staff.getStaffPhone());
        List<StaffResponse> staffResponses = staffMapper.selectByCond(staffQuery);
        if (staffResponses != null && staffResponses.size() > 0) {
            return ResponseResultUtil.error(ResponseCodeEnum.ERROR_STAFF_PHONE_EXIST);
        }
        // 获取编码和主键UuId
        Map<String, Object> codeMap = commonService.getUniqueNoteCode(
                Constant.docNameConstant.STAFF.getName(), staff.getCpId(), true);
        staff.setStaffId(codeMap.get("outId").toString());
        staff.setStaffCode(codeMap.get("outNote").toString());
        super.insert(staff);
        return ResponseResultUtil.success(staff);
    }

    /**
     * @desc : 注册商户时候插入  角色 基础资料（仓库 渠道 收入 支出 入库 出库 账户 来源 盈亏原因） 计量单位 种类  打印票据  等等。
     *         返回角色的数据
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(rollbackFor = {Exception.class})
    public ResponseResultVO<?> insertFeignCompanyData(Map<String, List<Map<String, Object>>> map) {

        return ResponseResultUtil.success(null);
    }


    /**
     * @desc : 保存方法-邀请员工的确定
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(rollbackFor = {Exception.class})
    public ResponseResultVO<?> insertRequestStaff(StaffVO staffVO) {
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        // 校验同一个公司的电话不能重复
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setCpId(staff.getCpId());
        staffQuery.setStaffPhone(staff.getStaffPhone());
        List<StaffResponse> staffResponses = staffMapper.selectByCond(staffQuery);
        if (staffResponses != null && staffResponses.size() > 0) {
            return ResponseResultUtil.error(ResponseCodeEnum.ERROR_STAFF_PHONE_EXIST);
        }
        // 获取编码和主键UuId
        Map<String, Object> codeMap = commonService.getUniqueNoteCode(Constant.docNameConstant.STAFF.getName(), true);
        staff.setStaffId(codeMap.get("outId").toString());
        staff.setStaffCode(codeMap.get("outNote").toString());
        // 更新 被邀人员的cpid
        if (staff.getWxUserId() != null) {
            // 更新 被邀请人员的微信用户的cpid 加入公司
            Map<String, Object> collectQuery = new HashMap<>();
            collectQuery.put("cpId", staff.getCpId());
            collectQuery.put("userId", staff.getWxUserId());
            companyFeign.updateWxUserCompany(collectQuery);
        }
        // 插入员工
        super.insert(staff);
        return ResponseResultUtil.success(staff);
    }

    /**
     * @desc : 编辑方法
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<Boolean> update(StaffVO staffVO) {
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        return super.updateByUuid(staff);
    }

    /**
     * @desc : 保存权限方法
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> saveStaffRight(StaffVO staffVO) {
        // 获取当前公司的cpId
        Integer cpId = authUtils.getStaff().getCpId();
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        staffRightService.delete(staffVO.getStaffId());
        for (StaffRight staffRight : staffVO.getStaffRightList()) {
            staffRight.setStaffId(staff.getStaffId());
            staffRight.setRightType(1);
            staffRight.setCpId(cpId);
        }
         if (staffVO.getStaffRightList()!=null && staffVO.getStaffRightList().size() > 0) {
             staffRightService.saveStaffRight(staffVO.getStaffRightList());
         }
        return ResponseResultUtil.success();
    }

    /**
     * @desc : 保存权限方法
     * @author : 姜永辉
     * @date : 2023/1/9 10:49
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<?> saveStaffPurview(StaffVO staffVO) {
        // 获取当前公司的cpId
        Integer cpId = authUtils.getStaff().getCpId();
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        for (StaffPurview staffRight : staffVO.getStaffPurviewList()) {
            staffRight.setStaffId(staff.getStaffId());
            staffRight.setCpId(cpId);
        }
        staffPurviewService.saveStaffPurview(staffVO.getStaffPurviewList());
        return ResponseResultUtil.success();
    }


    /**
     * @desc : 员工离职
     * @author : 姜永辉
     * @date : 2023/2/13 13:45
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<Boolean> dimission(StaffVO staffVO) {
        // 将微信的用户的信息 openid  current_cp  , "joined_cps"   缩减相应的cpid
        // 更新 被邀请人员的微信用户的cpid 加入公司
        Map<String, Object> collectQuery = new HashMap<>();
        // 获取当前公司的cpId
        Integer cpId = authUtils.getStaff().getCpId();
        collectQuery.put("cpId", cpId);
        collectQuery.put("userId", staffVO.getWxUserId());
        ResponseResultVO<?> resultVO = userFeign.updateClearOpenidFeign(collectQuery);
        // 如果没有成功返回，状态设置为待审
        if (resultVO.getCode() != ResponseCodeEnum.SUCCESS.getCode()) {
            // 无用户
            throw new BaseBusinessException(ErrorCodeEnum.STAFF_UPDATE_ERROR.getCode(),
                    ErrorCodeEnum.STAFF_UPDATE_ERROR.getMessage());
        }
        // 转化实体
        Staff staff = staffConvert.convertToPo(staffVO);
        super.updateByUuid(staff);
        return ResponseResultUtil.success();
    }

    /**
     * @desc : 导入员工
     * @author : 姜永辉
     * @date : 2023/3/1 14:40
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<Boolean> importStaffList(List<StaffVO> list) {
        if (CollectionUtils.isEmpty(list) || list.size() == 0) {
            return ResponseResultUtil.error(ResponseCodeEnum.INSERT_FAIL);
        }

        return ResponseResultUtil.success();
    }

    /**
     * @desc : 登录后获取信息
     * @author : 周兴
     * @date : 2024/3/4 11:41
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<Dictionary<String, Object>> getInfoAfterLogin(Map<String, Object> param) {
        // 先根据userId查询当前企业的员工信息
        StaffResponse staff = staffMapper.selectByUserId(param.get("userId").toString(),Integer.parseInt(param.get("cpId").toString()));
        if (staff != null) {
            // 存Redis
            authUtils.saveStaff(new StaffEntity().setStaffId(staff.getStaffId())
                    .setWxUserId(staff.getWxUserId())
                    .setStaffCode(staff.getStaffCode())
                    .setStaffName(staff.getStaffName())
                    .setCpId(Integer.parseInt(param.get("cpId").toString()))
                    .setAppCode(param.get("appCode").toString()));
            // 更新员工登录状态
            this.updateByUuid(new Staff().setStaffId(staff.getStaffId()).setFlgCanLogin(true));
        } else {
            return ResponseResultUtil.error(ErrorCodeEnum.STAFF_NOT_EXIST.getCode(), ErrorCodeEnum.STAFF_NOT_EXIST.getMessage());
        }

        // 获取菜单
        List menuList = commonMapper.getMenuByUser(param);
        // 获取常用菜单
        ResponseResultVO<?> comMenuList = comMenuService.selectMenu(new ComMenuQuery().setStaffId(staff.getStaffId())
                .setAppCode(param.get("appCode").toString()));
        // 获取所有参数
        Map<String, Object> allSettingValue = commonMapper.getAllSettingValue();
        Dictionary<String, Object> dic = new Hashtable<>();
        dic.put("menuList", menuList);
        dic.put("comMenuList", comMenuList.getData());
        dic.put("dataKindList",  commonMapper.getDataKind(param));
        dic.put("settingValue", allSettingValue);
        dic.put("staff", staff);
        return ResponseResultUtil.success(dic);
    }

    /**
     * @desc : 退出登录
     * @author : 周兴
     * @date : 2024-03-18 09:03
     */
    @Transactional(
            rollbackFor = {Exception.class}
    )
    public ResponseResultVO<Boolean> logout(Map<String, Object> param) {
        // 更新员工登录状态
        this.updateByUuid(new Staff().setStaffId(param.get("staffId").toString()).setFlgCanLogin(false));
        return ResponseResultUtil.success(true);
    }
}
