package org.qinan.safetyeval.app.executor;

import org.qinan.safetyeval.client.api.QualFilingCommitmentApi;
import org.qinan.safetyeval.client.dto.PageResponse;
import org.qinan.safetyeval.client.dto.SingleResponse;
import org.qinan.safetyeval.client.co.QualFilingCommitmentCO;
import org.qinan.safetyeval.client.dto.QualFilingCommitmentAddCmd;
import org.qinan.safetyeval.client.dto.QualFilingCommitmentModifyCmd;
import org.qinan.safetyeval.client.dto.QualFilingCommitmentPageQuery;
import org.qinan.safetyeval.domain.entity.QualFilingCommitmentEntity;
import org.qinan.safetyeval.domain.query.QualFilingCommitmentQuery;
import org.qinan.safetyeval.domain.query.PageResult;
import org.qinan.safetyeval.domain.service.QualFilingCommitmentDomainService;
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 QualFilingCommitmentExecutor implements QualFilingCommitmentApi {

    @Lazy
    @Autowired(required = false)
    private QualFilingCommitmentDomainService qualFilingCommitmentDomainService;

    @Override
    public SingleResponse<QualFilingCommitmentCO> add(QualFilingCommitmentAddCmd cmd) {
        QualFilingCommitmentEntity entity = new QualFilingCommitmentEntity();
        entity.setCommitmentContent(cmd.getCommitmentContent());
        entity.setLegalRepSignatureUrl(cmd.getLegalRepSignatureUrl());
        entity.setSignDate(cmd.getSignDate());
        entity.setLegalRepPersonnelId(cmd.getLegalRepPersonnelId());
        entity.setLegalRepName(cmd.getLegalRepName());

        QualFilingCommitmentEntity result = qualFilingCommitmentDomainService.add(entity);
        return SingleResponse.success(toCO(result));
    }

    @Override
    public SingleResponse<QualFilingCommitmentCO> get(Long id) {
        QualFilingCommitmentEntity entity = qualFilingCommitmentDomainService.get(id);
        return SingleResponse.success(toCO(entity));
    }

    @Override
    public SingleResponse<QualFilingCommitmentCO> modify(QualFilingCommitmentModifyCmd cmd) {
        QualFilingCommitmentEntity entity = new QualFilingCommitmentEntity();
        entity.setId(cmd.getId());
        entity.setCommitmentContent(cmd.getCommitmentContent());
        entity.setLegalRepSignatureUrl(cmd.getLegalRepSignatureUrl());
        entity.setSignDate(cmd.getSignDate());
        entity.setLegalRepPersonnelId(cmd.getLegalRepPersonnelId());
        entity.setLegalRepName(cmd.getLegalRepName());

        QualFilingCommitmentEntity result = qualFilingCommitmentDomainService.modify(entity);
        return SingleResponse.success(toCO(result));
    }

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

    @Override
    public PageResponse<QualFilingCommitmentCO> page(QualFilingCommitmentPageQuery query) {
        QualFilingCommitmentQuery domainQuery = new QualFilingCommitmentQuery();
        domainQuery.setPageNum(query.getCurrent());
        domainQuery.setPageSize(query.getSize());
        domainQuery.setTenantId(AuthUserContextAdapter.getCurrentTenantId());
        domainQuery.setFilingId(query.getFilingId());

        PageResult<QualFilingCommitmentEntity> pageResult = qualFilingCommitmentDomainService.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.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;

    @javax.annotation.Resource
    private org.qinan.safetyeval.domain.gateway.QualFilingCommitmentGateway qualFilingCommitmentGateway;

    @Override
    public SingleResponse<QualFilingCommitmentCO> saveOrUpdate(QualFilingCommitmentModifyCmd cmd) {
        Long filingId = cmd.getFilingId();
        QualFilingCommitmentEntity existing = null;
        if (cmd.getId() != null) {
            existing = qualFilingCommitmentGateway.get(cmd.getId());
            if (existing != null) {
                filingId = existing.getFilingId();
            }
        }
        if (filingId == null) {
            throw new org.qinan.safetyeval.domain.exception.BizException(
                    org.qinan.safetyeval.domain.exception.ErrorCode.QUAL_FILING_COMMITMENT_NOT_FOUND, "filingId不能为空");
        }
        if (existing == null) {
            existing = qualFilingCommitmentGateway.getByFilingId(filingId);
        }
        statusGuard.ensureEditable(qualFilingGateway.get(filingId));
        if (existing == null) {
            QualFilingCommitmentEntity entity = new QualFilingCommitmentEntity();
            entity.setFilingId(filingId);
            entity.setCommitmentContent(cmd.getCommitmentContent());
            entity.setLegalRepSignatureUrl(cmd.getLegalRepSignatureUrl());
            entity.setSignDate(cmd.getSignDate());
            entity.setLegalRepPersonnelId(cmd.getLegalRepPersonnelId());
            entity.setLegalRepName(cmd.getLegalRepName());
            return SingleResponse.success(toCO(qualFilingCommitmentDomainService.add(entity)));
        }
        existing.setCommitmentContent(cmd.getCommitmentContent());
        existing.setLegalRepSignatureUrl(cmd.getLegalRepSignatureUrl());
        existing.setSignDate(cmd.getSignDate());
        existing.setLegalRepPersonnelId(cmd.getLegalRepPersonnelId());
        existing.setLegalRepName(cmd.getLegalRepName());
        return SingleResponse.success(toCO(qualFilingCommitmentDomainService.modify(existing)));
    }

    @Override
    public SingleResponse<QualFilingCommitmentCO> uploadSignature(org.qinan.safetyeval.client.dto.QualFilingAttachmentUploadCmd cmd) {
        QualFilingCommitmentEntity existing = qualFilingCommitmentGateway.get(cmd.getId());
        if (existing == null) {
            throw new org.qinan.safetyeval.domain.exception.BizException(
                    org.qinan.safetyeval.domain.exception.ErrorCode.QUAL_FILING_COMMITMENT_NOT_FOUND);
        }
        statusGuard.ensureEditable(qualFilingGateway.get(existing.getFilingId()));
        existing.setLegalRepSignatureUrl(attachmentHelper.resolveUrl(cmd.getAttachmentUrl()));
        return SingleResponse.success(toCO(qualFilingCommitmentDomainService.modify(existing)));
    }

    private QualFilingCommitmentCO toCO(QualFilingCommitmentEntity entity) {
        if (entity == null) {
            return null;
        }
        QualFilingCommitmentCO co = new QualFilingCommitmentCO();
        co.setId(entity.getId());
        co.setFilingId(entity.getFilingId());
        co.setCommitmentContent(entity.getCommitmentContent());
        co.setLegalRepSignatureUrl(entity.getLegalRepSignatureUrl());
        co.setSignDate(entity.getSignDate());
        co.setLegalRepPersonnelId(entity.getLegalRepPersonnelId());
        co.setLegalRepName(entity.getLegalRepName());
        co.setTenantId(entity.getTenantId());
        return co;
    }
}
