package org.qinan.safetyeval.app.executor;

import org.qinan.safetyeval.client.api.OrgDepartmentApi;
import org.qinan.safetyeval.client.dto.PageResponse;
import org.qinan.safetyeval.client.dto.SingleResponse;
import org.qinan.safetyeval.client.co.OrgDepartmentCO;
import org.qinan.safetyeval.client.dto.OrgDepartmentAddCmd;
import org.qinan.safetyeval.client.dto.OrgDepartmentModifyCmd;
import org.qinan.safetyeval.client.dto.OrgDepartmentPageQuery;
import org.qinan.safetyeval.domain.entity.OrgDepartmentEntity;
import org.qinan.safetyeval.domain.query.OrgDepartmentQuery;
import org.qinan.safetyeval.domain.query.PageResult;
import org.qinan.safetyeval.domain.service.OrgDepartmentDomainService;
import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

/**
 * 部门执行器（App层）
 *
 * @author safety-eval
 */
@Service
public class OrgDepartmentExecutor implements OrgDepartmentApi {

    @Lazy
    @Autowired(required = false)
    private OrgDepartmentDomainService orgDepartmentDomainService;

    @Override
    public SingleResponse<OrgDepartmentCO> add(OrgDepartmentAddCmd cmd) {
        OrgDepartmentEntity entity = new OrgDepartmentEntity();
        entity.setParentId(cmd.getParentId());
        entity.setDeptName(cmd.getDeptName());
        entity.setManagerName(cmd.getManagerName());
        entity.setManagerAccount(cmd.getManagerAccount());
        entity.setDeptLevelCode(cmd.getDeptLevelCode());
        entity.setDeptLevelName(cmd.getDeptLevelName());

        OrgDepartmentEntity result = orgDepartmentDomainService.add(entity);
        return SingleResponse.success(toCO(result));
    }

    @Override
    public SingleResponse<OrgDepartmentCO> get(Long id) {
        OrgDepartmentEntity entity = orgDepartmentDomainService.get(id);
        return SingleResponse.success(toCO(entity));
    }

    @Override
    public SingleResponse<OrgDepartmentCO> modify(OrgDepartmentModifyCmd cmd) {
        OrgDepartmentEntity entity = new OrgDepartmentEntity();
        entity.setId(cmd.getId());
        entity.setParentId(cmd.getParentId());
        entity.setDeptName(cmd.getDeptName());
        entity.setManagerName(cmd.getManagerName());
        entity.setManagerAccount(cmd.getManagerAccount());
        entity.setDeptLevelCode(cmd.getDeptLevelCode());
        entity.setDeptLevelName(cmd.getDeptLevelName());

        OrgDepartmentEntity result = orgDepartmentDomainService.modify(entity);
        return SingleResponse.success(toCO(result));
    }

    @Override
    public SingleResponse<Void> delete(Long id) {
        orgDepartmentDomainService.delete(id);
        return SingleResponse.success();
    }

    @Override
    public PageResponse<OrgDepartmentCO> page(OrgDepartmentPageQuery query) {
        OrgDepartmentQuery domainQuery = new OrgDepartmentQuery();
        domainQuery.setPageNum(query.getCurrent());
        domainQuery.setPageSize(query.getSize());
        domainQuery.setTenantId(AuthUserContextAdapter.getCurrentTenantId());
        domainQuery.setOrgId(query.getOrgId());
        domainQuery.setParentId(query.getParentId());
        domainQuery.setDeptName(query.getDeptName());

        PageResult<OrgDepartmentEntity> pageResult = orgDepartmentDomainService.page(domainQuery);

        return PageResponse.of(
                pageResult.getRecords().stream()
                        .map(this::toCO)
                        .collect(java.util.stream.Collectors.toList()),
                pageResult.getTotal());
    }

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