package com.yiboshi.science.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiboshi.arch.exception.BusinessException;
import com.yiboshi.science.base.BaseServiceImpl;
import com.yiboshi.science.base.Pagination;
import com.yiboshi.science.config.security.SecurityUserHolder;
import com.yiboshi.science.dao.ComExpertDAO;
import com.yiboshi.science.entity.*;
import com.yiboshi.science.enumeration.CommonEnum;
import com.yiboshi.science.param.dto.ComExpertDTO;
import com.yiboshi.science.param.dto.ComExpertSpecDTO;
import com.yiboshi.science.param.query.ComExpertQueryVO;
import com.yiboshi.science.service.*;
import com.yiboshi.science.utils.ChineseToPinyin;
import com.yiboshi.science.utils.StringUtil;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static com.yiboshi.science.utils.StringUtil.hideAllIdCardNum;

@Service
@AllArgsConstructor
public class ComExpertServiceImpl extends BaseServiceImpl<ComExpertDAO, ComExpertQueryVO, ComExpertDTO, ComExpert> implements ComExpertService {

    @Autowired
    private ComExpertDAO comExpertDAO;
    @Autowired
    private ComExpertSpecService comExpertSpecService;
    @Autowired
    private ComPersonService comPersonService;
    @Autowired
    private ComUnitService comUnitService;
    @Autowired
    private SystemUserService systemUserService;
    @Autowired
    private SystemUserRoleService systemUserRoleService;
    @Autowired
    private SystemParameterService systemParameterService;

    @Override
    protected void setCriteriaForQuery(ComExpertQueryVO vo, QueryWrapper<ComExpertQueryVO> criteria) {
        if (Objects.nonNull(vo.getUnitId())) {
            criteria.eq("e.unit_id", vo.getUnitId());
        }
        if (Objects.nonNull(vo.getReportState())) {
            criteria.eq("a.report_state", vo.getReportState());
        }
        if (Objects.nonNull(vo.getCertId())) {
            criteria.eq("e.cert_id", vo.getCertId());
        }
        if (Objects.nonNull(vo.getPersonName())) {
            criteria.eq("e.person_name", vo.getPersonName());
        }
        if (Objects.nonNull(vo.getWorkUnit())) {
            criteria.eq("e.work_unit", vo.getWorkUnit());
        }
        if (Objects.nonNull(vo.getUnitName())) {
            criteria.like("d.unit_name", vo.getUnitName());
        }
        if (Objects.nonNull(vo.getUsername())) {
            criteria.eq("f.username", vo.getUsername());
        }
        if (Objects.nonNull(vo.getRoleId())) {
            criteria.eq("l.role_id", vo.getRoleId());
        }
        if (Objects.nonNull(vo.getRemark())) {
            criteria.like("a.remark", vo.getRemark());
        }
        if (Objects.nonNull(vo.getTitle())) {
            criteria.eq("e.title", vo.getTitle());
        }
        if (Objects.nonNull(vo.getTitleParentId())) {
            criteria.eq("i.parent_id", vo.getTitleParentId());
        }
        if (Objects.nonNull(vo.getSpec())) {
            criteria.eq("e.spec", vo.getSpec());
        }
        if (Objects.nonNull(vo.getSpecParentId())) {
            criteria.eq("j.parent_id", vo.getSpecParentId());
        }
    }

    @Override
    public Pagination<ComExpertDTO> getListByPage(ComExpertQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        Page<ComExpertQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComExpertDTO> dtoList = comExpertDAO.getListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }

    public ComExpertDTO getExpertById(String id) {
        ComExpertDTO dto = comExpertDAO.getExpertById(id);
        if (null != dto) {
            dto.setSpecList(comExpertSpecService.getListByExpertId(id));
            dto.setCertId(hideAllIdCardNum(dto.getCertId()));
//            if (Objects.nonNull(dto.getMobile()))
//                dto.setMobile(hideAllPhoneNum(dto.getMobile()));
        }
        return dto;
    }

