package cn.iocoder.yudao.module.relations.service.entry;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.employee.api.EmployeeApi;
import cn.iocoder.yudao.module.employee.api.dto.EmployeeRespDTO;
import cn.iocoder.yudao.module.infra.api.file.FileApi;
import cn.iocoder.yudao.module.infra.api.file.dto.FileDTO;
import cn.iocoder.yudao.module.relations.api.entry.dto.RelationsEntryCreateReqDTO;
import cn.iocoder.yudao.module.relations.controller.admin.entry.vo.RelationsEntryPageReqVO;
import cn.iocoder.yudao.module.relations.controller.admin.entry.vo.RelationsEntryRespVO;
import cn.iocoder.yudao.module.relations.controller.admin.entry.vo.RelationsEntrySaveReqVO;
import cn.iocoder.yudao.module.relations.dal.dataobject.entry.RelationsEntryDO;
import cn.iocoder.yudao.module.relations.dal.mysql.entry.RelationsEntryMapper;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.PostApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.dept.dto.PostRespDTO;
import cn.iocoder.yudao.module.system.api.dicttenant.DictDataTenantApi;
import cn.iocoder.yudao.module.system.api.dicttenant.dto.DictDataTenantRespDTO;
import cn.iocoder.yudao.module.system.enums.dicttenant.DictTypeTenantEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

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

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.relations.enums.ErrorCodeConstants.RELATIONS_ENTRY_NOT_EXISTS;

/**
 * 入职信息 Service 实现类
 *
 * @author zhaopq
 */
@Service
@Validated
public class RelationsEntryServiceImpl implements RelationsEntryService {

    @Resource
    private RelationsEntryMapper entryMapper;
    @Resource
    private FileApi fileApi;
    @Resource
    private DeptApi deptApi;
    @Resource
    private EmployeeApi employeeApi;
    @Resource
    private PostApi postApi;
    @Resource
    private DictDataTenantApi dictDataTenantApi;

    @Override
    public Long createEntry(RelationsEntrySaveReqVO createReqVO) {
        // 获取用户信息和租户ID
        LoginUser user = SecurityFrameworkUtils.getLoginUser();
//        Long tenantId = user != null && user.getTenantId() != null ? user.getTenantId() : 0L;
        Long userId = user != null && user.getId() != null ? user.getId() : 0L;
//        createReqVO.setTenantId(tenantId);
        // 职位
        Long postId = createReqVO.getPostId();
        PostRespDTO post = postApi.getPost(postId);
        if (Objects.nonNull(post)) {
            createReqVO.setPosition(post.getName());
        }
        // 插入
        String infoId = IdUtil.fastSimpleUUID();
        createReqVO.setEntryId(infoId);
        RelationsEntryDO entry = BeanUtils.toBean(createReqVO, RelationsEntryDO.class);
        // 登录员工信息
        EmployeeRespDTO loginEmployee = employeeApi.getEmployeeByUserId(userId);// 判空检查
        if (loginEmployee != null) {
            entry.setCreatorEmployeeId(loginEmployee.getId());
            entry.setCreatorEmployeeName(loginEmployee.getName());
        }
        entryMapper.insert(entry);
        // 保存业务uuid到附件中
        fileApi.updateFileBiz(createReqVO.getFileIdList(), infoId);
        // 返回
        return entry.getId();
    }

    @Override
    public Long createEntryInfoAfterAudit(RelationsEntryCreateReqDTO entryCreateReqDTO) {
        RelationsEntryDO relationsEntryDO = BeanUtils.toBean(entryCreateReqDTO, RelationsEntryDO.class);
        entryMapper.insert(relationsEntryDO);
        return relationsEntryDO.getId();
    }

    @Override
    public void updateEntry(RelationsEntrySaveReqVO updateReqVO) {
        // 校验存在
        validateEntryExists(updateReqVO.getId());
        // 保存业务uuid到附件中
        fileApi.updateFileBiz(updateReqVO.getFileIdList(), updateReqVO.getEntryId());
        // 职位
        Long postId = updateReqVO.getPostId();
        PostRespDTO post = postApi.getPost(postId);
        if (Objects.nonNull(post)) {
            updateReqVO.setPosition(post.getName());
        }
        // 更新
        RelationsEntryDO updateObj = BeanUtils.toBean(updateReqVO, RelationsEntryDO.class);
        entryMapper.updateById(updateObj);
    }

    @Override
    public void deleteEntry(Long id) {
        // 校验存在
        validateEntryExists(id);
        // 删除
        entryMapper.deleteById(id);
    }

    private void validateEntryExists(Long id) {
        if (entryMapper.selectById(id) == null) {
            throw exception(RELATIONS_ENTRY_NOT_EXISTS);
        }
    }

    @Override
    public RelationsEntryDO getEntry(Long id) {
        return entryMapper.selectById(id);
    }

    @Override
    public RelationsEntryRespVO getById(Long id) {
        // 第一步：检查ID是否为空
        if (id == null) {
            throw new IllegalArgumentException("ID cannot be null");
        }
        // 第二步：从数据库获取数据
        RelationsEntryDO entryDO = entryMapper.selectById(id);
        if (entryDO == null) {
            throw exception(RELATIONS_ENTRY_NOT_EXISTS);
        }
        // 第三步：将DO对象转换为VO对象
        RelationsEntryRespVO respVO = BeanUtils.toBean(entryDO, RelationsEntryRespVO.class);
        if (respVO == null) {
            // 理论上BeanUtils.toBean不应该返回null，但为了安全起见，还是检查一下
            throw new RuntimeException("Failed to convert DO to VO");
        }
        // 第四步：获取附件列表
        List<FileDTO> fileList = fileApi.getFileDTOListByBiz(entryDO.getEntryId());
        if (fileList != null) {
            // 如果fileList不为null，则设置到VO对象中
            respVO.setFileList(fileList);
            List<Long> fileIdList = fileList.stream().map(FileDTO::getId).collect(Collectors.toList());
            respVO.setFileIdList(fileIdList);
        }
        // 部门
        if (entryDO.getDeptId() != null) {
            DeptRespDTO dept = deptApi.getDept(entryDO.getDeptId());
            respVO.setDeptName(dept.getName());
            if (dept != null && StringUtils.isNotBlank(dept.getName())) {
                respVO.setDeptName(dept.getName());
            }
        }
        // 员工类型
        if (StrUtil.isNotBlank(entryDO.getEmployeeType())) {
            List<DictDataTenantRespDTO> dictDataList = dictDataTenantApi.getDictDataList(DictTypeTenantEnum.TENANT_EMPLOYEE_TYPE.getType());
            Map<String, String> dictDataMap = CollectionUtils.convertMap(dictDataList, DictDataTenantRespDTO::getValue, DictDataTenantRespDTO::getLabel);
            String employeeTypeDesc = dictDataMap.get(entryDO.getEmployeeType());
            if (StrUtil.isNotBlank(employeeTypeDesc)) {
                respVO.setEmployeeTypeDesc(employeeTypeDesc);
            }
        }
        // 第五步：返回VO对象
        return respVO;
    }

    @Override
    public PageResult<RelationsEntryDO> getEntryPage(RelationsEntryPageReqVO pageReqVO) {
        return entryMapper.selectPage(pageReqVO);
    }

}