package com.docus.server.collect.report.listener;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.web.api.CommonResult;
import com.docus.infrastructure.web.api.ResultCode;
import com.docus.server.archivefile.infrastructure.dto.ReportDTO;
import com.docus.server.archivefile.infrastructure.entity.AfReportRecord;
import com.docus.server.archivefile.infrastructure.mapper.AfReportRecordMapper;
import com.docus.server.collect.report.event.TaskConsumptionReportDownEvent;
import com.docus.server.collect.report.event.ThreePartyPushReportDownEvent;
import com.docus.server.collect.web.common.pojo.dto.ReportDownDTO;
import com.docus.server.collect.web.common.pojo.dto.ReportDownPatientDTO;
import com.docus.server.collect.web.common.pojo.dto.ReportDownScanFileDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 上报下载监听
 *
 * @author wyb
 */
@Component
@Slf4j
public class ReportDownListener {
    @Resource
    private AfReportRecordMapper afReportRecordMapper;

    @EventListener
    @Async("threadPoolExecutor")
    public void threePartyPushReportDown(ThreePartyPushReportDownEvent threePartyPushReportDownEvent) {
        // 根据任务id获取上报记录信息
        AfReportRecord afReportRecord = afReportRecordMapper.getReportRecordInfoByTaskId(threePartyPushReportDownEvent.getTaskId());

        // 组织基础信息数据
        ReportDownPatientDTO reportDownPatientDto = new ReportDownPatientDTO(afReportRecord);

        // 组织文件数据
        List<ReportDownScanFileDTO> reportDownScanFileDtos = new ArrayList<>(5);
        ReportDownScanFileDTO reportDownScanFileDto = new ReportDownScanFileDTO(afReportRecord);
        reportDownScanFileDtos.add(reportDownScanFileDto);

        // 组织下载数据，基础信息和文件数据
        ReportDownDTO reportDownDto = new ReportDownDTO();
        reportDownDto.setAssortid(afReportRecord.getZdAssortId());
        reportDownDto.setCollectorid(afReportRecord.getSysflag());
        reportDownDto.setScanusercode("admin");
        reportDownDto.setScanusername("admin");
        reportDownDto.setPatient(reportDownPatientDto);
        reportDownDto.setScanfiles(reportDownScanFileDtos);

        // 下面是调用下载服务

        String requestParam = Func.toJson(reportDownDto);
        try {
            log.info("调用下载服务，地址：{} ，参数：{}", "http://localhost:9291/api/downplatform/report", requestParam);
            String respBody = post("http://localhost:9291/api/downplatform/report", requestParam);
            log.info("调用下载服务成功,响应参数：{}", respBody);
            CommonResult commonResult = Func.readJson(respBody, CommonResult.class);
            if (ResultCode.SUCCESS.getCode().equals(commonResult.getCode())) {
                // 下载返回了成功更新状态
                afReportRecordMapper.updateStateByTaskId(threePartyPushReportDownEvent.getTaskId());
            }
        } catch (Exception e) {
            log.error("调用下载服务失败", e);
        }
    }


    @EventListener
    @Async("threadPoolExecutor")
    public void taskConsumptionReporDown(TaskConsumptionReportDownEvent taskConsumptionReportDownEvent) {
        ReportDTO reportDto = taskConsumptionReportDownEvent.getReportDTO();
        // 组织基础信息数据
        ReportDownPatientDTO reportDownPatientDto = new ReportDownPatientDTO(reportDto);

        // 组织文件数据
        List<ReportDownScanFileDTO> reportDownScanFileDtos = new ArrayList<>(5);
        ReportDownScanFileDTO reportDownScanFileDto = new ReportDownScanFileDTO(reportDto);
        reportDownScanFileDtos.add(reportDownScanFileDto);

        // 组织下载数据，基础信息和文件数据
        ReportDownDTO reportDownDto = new ReportDownDTO();
        reportDownDto.setAssortid(reportDto.getAssortId());
        reportDownDto.setCollectorid(reportDto.getSysFlag());
        reportDownDto.setScanusercode("admin");
        reportDownDto.setScanusername("admin");
        reportDownDto.setPatient(reportDownPatientDto);
        reportDownDto.setScanfiles(reportDownScanFileDtos);

        // 下面是调用下载服务
        String requestParam = Func.toJson(reportDownDto);
        try {
            log.info("调用下载服务，地址：{} ，参数：{}", "http://localhost:9291/api/downplatform/report", requestParam);
            String respBody = post("http://localhost:9291/api/downplatform/report", requestParam);
            log.info("调用下载服务成功,响应参数：{}", respBody);
        } catch (Exception e) {
            log.error("调用下载服务失败", e);
        }
    }

    private final static Lock HTTP_POST_LOCK = new ReentrantLock();

    public String post(String url, String body) {
        HTTP_POST_LOCK.lock();
        try {
            HttpRequest post = HttpUtil.createPost(url);
            post.timeout(5 * 1000);
            post.header("Content-Type", "application/json; charset=utf-8");
            post.body(body);
            HttpResponse response = post.execute();
            return response.body();
        } finally {
            HTTP_POST_LOCK.unlock();
        }
    }
}
