package org.qinan.safetyeval.app.executor;

import org.qinan.safetyeval.app.orchestrator.QualFilingOrchestrator;
import org.qinan.safetyeval.client.api.QualFilingChangeApi;
import org.qinan.safetyeval.client.co.QualFilingChangeCO;
import org.qinan.safetyeval.client.co.QualFilingChangeHistoryCO;
import org.qinan.safetyeval.client.dto.PageResponse;
import org.qinan.safetyeval.client.dto.SingleResponse;
import org.qinan.safetyeval.client.dto.QualFilingChangeAddCmd;
import org.qinan.safetyeval.client.dto.QualFilingChangeModifyCmd;
import org.qinan.safetyeval.client.dto.QualFilingChangePageQuery;
import org.qinan.safetyeval.client.dto.QualFilingChangeSubmitCmd;
import org.qinan.safetyeval.client.dto.QualFilingRejectCmd;
import org.qinan.safetyeval.domain.entity.QualFilingChangeEntity;
import org.qinan.safetyeval.domain.query.QualFilingChangeQuery;
import org.qinan.safetyeval.domain.query.PageResult;
import org.qinan.safetyeval.domain.service.QualFilingChangeDomainService;
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;

import javax.annotation.Resource;

/**
 * 备案变更执行器（App层）
 */
@Service
public class QualFilingChangeExecutor implements QualFilingChangeApi {

    @Lazy
    @Autowired(required = false)
    private QualFilingChangeDomainService qualFilingChangeDomainService;

    @Resource
    private QualFilingOrchestrator qualFilingOrchestrator;

    @Override
    public SingleResponse<QualFilingChangeCO> add(QualFilingChangeAddCmd cmd) {
        QualFilingChangeEntity entity = new QualFilingChangeEntity();
        entity.setOriginFilingId(cmd.getOriginFilingId());
        entity.setFilingTerritoryCode(cmd.getFilingTerritoryCode());
        entity.setFilingTerritoryName(cmd.getFilingTerritoryName());
        entity.setFilingUnitName(cmd.getFilingUnitName());
        entity.setFilingUnitTypeCode(cmd.getFilingUnitTypeCode());
        entity.setFilingUnitTypeName(cmd.getFilingUnitTypeName());
        entity.setFilingNo(cmd.getFilingNo());
        entity.setBusinessScope(cmd.getBusinessScope());
        entity.setRegisterAddress(cmd.getRegisterAddress());
        entity.setOfficeAddress(cmd.getOfficeAddress());
        entity.setCreditCode(cmd.getCreditCode());
        entity.setQualCertNo(cmd.getQualCertNo());
        entity.setLegalPersonPhone(cmd.getLegalPersonPhone());
        entity.setContactPhone(cmd.getContactPhone());
        entity.setInfoDisclosureUrl(cmd.getInfoDisclosureUrl());
        entity.setFixedAssetAmount(cmd.getFixedAssetAmount());
        entity.setArchiveRoomArea(cmd.getArchiveRoomArea());
        entity.setFulltimeEvaluatorCount(cmd.getFulltimeEvaluatorCount());
        entity.setRegisteredEngineerCount(cmd.getRegisteredEngineerCount());
        entity.setWorkplaceArea(cmd.getWorkplaceArea());
        entity.setUnitIntro(cmd.getUnitIntro());
        entity.setAttachmentUrl(cmd.getAttachmentUrl());
        entity.setFilingStatusCode(cmd.getFilingStatusCode());
        entity.setFilingStatusName(cmd.getFilingStatusName());
        QualFilingChangeEntity result = qualFilingChangeDomainService.add(entity);
        return SingleResponse.success(toCO(result));
    }

    @Override
    public SingleResponse<QualFilingChangeCO> get(Long id) {
        QualFilingChangeEntity entity = qualFilingChangeDomainService.get(id);
        return SingleResponse.success(toCO(entity));
    }

    @Override
    public SingleResponse<QualFilingChangeCO> modify(QualFilingChangeModifyCmd cmd) {
        QualFilingChangeEntity entity = new QualFilingChangeEntity();
        entity.setId(cmd.getId());
        entity.setOriginFilingId(cmd.getOriginFilingId());
        entity.setFilingTerritoryCode(cmd.getFilingTerritoryCode());
        entity.setFilingTerritoryName(cmd.getFilingTerritoryName());
        entity.setFilingUnitName(cmd.getFilingUnitName());
        entity.setFilingUnitTypeCode(cmd.getFilingUnitTypeCode());
        entity.setFilingUnitTypeName(cmd.getFilingUnitTypeName());
        entity.setFilingNo(cmd.getFilingNo());
        entity.setBusinessScope(cmd.getBusinessScope());
        entity.setRegisterAddress(cmd.getRegisterAddress());
        entity.setOfficeAddress(cmd.getOfficeAddress());
        entity.setCreditCode(cmd.getCreditCode());
        entity.setQualCertNo(cmd.getQualCertNo());
        entity.setLegalPersonPhone(cmd.getLegalPersonPhone());
        entity.setContactPhone(cmd.getContactPhone());
        entity.setInfoDisclosureUrl(cmd.getInfoDisclosureUrl());
        entity.setFixedAssetAmount(cmd.getFixedAssetAmount());
        entity.setArchiveRoomArea(cmd.getArchiveRoomArea());
        entity.setFulltimeEvaluatorCount(cmd.getFulltimeEvaluatorCount());
        entity.setRegisteredEngineerCount(cmd.getRegisteredEngineerCount());
        entity.setWorkplaceArea(cmd.getWorkplaceArea());
        entity.setUnitIntro(cmd.getUnitIntro());
        entity.setAttachmentUrl(cmd.getAttachmentUrl());
        entity.setFilingStatusCode(cmd.getFilingStatusCode());
        entity.setFilingStatusName(cmd.getFilingStatusName());
        QualFilingChangeEntity result = qualFilingChangeDomainService.modify(entity);
        return SingleResponse.success(toCO(result));
    }

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

