package org.qinan.safetyeval.app.executor;

import org.qinan.safetyeval.client.api.QualFilingEquipmentApi;
import org.qinan.safetyeval.client.dto.PageResponse;
import org.qinan.safetyeval.client.dto.SingleResponse;
import org.qinan.safetyeval.client.co.QualFilingEquipmentCO;
import org.qinan.safetyeval.client.dto.QualFilingEquipmentAddCmd;
import org.qinan.safetyeval.client.dto.QualFilingEquipmentModifyCmd;
import org.qinan.safetyeval.client.dto.QualFilingEquipmentPageQuery;
import org.qinan.safetyeval.domain.entity.QualFilingEquipmentEntity;
import org.qinan.safetyeval.domain.query.QualFilingEquipmentQuery;
import org.qinan.safetyeval.domain.query.PageResult;
import org.qinan.safetyeval.domain.service.QualFilingEquipmentDomainService;
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 QualFilingEquipmentExecutor implements QualFilingEquipmentApi {

    @Lazy
    @Autowired(required = false)
    private QualFilingEquipmentDomainService qualFilingEquipmentDomainService;

    @Override
    public SingleResponse<QualFilingEquipmentCO> add(QualFilingEquipmentAddCmd cmd) {
        QualFilingEquipmentEntity entity = new QualFilingEquipmentEntity();
        entity.setDeviceName(cmd.getDeviceName());
        entity.setDeviceModel(cmd.getDeviceModel());
        entity.setInstrumentTypeCode(cmd.getInstrumentTypeCode());
        entity.setInstrumentTypeName(cmd.getInstrumentTypeName());
        entity.setDeviceTypeCode(cmd.getDeviceTypeCode());
        entity.setDeviceTypeName(cmd.getDeviceTypeName());
        entity.setManufacturer(cmd.getManufacturer());
        entity.setFlowDesc(cmd.getFlowDesc());
        entity.setMinFlow(cmd.getMinFlow());
        entity.setMaxFlow(cmd.getMaxFlow());
        entity.setCalibrationUnit(cmd.getCalibrationUnit());
        entity.setCalibrationInitValue(cmd.getCalibrationInitValue());
        entity.setFieldCalibrationTypeCode(cmd.getFieldCalibrationTypeCode());
        entity.setFieldCalibrationTypeName(cmd.getFieldCalibrationTypeName());
        entity.setDualChannelFlag(cmd.getDualChannelFlag());

        QualFilingEquipmentEntity result = qualFilingEquipmentDomainService.add(entity);
        return SingleResponse.success(toCO(result));
    }

    @Override
    public SingleResponse<QualFilingEquipmentCO> get(Long id) {
        QualFilingEquipmentEntity entity = qualFilingEquipmentDomainService.get(id);
        return SingleResponse.success(toCO(entity));
    }

    @Override
    public SingleResponse<QualFilingEquipmentCO> modify(QualFilingEquipmentModifyCmd cmd) {
        QualFilingEquipmentEntity entity = new QualFilingEquipmentEntity();
        entity.setId(cmd.getId());
        entity.setDeviceName(cmd.getDeviceName());
        entity.setDeviceModel(cmd.getDeviceModel());
        entity.setInstrumentTypeCode(cmd.getInstrumentTypeCode());
        entity.setInstrumentTypeName(cmd.getInstrumentTypeName());
        entity.setDeviceTypeCode(cmd.getDeviceTypeCode());
        entity.setDeviceTypeName(cmd.getDeviceTypeName());
        entity.setManufacturer(cmd.getManufacturer());
        entity.setFlowDesc(cmd.getFlowDesc());
        entity.setMinFlow(cmd.getMinFlow());
        entity.setMaxFlow(cmd.getMaxFlow());
        entity.setCalibrationUnit(cmd.getCalibrationUnit());
        entity.setCalibrationInitValue(cmd.getCalibrationInitValue());
        entity.setFieldCalibrationTypeCode(cmd.getFieldCalibrationTypeCode());
        entity.setFieldCalibrationTypeName(cmd.getFieldCalibrationTypeName());
        entity.setDualChannelFlag(cmd.getDualChannelFlag());

        QualFilingEquipmentEntity result = qualFilingEquipmentDomainService.modify(entity);
        return SingleResponse.success(toCO(result));
    }

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

    @Override
    public PageResponse<QualFilingEquipmentCO> page(QualFilingEquipmentPageQuery query) {
        QualFilingEquipmentQuery domainQuery = new QualFilingEquipmentQuery();
        domainQuery.setPageNum(query.getCurrent());
        domainQuery.setPageSize(query.getSize());
        domainQuery.setTenantId(AuthUserContextAdapter.getCurrentTenantId());
        domainQuery.setFilingId(query.getFilingId());
        domainQuery.setDeviceName(query.getDeviceName());

        PageResult<QualFilingEquipmentEntity> pageResult = qualFilingEquipmentDomainService.page(domainQuery);

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

    @javax.annotation.Resource
    private org.qinan.safetyeval.app.orchestrator.QualFilingOrchestrator qualFilingOrchestrator;

    @javax.annotation.Resource
    private org.qinan.safetyeval.app.support.QualFilingAttachmentHelper attachmentHelper;

    @javax.annotation.Resource
    private org.qinan.safetyeval.app.support.QualFilingStatusGuard statusGuard;

    @javax.annotation.Resource
    private org.qinan.safetyeval.domain.gateway.QualFilingGateway qualFilingGateway;

    @Override
    public SingleResponse<Integer> batchAddFromOrg(org.qinan.safetyeval.client.dto.QualFilingEquipmentBatchAddCmd cmd) {
        int count = qualFilingOrchestrator.batchAddEquipment(cmd.getFilingId(), cmd.getSourceEquipmentIds());
        return SingleResponse.success(count);
    }

    @Override
    public SingleResponse<QualFilingEquipmentCO> uploadCalibration(org.qinan.safetyeval.client.dto.QualFilingAttachmentUploadCmd cmd) {
        QualFilingEquipmentEntity equipment = qualFilingEquipmentDomainService.get(cmd.getId());
        if (equipment == null) {
            throw new org.qinan.safetyeval.domain.exception.BizException(
                    org.qinan.safetyeval.domain.exception.ErrorCode.QUAL_FILING_EQUIPMENT_NOT_FOUND);
        }
        statusGuard.ensureEditable(qualFilingGateway.get(equipment.getFilingId()));
        equipment.setCalibrationReportUrl(attachmentHelper.resolveUrl(cmd.getAttachmentUrl()));
        QualFilingEquipmentEntity saved = qualFilingEquipmentDomainService.modify(equipment);
        return SingleResponse.success(toCO(saved));
    }

    private QualFilingEquipmentCO toCO(QualFilingEquipmentEntity entity) {
        if (entity == null) {
            return null;
        }
        QualFilingEquipmentCO co = new QualFilingEquipmentCO();
        co.setId(entity.getId());
        co.setFilingId(entity.getFilingId());
        co.setSourceEquipmentId(entity.getSourceEquipmentId());
        co.setDeviceName(entity.getDeviceName());
        co.setDeviceModel(entity.getDeviceModel());
        co.setInstrumentTypeCode(entity.getInstrumentTypeCode());
        co.setInstrumentTypeName(entity.getInstrumentTypeName());
        co.setDeviceTypeCode(entity.getDeviceTypeCode());
        co.setDeviceTypeName(entity.getDeviceTypeName());
        co.setManufacturer(entity.getManufacturer());
        co.setFlowDesc(entity.getFlowDesc());
        co.setMinFlow(entity.getMinFlow());
        co.setMaxFlow(entity.getMaxFlow());
        co.setCalibrationUnit(entity.getCalibrationUnit());
        co.setCalibrationInitValue(entity.getCalibrationInitValue());
        co.setFieldCalibrationTypeCode(entity.getFieldCalibrationTypeCode());
        co.setFieldCalibrationTypeName(entity.getFieldCalibrationTypeName());
        co.setDualChannelFlag(entity.getDualChannelFlag());
        co.setCalibrationReportUrl(entity.getCalibrationReportUrl());
        co.setTenantId(entity.getTenantId());
        return co;
    }
}
