package com.yiboshi.science.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yiboshi.arch.exception.BusinessException;
import com.yiboshi.science.base.BaseServiceImpl;
import com.yiboshi.science.config.bean.SystemProperties;
import com.yiboshi.science.dao.ComManagerDAO;
import com.yiboshi.science.entity.ComManager;
import com.yiboshi.science.entity.ComPerson;
import com.yiboshi.science.enumeration.CommonEnum;
import com.yiboshi.science.param.dto.ComManagerDTO;
import com.yiboshi.science.param.dto.ComPersonDTO;
import com.yiboshi.science.param.dto.ComUnitDTO;
import com.yiboshi.science.param.dto.SystemUserDTO;
import com.yiboshi.science.param.query.ComManagerQueryVO;
import com.yiboshi.science.service.ComManagerService;
import com.yiboshi.science.service.ComPersonService;
import com.yiboshi.science.service.SystemUserRoleService;
import com.yiboshi.science.service.SystemUserService;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 单位管理员表 Service 实现类
 *
 * @author lkl
 * @version 2021-08-26
 */
@Service
@AllArgsConstructor
public class ComManagerServiceImpl extends BaseServiceImpl<ComManagerDAO, ComManagerQueryVO, ComManagerDTO, ComManager> implements ComManagerService {

    @Autowired
    private ComManagerDAO comManagerDAO;

    @Autowired
    private SystemUserService systemUserService;

    @Autowired
    private ComPersonService comPersonService;

    private SystemProperties properties;

    @Autowired
    private SystemUserRoleService systemUserRoleService;

    @Override
    protected void setCriteriaForQuery(ComManagerQueryVO vo, QueryWrapper<ComManagerQueryVO> criteria) {
        if (Objects.nonNull(vo.getUnitId())) {
            criteria.eq("b.unit_id", vo.getUnitId());
        }
        if (Objects.nonNull(vo.getRoleId())) {
            criteria.eq("l.role_id", vo.getRoleId());
        }
    }

    public List<ComPersonDTO> getManagerListByUnitId(String unitId) {
        return comPersonService.getManagerListByUnitId(unitId);
    }

    @Transactional
    public String registerManager(ComUnitDTO dto) {
        //加入人员表
        String personId = this.personInsert(dto.getCertId(), dto.getPersonName(), dto.getMobile(), dto.getId(), dto.getSex(), dto.getBirthday());
        //创建角色
        String roleId = getManagerRoleByTreeCode(dto.getUnitType(), dto.getTreeCode());
        //创建用户
        systemUserService.CreateUser(dto.getUsername(), dto.getPassword(), personId, roleId, CommonEnum.userState.normal.getCode());
        return personId;
    }

    @Transactional
    public String createManager(ComManagerDTO dto) {
        dto.setCertId(dto.getCertId().toLowerCase());
        String roleId = getManagerRoleByTreeCode(dto.getUnitType(), dto.getTreeCode());
        SystemUserDTO systemUserDTO = systemUserRoleService.getUserRoleByCertId(dto.getCertId(),roleId);
        if (null != systemUserDTO)
            throw new BusinessException("管理员已存在");
        ComPerson comPerson = comPersonService.getPersonByCertId(dto.getCertId());
        String personId = "";
        if (null == comPerson) {
            personId = this.personInsert(dto.getCertId(), dto.getPersonName(), dto.getMobile(), dto.getUnitId(), dto.getSex(), dto.getBirthday());
            systemUserService.CreateUser(dto.getUsername(), dto.getPassword(), personId, roleId, CommonEnum.userState.normal.getCode());
        } else {
            if (Objects.isNull(comPerson.getUnitId()) || dto.getUnitId().equals(comPerson.getUnitId())) {
                if (!dto.getPersonName().equals(comPerson.getPersonName()))
                    throw new BusinessException("系统已存在该管理员,但姓名与证件号不匹配，请检查后再试");
                ComPerson person = new ComPerson();
                person.setId(person.getId());
                person.setUnitId(dto.getUnitId());
                person.setPersonState(CommonEnum.personState.normal.getCode());
                personId = comPersonService.update(person);
                systemUserRoleService.addRoleByPersonId(comPerson.getId(), roleId);
            } else
                throw new BusinessException("该人员不属于本单位");
        }
        return personId;
    }

    public String updateManagerState(String userRoleId, Integer state) {
        return systemUserRoleService.updateStateById(userRoleId, state);
    }

    private String getManagerRoleByTreeCode(Integer unitType, String treeCode) {
        String roleId = CommonEnum.systemRole.unit.getCode().toString();
        if (null != unitType && unitType.equals(CommonEnum.unitType.gov.getCode())) {
            if (null != treeCode && treeCode.length() == properties.getDefaultCodeLength())
                roleId = CommonEnum.systemRole.topGov.getCode().toString();
            else
                roleId = CommonEnum.systemRole.gov.getCode().toString();
        }
        return roleId;
    }

    public String personInsert(String certId, String personName, String mobile, String unitId, String sex, Date birthday) {
        ComPerson person = new ComPerson();
        person.setCertId(certId);
        person.setPersonName(personName);
        person.setMobile(mobile);
        person.setUnitId(unitId);
        person.setPersonState(CommonEnum.personState.normal.getCode());
        person.setSex(sex);
        person.setBirthday(birthday);
        return comPersonService.insert(person);
    }

    @Transactional
    public String addManagerByList(List<ComPersonDTO> list, String unitId, String roleId) {
        AtomicInteger allCount = new AtomicInteger(0);
        if (null != list) {
            list.forEach((e) -> {
                e.setCertId(e.getCertId().toLowerCase());
                SystemUserDTO systemUserDTO = systemUserRoleService.getUserRoleByCertId(e.getCertId(),roleId);
                if (null == systemUserDTO){
                    ComPerson person = comPersonService.getPersonByCertId(e.getCertId());
                    String personId = "";
                    if (null == person) {
                        personId = this.personInsert(e.getCertId(), e.getPersonName(), e.getMobile(), unitId, e.getSex(), e.getBirthday());
                        systemUserService.CreateUser(e.getUsername(), e.getPassword(), personId, roleId, CommonEnum.userState.normal.getCode());
                        allCount.incrementAndGet();
                    } else {
                        if (Objects.isNull(person.getUnitId()) || unitId.equals(person.getUnitId())) {
                            if (e.getPersonName().equals(person.getPersonName())) {
                                ComPerson comPerson = new ComPerson();
                                comPerson.setId(person.getId());
                                comPerson.setUnitId(unitId);
                                comPerson.setPersonState(CommonEnum.personState.normal.getCode());
                                comPersonService.update(comPerson);
                                systemUserRoleService.addRoleByPersonId(person.getId(), roleId);
                                allCount.incrementAndGet();
                            }
                        }
                    }
                }
            });
        }
        if (allCount.get() == 0)
            throw new BusinessException("添加失败，管理员已存在系统中，请检查后再试！");
        else
            return unitId;
    }

    @Transactional
    public String deleteManagerById(ComPersonDTO d) {
        List<ComPersonDTO> list = getManagerListByUnitId(d.getUnitId());
        if (null == list || list.size() == 1)
            throw new BusinessException("删除失败，唯一管理员！");
        systemUserRoleService.deleteById(d.getUserRoleId());
        return d.getUserRoleId();
    }

    @Transactional
    public void updateManagerRole(String unitId, String roleId) {
        List<ComPersonDTO> list = getManagerListByUnitId(unitId);
        list.forEach((f) -> {
            systemUserService.updateRoleById(f.getUserId(),f.getUserRoleId(), roleId);
        });
    }
}