package org.qinan.safetyeval.infrastructure.gatewayimpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.qinan.safetyeval.domain.entity.OrgPersonnelEntity;
import org.qinan.safetyeval.domain.gateway.OrgPersonnelGateway;
import org.qinan.safetyeval.domain.query.OrgPersonnelQuery;
import org.qinan.safetyeval.domain.query.PageResult;
import org.qinan.safetyeval.infrastructure.dataobject.OrgPersonnelDO;
import org.qinan.safetyeval.infrastructure.mapper.OrgPersonnelMapper;
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
import org.qinan.safetyeval.infrastructure.support.OrgContextResolver;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 人员信息Gateway实现（Infrastructure层）
 *
 * @author safety-eval
 */
@Component
public class OrgPersonnelGatewayImpl implements OrgPersonnelGateway {

    @Resource
    private OrgPersonnelMapper orgPersonnelMapper;

    @Resource
    private OrgContextResolver orgContextResolver;

    @Override
    public OrgPersonnelEntity save(OrgPersonnelEntity entity) {
        OrgPersonnelDO dataObject = toDO(entity);
        InsertFieldDefaults.apply(dataObject);
        orgPersonnelMapper.insert(dataObject);
        entity.setId(dataObject.getId());
        InsertFieldDefaults.apply(entity);
        entity.setTenantId(dataObject.getTenantId());
        return entity;
    }

