package org.agt.module.license.service.project;

import cn.hutool.core.util.StrUtil;
import jakarta.annotation.Resource;
import org.agt.framework.common.pojo.PageResult;
import org.agt.framework.common.util.object.BeanUtils;
import org.agt.module.license.controller.admin.project.vo.ProjectPageReqVO;
import org.agt.module.license.controller.admin.project.vo.ProjectSaveReqVO;
import org.agt.module.license.dal.dataobject.project.ProjectDO;
import org.agt.module.license.dal.mysql.project.ProjectMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import static org.agt.framework.common.exception.util.ServiceExceptionUtil.exception;
import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_CODE_DUPLICATE;
import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_NAME_DUPLICATE;
import static org.agt.module.license.enums.ErrorCodeConstants.PROJECT_NOT_EXISTS;

/**
 * 项目 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
public class ProjectServiceImpl implements ProjectService {

    @Resource
    private ProjectMapper projectMapper;

    @Override
    public Long createProject(ProjectSaveReqVO createReqVO) {
        // 校验项目名称和编号是否唯一
        validateProjectNameAndCodeUnique(createReqVO.getName(), createReqVO.getCode(), createReqVO.getId());
        // 插入
        ProjectDO project = BeanUtils.toBean(createReqVO, ProjectDO.class);
        projectMapper.insert(project);
        // 返回
        return project.getId();
    }

    @Override
    public void updateProject(ProjectSaveReqVO updateReqVO) {
        // 校验项目名称和编号是否唯一
        validateProjectNameAndCodeUnique(updateReqVO.getName(), updateReqVO.getCode(), updateReqVO.getId());
        // 校验存在
        validateProjectExists(updateReqVO.getId());
        // 更新
        ProjectDO updateObj = BeanUtils.toBean(updateReqVO, ProjectDO.class);
        projectMapper.updateById(updateObj);
    }

    @Override
    public void deleteProject(Long id) {
        // 校验存在
        validateProjectExists(id);
        // 删除
        projectMapper.deleteById(id);
    }

    private void validateProjectExists(Long id) {
        if (projectMapper.selectById(id) == null) {
            throw exception(PROJECT_NOT_EXISTS);
        }
    }

    private void validateProjectNameAndCodeUnique(String name, String code, Long id) {
        Boolean isNameUnique = validateProjectNameUnique(name, id);
        if (!isNameUnique) {
            throw exception(PROJECT_NAME_DUPLICATE, name);
        }
        Boolean isCodeUnique = validateProjectCodeUnique(code, id);
        if (!isCodeUnique) {
            throw exception(PROJECT_CODE_DUPLICATE, code);
        }
    }

    @Override
    public ProjectDO getProject(Long id) {
        return projectMapper.selectById(id);
    }

    @Override
    public PageResult<ProjectDO> getProjectPage(ProjectPageReqVO pageReqVO) {
        return projectMapper.selectPage(pageReqVO);
    }

    @Override
    public Boolean validateProjectNameUnique(String name, Long id) {
        if (StrUtil.isBlank(name)) {
            return true;
        }
        ProjectDO project = projectMapper.selectByName(name);
        if (project == null) {
            return true;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的客户
        if (id == null) {
            return false;
        }
        if (!project.getId().equals(id)) {
            return false;
        }
        return true;
    }

    @Override
    public Boolean validateProjectCodeUnique(String code, Long id) {
        if (StrUtil.isBlank(code)) {
            return true;
        }
        ProjectDO project = projectMapper.selectByCode(code);
        if (project == null) {
            return true;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的客户
        if (id == null) {
            return false;
        }
        if (!project.getId().equals(id)) {
            return false;
        }
        return true;
    }

    @Override
    public Integer selectMaxCode() {
        Integer maxCode = projectMapper.selectMaxCode();
        return maxCode == null || maxCode < 2000 ? 2000 : maxCode + 1;
    }
}