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.OrgDepartmentEntity;
import org.qinan.safetyeval.domain.gateway.OrgDepartmentGateway;
import org.qinan.safetyeval.domain.query.OrgDepartmentQuery;
import org.qinan.safetyeval.domain.query.PageResult;
import org.qinan.safetyeval.infrastructure.dataobject.OrgDepartmentDO;
import org.qinan.safetyeval.infrastructure.mapper.OrgDepartmentMapper;
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 OrgDepartmentGatewayImpl implements OrgDepartmentGateway {

    @Resource
    private OrgDepartmentMapper orgDepartmentMapper;

    @Resource
    private OrgContextResolver orgContextResolver;

    @Override
    public OrgDepartmentEntity save(OrgDepartmentEntity entity) {
        OrgDepartmentDO dataObject = toDO(entity);
        InsertFieldDefaults.apply(dataObject);
        orgDepartmentMapper.insert(dataObject);
        entity.setId(dataObject.getId());
        return entity;
    }

    @Override
    public OrgDepartmentEntity get(Long id) {
        OrgDepartmentDO dataObject = orgDepartmentMapper.selectById(id);
        return toEntity(dataObject);
    }

    @Override
    public OrgDepartmentEntity modify(OrgDepartmentEntity entity) {
        OrgDepartmentDO dataObject = toDO(entity);
        dataObject.setId(entity.getId());
        InsertFieldDefaults.applyForUpdate(dataObject);
        orgDepartmentMapper.updateById(dataObject);
        return get(entity.getId());
    }

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

    @Override
    public PageResult<OrgDepartmentEntity> page(OrgDepartmentQuery query) {
        LambdaQueryWrapper<OrgDepartmentDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrgDepartmentDO::getDeleteEnum, "false");
        if (query.getOrgId() != null) {
            wrapper.eq(OrgDepartmentDO::getOrgId, query.getOrgId());
        }
        if (query.getParentId() != null) {
            wrapper.eq(OrgDepartmentDO::getParentId, query.getParentId());
        }
        if (StringUtils.hasText(query.getDeptName())) {
            wrapper.like(OrgDepartmentDO::getDeptName, query.getDeptName());
        }

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

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

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

    private OrgDepartmentDO toDO(OrgDepartmentEntity entity) {
        OrgDepartmentDO dataObject = new OrgDepartmentDO();
        dataObject.setOrgId(orgContextResolver.resolveOrgId(entity.getOrgId()));
        dataObject.setParentId(entity.getParentId() != null ? entity.getParentId() : 0L);
        dataObject.setDeptName(entity.getDeptName());
        dataObject.setManagerName(entity.getManagerName());
        dataObject.setManagerAccount(entity.getManagerAccount());
        dataObject.setDeptLevelCode(entity.getDeptLevelCode());
        dataObject.setDeptLevelName(entity.getDeptLevelName());
        dataObject.setTenantId(entity.getTenantId());
        return dataObject;
    }

    private OrgDepartmentEntity toEntity(OrgDepartmentDO dataObject) {
        if (dataObject == null) {
            return null;
        }
        OrgDepartmentEntity entity = new OrgDepartmentEntity();
        entity.setId(dataObject.getId());
        entity.setParentId(dataObject.getParentId());
        entity.setDeptName(dataObject.getDeptName());
        entity.setManagerName(dataObject.getManagerName());
        entity.setManagerAccount(dataObject.getManagerAccount());
        entity.setDeptLevelCode(dataObject.getDeptLevelCode());
        entity.setDeptLevelName(dataObject.getDeptLevelName());
        entity.setTenantId(dataObject.getTenantId());
        return entity;
    }
}