    @Override
    public PageResponse<QualFilingChangeCO> page(QualFilingChangePageQuery query) {
        QualFilingChangeQuery domainQuery = new QualFilingChangeQuery();
        domainQuery.setPageNum(query.getCurrent());
        domainQuery.setPageSize(query.getSize());
        domainQuery.setTenantId(AuthUserContextAdapter.getCurrentTenantId());
        domainQuery.setOrgId(query.getOrgId());
        domainQuery.setOriginFilingId(query.getOriginFilingId());
        domainQuery.setFilingNo(query.getFilingNo());
        domainQuery.setFilingStatusCode(query.getFilingStatusCode());
        PageResult<QualFilingChangeEntity> pageResult = qualFilingChangeDomainService.page(domainQuery);
        return PageResponse.of(
                pageResult.getRecords().stream().map(this::toCO).collect(java.util.stream.Collectors.toList()),
                pageResult.getTotal());
    }

    @Override
    public SingleResponse<Long> start(Long originFilingId) {
        return SingleResponse.success(qualFilingOrchestrator.startChange(originFilingId));
    }

    @Override
    public SingleResponse<Void> submit(QualFilingChangeSubmitCmd cmd) {
        qualFilingOrchestrator.submitChange(cmd.getDraftFilingId());
        return SingleResponse.success();
    }

    @Override
    public SingleResponse<QualFilingChangeHistoryCO> history(Long originFilingId) {
        return SingleResponse.success(qualFilingOrchestrator.getChangeHistory(originFilingId));
    }

    @Override
    public SingleResponse<Void> approve(Long changeId) {
        qualFilingOrchestrator.approveChange(changeId);
        return SingleResponse.success();
    }

    @Override
    public SingleResponse<Void> reject(QualFilingRejectCmd cmd) {
        qualFilingOrchestrator.rejectChange(cmd.getId(), cmd.getRejectReason());
        return SingleResponse.success();
    }

    private QualFilingChangeCO toCO(QualFilingChangeEntity entity) {
        if (entity == null) {
            return null;
        }
        QualFilingChangeCO co = new QualFilingChangeCO();
        co.setId(entity.getId());
        co.setOriginFilingId(entity.getOriginFilingId());
        co.setChangeFilingId(entity.getChangeFilingId());
        co.setFilingTerritoryCode(entity.getFilingTerritoryCode());
        co.setFilingTerritoryName(entity.getFilingTerritoryName());
        co.setFilingUnitName(entity.getFilingUnitName());
        co.setFilingUnitTypeCode(entity.getFilingUnitTypeCode());
        co.setFilingUnitTypeName(entity.getFilingUnitTypeName());
        co.setFilingNo(entity.getFilingNo());
        co.setBusinessScope(entity.getBusinessScope());
        co.setRegisterAddress(entity.getRegisterAddress());
        co.setOfficeAddress(entity.getOfficeAddress());
        co.setCreditCode(entity.getCreditCode());
        co.setQualCertNo(entity.getQualCertNo());
        co.setLegalPersonPhone(entity.getLegalPersonPhone());
        co.setContactPhone(entity.getContactPhone());
        co.setInfoDisclosureUrl(entity.getInfoDisclosureUrl());
        co.setFixedAssetAmount(entity.getFixedAssetAmount());
        co.setArchiveRoomArea(entity.getArchiveRoomArea());
        co.setFulltimeEvaluatorCount(entity.getFulltimeEvaluatorCount());
        co.setRegisteredEngineerCount(entity.getRegisteredEngineerCount());
        co.setWorkplaceArea(entity.getWorkplaceArea());
        co.setUnitIntro(entity.getUnitIntro());
        co.setAttachmentUrl(entity.getAttachmentUrl());
        co.setFilingStatusCode(entity.getFilingStatusCode());
        co.setFilingStatusName(entity.getFilingStatusName());
        co.setTenantId(entity.getTenantId());
        return co;
    }
}