    @Transactional
    public String insert(ComExpertDTO dto) {
        dto.setCertId(dto.getCertId().toLowerCase());
        ComPerson comPerson = comPersonService.getPersonByCertId(dto.getCertId());
        ComExpert comExpert = new ComExpert();
        String personId = "";
        if (comPerson != null) {
            personId = comPerson.getId();
            comExpert.setPersonId(personId);
            comExpert = this.getEntity(comExpert);
            if (null != comExpert)
                throw new BusinessException("专家已存在！");
            if (!dto.getPersonName().equals(comPerson.getPersonName()))
                throw new BusinessException("该证件号已存在系统中，但姓名不一致，请检查！");
            if (!dto.getMobile().equals(comPerson.getMobile()))
                throw new BusinessException("该手机号已注册，请检查后再试！");
            StringUtil.copyObj2Obj(dto, comPerson);
            comPerson.setId(personId);
            comPersonService.updateById(comPerson);
            systemUserRoleService.addRoleByPersonId(personId, CommonEnum.systemRole.expert.getCode().toString());
        } else {
            if (comPersonService.isMobileExist(dto.getMobile()))
                throw new BusinessException("该手机号已注册，请检查后再试！");
            comPerson = new ComPerson();
            StringUtil.copyObj2Obj(dto, comPerson);

            comPerson.setPersonState(CommonEnum.personState.normal.getCode());
            personId = comPersonService.insert(comPerson);
            String pwd = dto.getCertId().substring(dto.getCertId().length() - 6).toLowerCase();
            String UserName = ChineseToPinyin.toPinyin(comPerson.getPersonName());
            systemUserService.CreateUser(UserName, pwd, personId, CommonEnum.systemRole.expert.getCode().toString(), CommonEnum.userState.normal.getCode());
        }
        comExpert = new ComExpert();
        comExpert.setPersonId(personId);
        comExpert.setRemark(dto.getRemark());
        comExpert.setExpertState(CommonEnum.loginState.start.getCode());
        comExpert.setReportState(dto.getReportState());
        String id = this.insert(comExpert);
        dto.setId(comExpert.getId());
        comExpertSpecService.insertSpecList(dto.getSpecList(), id);
        return dto.getId();
    }

    @Transactional
    public String update(ComExpertDTO dto) {
        ComExpert comExpert = this.entityById(dto.getId());
        if (null == comExpert)
            throw new BusinessException("专家不存在或已删除！");
        ComPerson comPerson = new ComPerson();
        StringUtil.copyObj2Obj(dto, comPerson);
        comPerson.setId(comExpert.getPersonId());
        comPerson.setCertId(null);
        comPerson.setMobile(null);

        comExpert = new ComExpert();
        comExpert.setId(dto.getId());
        comExpert.setRemark(dto.getRemark());
        if(dto.getReportState()!=null){
            comExpert.setReportState(dto.getReportState());
        }
        this.update(comExpert);

        comPersonService.updateById(comPerson);
        comExpertSpecService.insertSpecList(dto.getSpecList(), dto.getId());
        return dto.getId();
    }

    @Transactional
    public String deleteExpert(ComExpertDTO d) {
        //systemUserRoleService.deleteById(d.getUserRoleId());
        if (null != d.getUserRoleId())
            throw new BusinessException("系统限制，专家暂时不能删除！");
        return d.getUserRoleId();
    }

    public String updateExpertState(ComExpertDTO d) {
        ComExpert comExpert = new ComExpert();
        comExpert.setId(d.getId());
        comExpert.setExpertState(d.getExpertState());
        String id = this.update(comExpert);
        systemUserRoleService.updateStateById(d.getUserRoleId(), d.getExpertState());
        return id;
    }

