package com.yeejoin.amos.api.openapi.face.service;


import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.api.openapi.face.model.TmCylinderInfoModel;
import com.yeejoin.amos.api.openapi.face.orm.dao.ESCylinderInfoRepository;
import com.yeejoin.amos.api.openapi.face.orm.dao.TmCylinderInfoMapper;
import com.yeejoin.amos.api.openapi.face.orm.entity.TmCylinderInfo;
import com.yeejoin.amos.api.openapi.feign.TzsJgServiceFeignClient;
import com.yeejoin.amos.api.openapi.listener.event.FileToBeDeleteEvent;
import com.yeejoin.amos.api.openapi.publisher.EventPublisher;
import com.yeejoin.amos.api.openapi.service.MyBaseServiceImpl;
import com.yeejoin.amos.api.openapi.util.FileDeleteUtil;
import com.yeejoin.amos.api.openapi.util.MultiFieldKey;
import com.yeejoin.amos.boot.module.cylinder.flc.api.mapper.CylinderInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.util.*;
import java.util.stream.Collectors;


/**
 * <pre>
 * 气瓶基本信息 服务类
 * </pre>
 *
 * @author gwb
 * @version $Id: ElevatorService.java, v 0.1 2021年9月30日 下午3:28:55 gwb Exp $
 */
@Component
@Slf4j
public class TmCylinderInfoService extends MyBaseServiceImpl<TmCylinderInfoModel, TmCylinderInfo, TmCylinderInfoMapper> {

    @Autowired
    CylinderInfoMapper cylinderInfoMapper;

    @Autowired
    private SyncCylinderDataService syncCylinderDataService;

    @Autowired
    ESCylinderInfoRepository esCylinderInfoRepository;

    @Autowired
    private EventPublisher eventPublisher;

    @Autowired
    private TzsJgServiceFeignClient jgServiceFeignClient;

    @DSTransactional
    @Transactional(rollbackFor = {java.lang.Exception.class})
    public String createCylinderInfo(List<TmCylinderInfoModel> model) {
        if (ValidationUtil.isEmpty(model))
            throw new BadRequest("气瓶基本信息数据为空.");
        String appId = getAppId();
        Date now = new Date();
        for (TmCylinderInfoModel cylinderInfoModel : model) {
            cylinderInfoModel.setSequenceNbr(null);
            cylinderInfoModel.setRecDate(now);
            cylinderInfoModel.setAppId(appId);
        }
        // 同步至企业业务库
        syncCylinderInfo(model);

        // 保存至气瓶对接服务库
        List<TmCylinderInfo> tmCylinderInfoList = Bean.toModels(model, TmCylinderInfo.class);
        this.saveOrUpdateBatchByUniqueFields(
                tmCylinderInfoList,
                tmCylinderInfo -> new LambdaQueryWrapper<TmCylinderInfo>()
                        .eq(TmCylinderInfo::getSequenceCode, tmCylinderInfo.getSequenceCode())
                        .eq(TmCylinderInfo::getAppId, tmCylinderInfo.getAppId()),
                entity -> new MultiFieldKey(entity.getAppId(), entity.getSequenceCode()),
                "appId", "sequenceCode");
        syncCylinderDataService.createCylinderInfo2ES(model);

        // 从数据库查询tmCylinderInfoList对应信息
        LambdaQueryWrapper<TmCylinderInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(TmCylinderInfo::getAppId, tmCylinderInfoList.stream().map(TmCylinderInfo::getAppId).collect(Collectors.toList()))
                .in(TmCylinderInfo::getSequenceCode, tmCylinderInfoList.stream().map(TmCylinderInfo::getSequenceCode).collect(Collectors.toList()));
        List<TmCylinderInfo> oldList = this.baseMapper.selectList(queryWrapper);

        deleteOldFile(oldList);
        return "OK";
    }
    /**
     * 删除旧的附件
     * @param oldList 旧附件列表
     */
    private void deleteOldFile(List<TmCylinderInfo> oldList) {
        if (!ValidationUtil.isEmpty(oldList)) {
            List<String> fileUrlList = Lists.newArrayList();
            oldList.forEach(old -> {
                if (old.getProductQualified() != null) {
                    fileUrlList.addAll(Arrays.asList(ValidationUtil.isEmpty(old.getProductQualified()) ? new String[0] : old.getProductQualified().split(",")));
                }
                if (old.getProofQuality() != null) {
                    fileUrlList.addAll(Arrays.asList(ValidationUtil.isEmpty(old.getProofQuality()) ? new String[0] : old.getProofQuality().split(",")));
                }
                if (old.getSupervisionInspec() != null) {
                    fileUrlList.addAll(Arrays.asList(ValidationUtil.isEmpty(old.getSupervisionInspec()) ? new String[0] : old.getSupervisionInspec().split(",")));
                }
                if (old.getTypeExperiments() != null) {
                    fileUrlList.addAll(Arrays.asList(ValidationUtil.isEmpty(old.getTypeExperiments()) ? new String[0] : old.getTypeExperiments().split(",")));
                }
            });
            eventPublisher.publish(new FileToBeDeleteEvent(this, FileDeleteUtil.extractFileNames(fileUrlList)));
        }
    }

    /**
     * 同步气瓶信息至气瓶服务
     *
     * @param model
     */
    private void syncCylinderInfo(List<TmCylinderInfoModel> model) {
        syncCylinderDataService.syncCylinderInfo(model);
    }

    /**
     * 合规性检查
     *
     * @param sequenceCodes 气瓶序列号
     * @return 合规性检查结果
     */
    public Object complianceCheck(Map<String, List<String>> sequenceCodes) {
        try {
            if (!ValidationUtil.isEmpty(sequenceCodes) && !ValidationUtil.isEmpty(sequenceCodes.get("sequenceCodes"))) {
                List<String> sequenceCodeList = sequenceCodes.get("sequenceCodes");
                if (sequenceCodeList.size() > 100) {
                    return new HashMap<String, Object>() {{
                        put("errorMsg", "请不要一次性提交超过 100 个气瓶.");
                    }};
                }
                ResponseModel<List<Map<String, Object>>> response = jgServiceFeignClient.cylinderComplianceCheck(sequenceCodeList);
                if (response == null || response.getResult() == null) {
                    log.error("气瓶合规性检查服务调用失败，返回结果为空。请查看监管服务详细日志");
                    return new HashMap<String, Object>() {{
                        put("errorMsg", "气瓶合规性检查服务暂时不可用，请稍后重试");
                    }};
                }
                return response.getResult();
            }
        } catch (Exception e) {
            log.error("气瓶合规性检查服务调用失败", e);
            throw new BadRequest("气瓶合规性检查服务暂时不可用，请稍后重试");
        }
        return Lists.newArrayList();
    }
}