    @Override
    public OrgPersonnelEntity get(Long id) {
        OrgPersonnelDO dataObject = orgPersonnelMapper.selectById(id);
        return toEntity(dataObject);
    }
    @Override
    public OrgPersonnelEntity getByAccount(String account) {
        LambdaQueryWrapper<OrgPersonnelDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrgPersonnelDO::getAccount, account);
        wrapper.eq(OrgPersonnelDO::getDeleteEnum, "false");
        Long orgId = orgContextResolver.resolveOrgId(null);
        if (orgId != null) {
            wrapper.eq(OrgPersonnelDO::getOrgId, orgId);
        }
        OrgPersonnelDO dataObject = orgPersonnelMapper.selectOne(wrapper);
        return toEntity(dataObject);
    }

    @Override
    public OrgPersonnelEntity findByUserName(String userName) {
        if (!StringUtils.hasText(userName)) {
            return null;
        }
        LambdaQueryWrapper<OrgPersonnelDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrgPersonnelDO::getUserName, userName);
        wrapper.eq(OrgPersonnelDO::getDeleteEnum, "false");
        wrapper.last("LIMIT 1");
        OrgPersonnelDO dataObject = orgPersonnelMapper.selectOne(wrapper);
        return toEntity(dataObject);
    }

    @Override
    public OrgPersonnelEntity modify(OrgPersonnelEntity entity) {
        OrgPersonnelDO dataObject = toDO(entity);
        dataObject.setId(entity.getId());
        InsertFieldDefaults.applyForUpdate(dataObject);
        orgPersonnelMapper.updateById(dataObject);
        return get(entity.getId());
    }

    @Override
    public void delete(Long id) {
        orgPersonnelMapper.deleteById(id);
    }

    @Override
    public PageResult<OrgPersonnelEntity> page(OrgPersonnelQuery query) {
        LambdaQueryWrapper<OrgPersonnelDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrgPersonnelDO::getDeleteEnum, "false");
        if (query.getOrgId() != null) {
            wrapper.eq(OrgPersonnelDO::getOrgId, query.getOrgId());
        }
        if (query.getDeptId() != null) {
            wrapper.eq(OrgPersonnelDO::getDeptId, query.getDeptId());
        }
        if (query.getPostId() != null) {
            wrapper.eq(OrgPersonnelDO::getPostId, query.getPostId());
        }
        if (StringUtils.hasText(query.getUserName())) {
            wrapper.like(OrgPersonnelDO::getUserName, query.getUserName());
        }
        if (StringUtils.hasText(query.getAccount())) {
            wrapper.like(OrgPersonnelDO::getAccount, query.getAccount());
        }
        if (query.getEmploymentStatusCode() != null) {
            wrapper.eq(OrgPersonnelDO::getEmploymentStatusCode, query.getEmploymentStatusCode());
        }
        if (query.getPersonnelIds() != null) {
            if (query.getPersonnelIds().isEmpty()) {
                wrapper.eq(OrgPersonnelDO::getId, -1L);
            }
            else {
                wrapper.in(OrgPersonnelDO::getId, query.getPersonnelIds());
            }
        }

        Page<OrgPersonnelDO> page = new Page<>(query.getPageNum(), query.getPageSize());
        IPage<OrgPersonnelDO> result = orgPersonnelMapper.selectPage(page, wrapper);

        List<OrgPersonnelEntity> entities = result.getRecords().stream()
                .map(this::toEntity)
                .collect(Collectors.toList());

        return PageResult.of(entities, result.getTotal(), result.getCurrent(), result.getSize());
    }

    private OrgPersonnelDO toDO(OrgPersonnelEntity entity) {
        OrgPersonnelDO dataObject = new OrgPersonnelDO();
        dataObject.setOrgId(orgContextResolver.resolveOrgId(entity.getOrgId()));
        dataObject.setDeptId(entity.getDeptId());
        dataObject.setPostId(entity.getPostId());
        dataObject.setUserName(entity.getUserName());
        dataObject.setAccount(entity.getAccount());
        dataObject.setGenderCode(entity.getGenderCode());
        dataObject.setGenderName(entity.getGenderName());
        dataObject.setBirthDate(entity.getBirthDate());
        dataObject.setIdCardNo(entity.getIdCardNo());
        dataObject.setCurrentAddress(entity.getCurrentAddress());
        dataObject.setOfficeAddress(entity.getOfficeAddress());
        dataObject.setEducationCode(entity.getEducationCode());
        dataObject.setEducationName(entity.getEducationName());
        dataObject.setGraduateSchool(entity.getGraduateSchool());
        dataObject.setMajor(entity.getMajor());
        dataObject.setEmploymentStatusCode(entity.getEmploymentStatusCode());
        dataObject.setEmploymentStatusName(entity.getEmploymentStatusName());
        dataObject.setPersonTypeCode(entity.getPersonTypeCode());
        dataObject.setPersonTypeName(entity.getPersonTypeName());
        dataObject.setQualScope(entity.getQualScope());
        dataObject.setProfessionalLevelCode(entity.getProfessionalLevelCode());
        dataObject.setProfessionalLevelName(entity.getProfessionalLevelName());
        dataObject.setEvaluatorCertNo(entity.getEvaluatorCertNo());
        dataObject.setEducationTypeCode(entity.getEducationTypeCode());
        dataObject.setEducationTypeName(entity.getEducationTypeName());
        dataObject.setEducationLevelCode(entity.getEducationLevelCode());
        dataObject.setEducationLevelName(entity.getEducationLevelName());
        dataObject.setTitleName(entity.getTitleName());
        dataObject.setRegisterEngineerFlag(entity.getRegisterEngineerFlag());
        dataObject.setPublications(entity.getPublications());
        dataObject.setAbilityDeclaration(entity.getAbilityDeclaration());
        dataObject.setWorkExperience(entity.getWorkExperience());
        dataObject.setProofMaterialUrl(entity.getProofMaterialUrl());
        dataObject.setTenantId(entity.getTenantId());
        return dataObject;
    }

    private OrgPersonnelEntity toEntity(OrgPersonnelDO dataObject) {
        if (dataObject == null) {
            return null;
        }
        OrgPersonnelEntity entity = new OrgPersonnelEntity();
        entity.setId(dataObject.getId());
        entity.setDeptId(dataObject.getDeptId());
        entity.setPostId(dataObject.getPostId());
        entity.setUserName(dataObject.getUserName());
        entity.setAccount(dataObject.getAccount());
        entity.setGenderCode(dataObject.getGenderCode());
        entity.setGenderName(dataObject.getGenderName());
        entity.setBirthDate(dataObject.getBirthDate());
        entity.setIdCardNo(dataObject.getIdCardNo());
        entity.setCurrentAddress(dataObject.getCurrentAddress());
        entity.setOfficeAddress(dataObject.getOfficeAddress());
        entity.setEducationCode(dataObject.getEducationCode());
        entity.setEducationName(dataObject.getEducationName());
        entity.setGraduateSchool(dataObject.getGraduateSchool());
        entity.setMajor(dataObject.getMajor());
        entity.setEmploymentStatusCode(dataObject.getEmploymentStatusCode());
        entity.setEmploymentStatusName(dataObject.getEmploymentStatusName());
        entity.setPersonTypeCode(dataObject.getPersonTypeCode());
        entity.setPersonTypeName(dataObject.getPersonTypeName());
        entity.setQualScope(dataObject.getQualScope());
        entity.setProfessionalLevelCode(dataObject.getProfessionalLevelCode());
        entity.setProfessionalLevelName(dataObject.getProfessionalLevelName());
        entity.setEvaluatorCertNo(dataObject.getEvaluatorCertNo());
        entity.setEducationTypeCode(dataObject.getEducationTypeCode());
        entity.setEducationTypeName(dataObject.getEducationTypeName());
        entity.setEducationLevelCode(dataObject.getEducationLevelCode());
        entity.setEducationLevelName(dataObject.getEducationLevelName());
        entity.setTitleName(dataObject.getTitleName());
        entity.setRegisterEngineerFlag(dataObject.getRegisterEngineerFlag());
        entity.setPublications(dataObject.getPublications());
        entity.setAbilityDeclaration(dataObject.getAbilityDeclaration());
        entity.setWorkExperience(dataObject.getWorkExperience());
        entity.setProofMaterialUrl(dataObject.getProofMaterialUrl());
        entity.setTenantId(dataObject.getTenantId());
        return entity;
    }
}