    public String expertImport(List<ComExpertDTO> list,String unitName) {
        try {
            //职称
            List<SystemParameter> titleList = systemParameterService.getListByType(7);
            //专业学科
            List<SystemParameter> specList = systemParameterService.getListByType(68);
            //专业学科
            List<SystemParameter> educationList = systemParameterService.getListByType(8);
            list.forEach(e -> {
                if (null != comPersonService.getPersonByCertId(e.getCertId()))
                    return;
                if (null != e.getTitleName()) {
                    List<SystemParameter> findList1 = titleList.stream().filter(p -> e.getTitleName().equals(p.getName())).collect(Collectors.toList());
                    if (findList1.size() > 0)
                        e.setTitle(findList1.stream().findFirst().get().getId());
                }
                if (null != e.getEducationName()) {
                    List<SystemParameter> findList1 = educationList.stream().filter(p -> e.getEducationName().equals(p.getName())).collect(Collectors.toList());
                    if (findList1.size() > 0)
                        e.setEducation(findList1.stream().findFirst().get().getId());
                }
                if (null != e.getSpecName()) {
                    if (e.getIsFinance() == 1) {
                        List<ComExpertSpecDTO> audtiSpecList = new ArrayList<>();
                        ComExpertSpecDTO w = new ComExpertSpecDTO();
                        w.setSpecId("a70f06d1-b6aa-11ef-b6cb-0c42a1381189");
                        audtiSpecList.add(w);
                        e.setSpecList(audtiSpecList);
                    } else {
                        List<SystemParameter> findList2 = specList.stream().filter(p -> e.getSpecName().equals(p.getName())).collect(Collectors.toList());
                        if (findList2.size() > 0) {
                            List<ComExpertSpecDTO> audtiSpecList = new ArrayList<>();
                            ComExpertSpecDTO w = new ComExpertSpecDTO();
                            w.setSpecId(findList2.stream().findFirst().get().getId());
                            audtiSpecList.add(w);
                            e.setSpecList(audtiSpecList);
                        }
                    }
                }
                if (SecurityUserHolder.getRoles().contains(CommonEnum.systemRole.unit.getCode().toString())) {
                    e.setUnitId(SecurityUserHolder.getUnitId());
                    e.setWorkUnit(unitName);
                    e.setReportState(1);
                }else{
                    e.setWorkUnit(e.getUnitName());
                    e.setReportState(2);
                }
                insert(e);
            });
            return "专家导入成功！";
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
    }

    public Boolean expertIsExist(String certId, String id) {
        Boolean isExist = false;
        ComExpertDTO dto = this.getExpertByCertId(certId);
        if (null != dto) {
            if (Objects.nonNull(id) && !id.equals("")) {
                ComExpertDTO comExpertDTO = comExpertDAO.getExpertById(id);
                if (null != comExpertDTO && !comExpertDTO.getCertId().equals(certId)) {
                    isExist = true;
                }
            } else {
                isExist = true;
            }
        }
        return isExist;
    }

    public List<SelectListItem> getExpertListByIdList(Map<String, Object> id) {
        List<String> idList = null;
        if (id.containsKey("idList")) {
            idList = (List<String>) id.get("idList");
        }
        QueryWrapper<SystemMenu> w = new QueryWrapper<SystemMenu>();
        if (Objects.nonNull(idList) && idList.size() > 0) {
            w.in("a.id", idList);
        }
        List<ComExpertDTO> list = comExpertDAO.getExpertListByIdList(w);
        List<SelectListItem> Item = new ArrayList<>();
        if (null != list && list.size() > 0) {
            list.forEach((e) -> {
                SelectListItem treeListItem = new SelectListItem(e.getPersonName(), e.getId(), "", false, false, new ArrayList<>());
                Item.add(treeListItem);
            });
        }
        return Item;
    }

    public ComExpertDTO getExpertByCertId(String certId) {
        return comExpertDAO.getExpertByCertId(certId);
    }
}
