package com.miyzh.controller;

import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.miyzh.entity.*;
import com.miyzh.mapper.prod.InsDSettlementMapper;
import com.miyzh.service.UploadExceptionLogService;
import com.miyzh.service.UploadService;
import com.miyzh.service.WebSocketService;
import com.miyzh.utils.CsvUtil;
import com.miyzh.utils.DateUtils;
import com.miyzh.utils.DesUtil;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.XmlFriendlyReplacer;
import com.thoughtworks.xstream.io.xml.XppDriver;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.websocket.Session;
import javax.websocket.server.PathParam;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;

/**
 * Title: TestController
 * Description:
 *
 * @author lyt
 * @date 2020/6/11 14:26
 */
@Slf4j
@RestController
@RequestMapping("export")
public class ExportController {

    @Autowired
    private InsDSettlementMapper insDSettlementMapper;
    @Autowired
    private UploadService uploadService;
    @Autowired
    private WebSocketService webSocketService;

    @Autowired
    private UploadExceptionLogService uploadExceptionLogService;

    @Value(value = "${scheduling.startDate}")
    private String startDate;
    @Value(value = "${scheduling.endDate}")
    private String endDate;

    @Value(value = "${scheduling.rootDir}")
    private String rootDir;

    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    @RequestMapping("exportHosByDate")
    @ResponseBody
    public Map<String, Integer> retryHos(){
        Map<String, Integer> result = new HashMap<>();
        try {
            String [] arr = {"37028211914", "37028211955", "37028212025", "37028211704", "37020010511", "37028211703", "37028211943", "37028211903", "37028212056", "37028211957", "37028211970", "37028211908"};
//            String [] arr = {"37028211908"};
            List<String> clinicList = Arrays.asList(arr);
            final CountDownLatch latch = new CountDownLatch(clinicList.size());
            List<Integer> preCounts = new ArrayList<>();
            List<Integer> confCounts = new ArrayList<>();
            for(String clinicId : clinicList) {
                ClcClinicIns clinicIns = insDSettlementMapper.queryClinicIns(clinicId);
                System.out.println(clinicId + "正在查询...");
                List<InsHospitalTotalSettlement> list = insDSettlementMapper.queryAllVisitCodeByClinicIdAndDays(clinicId, startDate, endDate);
                List<String> hospitalPreSettleDataList = new ArrayList<>();
                List<String> hospitalConfirmSettleDataList = new ArrayList<>();
                for(InsHospitalTotalSettlement insHospitalTotalSettlement : list) {
                    if(!StringUtils.isEmpty(insHospitalTotalSettlement.getSettleTransactionId())) {
                        InsDSettlementDetails searchSettlementDetailsList = new InsDSettlementDetails();
                        InsDSettlement searchSettlement = new InsDSettlement();
                        searchSettlement.setClinicId(clinicId);
                        searchSettlement.setSettleTransactionId(insHospitalTotalSettlement.getSettleTransactionId());
                        InsDSettlement targetSettlement = insDSettlementMapper.queryInsDSettlementList(searchSettlement);
                        if(null == targetSettlement) {
                            break;
                        }
                        searchSettlementDetailsList.setClinicId(clinicId);
                        searchSettlementDetailsList.setVisitCode(insHospitalTotalSettlement.getVisitCode());
                        List<InsDSettlementDetails> settlementDetailsList = insDSettlementMapper.queryAllInsDSettlementByVisitCode(searchSettlementDetailsList);
                        InsHospitalSign hospitalSign = insDSettlementMapper.queryInsHospitalSign(insHospitalTotalSettlement.getVisitCode(), insHospitalTotalSettlement.getPatientId(), clinicId);
                        if(null != hospitalSign) {
                            hospitalPreSettleDataList.add(uploadService.hospitalPreSettleData(targetSettlement,settlementDetailsList,hospitalSign, clinicIns).getUploadInfo());
                            if("1".equals(insHospitalTotalSettlement.getTransactionType())) {
                                hospitalConfirmSettleDataList.add(uploadService.hospitalConfirmSettleData(clinicIns,insHospitalTotalSettlement.getVisitCode(),0).getUploadInfo());
                            } else if("2".equals(insHospitalTotalSettlement.getTransactionType())) {
                                hospitalConfirmSettleDataList.add(uploadService.hospitalConfirmSettleData(clinicIns,insHospitalTotalSettlement.getVisitCode(),2).getUploadInfo());
                            }
                        }
                    }
                }
                if(hospitalPreSettleDataList.size() > 0){
                    System.out.println(clinicId + "主单开始写入");
                    String fileName = "hospitalPreSettleData-" + clinicId;
                    CsvUtil.writeCsv(rootDir, fileName, clinicIns.getInsCode(), hospitalPreSettleDataList, "uploadPatBillInfo");
                    System.out.println(clinicId + "主单全部导入成功");
                }
                if(hospitalConfirmSettleDataList.size() > 0){
                    System.out.println(clinicId + "结算状态开始写入");
                    String fileName = "hospitalConfirmSettleData-" + clinicId;
                    CsvUtil.writeCsv(rootDir, fileName, clinicIns.getInsCode(), hospitalConfirmSettleDataList, "uploadDocStatus");
                    System.out.println(clinicId + "结算状态全部导入成功");
                }
                preCounts.add(hospitalPreSettleDataList.size());
                confCounts.add(hospitalConfirmSettleDataList.size());
                latch.countDown();
            }
            try {
                latch.await();
                int preCount = preCounts.stream().reduce(Integer::sum).orElse(0);
                int confCount = confCounts.stream().reduce(Integer::sum).orElse(0);
                System.out.println("结束");
                result.put("preDateCount", preCount);
                result.put("confDateCount", confCount);
                return result;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @RequestMapping("exportCliByDate")
    @ResponseBody
    public Map<String, Integer> retryCli(){
        Map<String, Integer> result = new HashMap<>();
        try {
            String [] arr = {"37028212025", "37028211957","37028211914", "37028211955", "37028211704", "37020010511", "37028211703", "37028211943", "37028211903", "37028212056", "37028211970", "37028212050", "37028212073"};
//            String [] arr = {"37028211908"};
            List<String> clinicList = Arrays.asList(arr);
            List<Integer> preCounts = new ArrayList<>();
            List<Integer> confCounts = new ArrayList<>();
            for(String clinicId : clinicList) {
                ClcClinicIns clinicIns = insDSettlementMapper.queryClinicIns(clinicId);
                System.out.println(clinicId + "正在查询...");
                List<InsClinicSettlement> list = insDSettlementMapper.queryAllVisitCodeByClinicIdCliAndDays(clinicId, startDate, endDate);
                List<String> clinicPreSettleDataList = new ArrayList<>();
                List<String> clinicConfirmSettleDataList = new ArrayList<>();
                for(InsClinicSettlement insClinicSettlement : list) {
                    if(!StringUtils.isEmpty(insClinicSettlement.getSettleTransactionId())) {
                        InsDSettlementDetails searchSettlementDetailsList = new InsDSettlementDetails();
                        InsDSettlement searchSettlement = new InsDSettlement();
                        searchSettlement.setClinicId(clinicId);
                        searchSettlement.setSettleTransactionId(insClinicSettlement.getSettleTransactionId());
                        InsDSettlement targetSettlement = insDSettlementMapper.queryInsDSettlementList(searchSettlement);
                        if(null == targetSettlement) {
                            break;
                        }
                        searchSettlementDetailsList.setClinicId(clinicId);
                        searchSettlementDetailsList.setPrescriptionId(insClinicSettlement.getPrescriptionId());
                        List<InsDSettlementDetails> settlementDetailsList = insDSettlementMapper.queryAllInsDSettlementByPrescriptionId(searchSettlementDetailsList);
                        clinicPreSettleDataList.add(uploadService.clinicPreSettleData(targetSettlement,insClinicSettlement,settlementDetailsList, clinicIns).getUploadInfo());
                        if("1".equals(insClinicSettlement.getTransforType())) {
                            clinicConfirmSettleDataList.add(uploadService.clinicConfirmSettleData(clinicIns,insClinicSettlement.getVisitCode(),0).getUploadInfo());
                        } else if("2".equals(insClinicSettlement.getTransforType())) {
                            clinicConfirmSettleDataList.add(uploadService.clinicConfirmSettleData(clinicIns,insClinicSettlement.getVisitCode(),2).getUploadInfo());
                        }
                    }
                }
                if(clinicPreSettleDataList.size() > 0){
                    System.out.println(clinicId + "主单开始写入");
                    String fileName = "clinicPreSettleData-" + clinicId;
                    CsvUtil.writeCsv(rootDir, fileName, clinicIns.getInsCode(), clinicPreSettleDataList, "uploadPatBillInfo");
                    System.out.println(clinicId + "主单全部导入成功");
                }
                if(clinicConfirmSettleDataList.size() > 0){
                    System.out.println(clinicId + "结算状态开始写入");
                    String fileName = "clinicConfirmSettleData-" + clinicId;
                    CsvUtil.writeCsv(rootDir, fileName, clinicIns.getInsCode(), clinicConfirmSettleDataList, "uploadDocStatus");
                    System.out.println(clinicId + "结算状态全部导入成功");
                }
                preCounts.add(clinicPreSettleDataList.size());
                confCounts.add(clinicConfirmSettleDataList.size());
            }
            int preCount = preCounts.stream().reduce(Integer::sum).orElse(0);
            int confCount = confCounts.stream().reduce(Integer::sum).orElse(0);
            System.out.println("结束");
            result.put("preDateCount", preCount);
            result.put("confDateCount", confCount);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;

    }

    @RequestMapping("updateHosByDate")
    @ResponseBody
    public Map<String, Integer> updateHosByDays(){
        Map<String, Integer> result = new HashMap<>();
        try {
            String [] arr = {"37028211914", "37028211955", "37028212025", "37028211704", "37020010511", "37028211703", "37028211943", "37028211903", "37028212056", "37028211957", "37028211970", "37028212073"};
//            String [] arr = {"37028211908"};
            List<String> clinicList = Arrays.asList(arr);
            List<Integer> preCounts = new ArrayList<>();
            List<Integer> confCounts = new ArrayList<>();
            for(String clinicId : clinicList) {
                new Thread(() -> {
                    ClcClinicIns clinicIns = insDSettlementMapper.queryClinicIns(clinicId);
                    System.out.println(clinicId + "正在查询...");
                    List<InsHospitalTotalSettlement> list = insDSettlementMapper.queryAllVisitCodeByClinicIdAndDays(clinicId, startDate, endDate);
                    List<UploadExceptionLog> hospitalPreSettleDataList = new ArrayList<>();
                    List<UploadExceptionLog> hospitalConfirmSettleDataList = new ArrayList<>();
                    for(InsHospitalTotalSettlement insHospitalTotalSettlement : list) {
                        if(!StringUtils.isEmpty(insHospitalTotalSettlement.getSettleTransactionId())) {
                            InsDSettlementDetails searchSettlementDetailsList = new InsDSettlementDetails();
                            InsDSettlement searchSettlement = new InsDSettlement();
                            searchSettlement.setClinicId(clinicId);
                            searchSettlement.setSettleTransactionId(insHospitalTotalSettlement.getSettleTransactionId());
                            InsDSettlement targetSettlement = insDSettlementMapper.queryInsDSettlementList(searchSettlement);
                            searchSettlementDetailsList.setClinicId(clinicId);
                            searchSettlementDetailsList.setVisitCode(insHospitalTotalSettlement.getVisitCode());
                            List<InsDSettlementDetails> settlementDetailsList = insDSettlementMapper.queryAllInsDSettlementByVisitCode(searchSettlementDetailsList);
                            InsHospitalSign hospitalSign = insDSettlementMapper.queryInsHospitalSign(insHospitalTotalSettlement.getVisitCode(), insHospitalTotalSettlement.getPatientId(), clinicId);
                            if(null != hospitalSign) {
                                hospitalPreSettleDataList.add(uploadService.hospitalPreSettleData(targetSettlement,settlementDetailsList,hospitalSign, clinicIns));
                                if("1".equals(insHospitalTotalSettlement.getTransactionType())) {
                                    hospitalConfirmSettleDataList.add(uploadService.hospitalConfirmSettleData(clinicIns,insHospitalTotalSettlement.getVisitCode(),0));
                                } else if("2".equals(insHospitalTotalSettlement.getTransactionType())) {
                                    hospitalConfirmSettleDataList.add(uploadService.hospitalConfirmSettleData(clinicIns,insHospitalTotalSettlement.getVisitCode(),2));
                                }
                            }
                        }
                    }
                    if(hospitalPreSettleDataList.size() > 0){
                        for(UploadExceptionLog uploadExceptionLog : hospitalPreSettleDataList) {
                            uploadService.upload(uploadExceptionLog);
                        }
                    }
                    if(hospitalConfirmSettleDataList.size() > 0){
                        for(UploadExceptionLog uploadExceptionLog : hospitalPreSettleDataList) {
                            uploadExceptionLogService.saveUploadDocStatusReq(uploadExceptionLog);
                        }
                    }
                    preCounts.add(hospitalPreSettleDataList.size());
                    confCounts.add(hospitalConfirmSettleDataList.size());
                }).start();
            }
            int preCount = preCounts.stream().reduce(Integer::sum).orElse(0);
            int confCount = confCounts.stream().reduce(Integer::sum).orElse(0);
            System.out.println("结束");
            result.put("preDateCount", preCount);
            result.put("confDateCount", confCount);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    @RequestMapping("updateCliByDate")
    @ResponseBody
    public Map<String, Integer> updateCliByDays(){
        Map<String, Integer> result = new HashMap<>();
        try {
            String [] arr = {"37028211957","37028211914", "37028211955", "37028212025", "37028211704", "37020010511", "37028211703", "37028211943", "37028211903", "37028212056", "37028211970"};
            List<String> clinicList = Arrays.asList(arr);
            List<Integer> preCounts = new ArrayList<>();
            List<Integer> confCounts = new ArrayList<>();
            for(String clinicId : clinicList) {
                new Thread(() -> {
                    ClcClinicIns clinicIns = insDSettlementMapper.queryClinicIns(clinicId);
                    System.out.println(clinicId + "正在查询...");
                    List<InsClinicSettlement> list = insDSettlementMapper.queryAllVisitCodeByClinicIdCliAndDays(clinicId, startDate, endDate);
                    List<UploadExceptionLog> clinicPreSettleDataList = new ArrayList<>();
                    List<UploadExceptionLog> clinicConfirmSettleDataList = new ArrayList<>();
                    for(InsClinicSettlement insClinicSettlement : list) {
                        if(!StringUtils.isEmpty(insClinicSettlement.getSettleTransactionId())) {
                            InsDSettlementDetails searchSettlementDetailsList = new InsDSettlementDetails();
                            InsDSettlement searchSettlement = new InsDSettlement();
                            searchSettlement.setClinicId(clinicId);
                            searchSettlement.setSettleTransactionId(insClinicSettlement.getSettleTransactionId());
                            InsDSettlement targetSettlement = insDSettlementMapper.queryInsDSettlementList(searchSettlement);
                            searchSettlementDetailsList.setClinicId(clinicId);
                            searchSettlementDetailsList.setPrescriptionId(insClinicSettlement.getPrescriptionId());
                            List<InsDSettlementDetails> settlementDetailsList = insDSettlementMapper.queryAllInsDSettlementByPrescriptionId(searchSettlementDetailsList);
                            clinicPreSettleDataList.add(uploadService.clinicPreSettleData(targetSettlement,insClinicSettlement,settlementDetailsList, clinicIns));
                            if("1".equals(insClinicSettlement.getTransforType())) {
                                clinicConfirmSettleDataList.add(uploadService.clinicConfirmSettleData(clinicIns,insClinicSettlement.getVisitCode(),0));
                            } else if("2".equals(insClinicSettlement.getTransforType())) {
                                clinicConfirmSettleDataList.add(uploadService.clinicConfirmSettleData(clinicIns,insClinicSettlement.getVisitCode(),2));
                            }
                        }
                    }
                    if(clinicPreSettleDataList.size() > 0){
                        for(UploadExceptionLog uploadExceptionLog : clinicPreSettleDataList) {
                            uploadService.upload(uploadExceptionLog);
                        }
                    }
                    if(clinicConfirmSettleDataList.size() > 0){
                        for(UploadExceptionLog uploadExceptionLog : clinicConfirmSettleDataList) {
                            uploadExceptionLogService.saveUploadDocStatusReq(uploadExceptionLog);
                        }
                    }
                    preCounts.add(clinicPreSettleDataList.size());
                    confCounts.add(clinicConfirmSettleDataList.size());
                }).start();
            }
            int preCount = preCounts.stream().reduce(Integer::sum).orElse(0);
            int confCount = confCounts.stream().reduce(Integer::sum).orElse(0);
            System.out.println("结束");
            result.put("preDateCount", preCount);
            result.put("confDateCount", confCount);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;

    }


    @RequestMapping("uploadYesterdayOrder")
    @ResponseBody
    public Integer uploadYesterdayOrder(@RequestParam String sid){
        Session session = webSocketService.generateSession(sid);
        List<UploadExceptionLog> list = uploadExceptionLogService.listUploadPatbillInfo();
        int progress = 0;
        if (null != list && list.size() > 0) {
            for(int i = 0; i < list.size(); i ++) {
                progress = (i + 1) / list.size() * 100;
                if(null != session) {
                    try{
                        webSocketService.sendMessage(session, String.valueOf(progress) + "%");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                log.info("开始上传:" + list.get(i).getTradeCode() + ":" + list.get(i).getSerialNumber());
                uploadService.upload(list.get(i));
            }
            return list.size();
        }
        return 0;
    }

    @RequestMapping("uploadYesterdayDocStatus")
    @ResponseBody
    public Integer uploadYesterdayDocStatus(){
        List<UploadExceptionLog> list = uploadExceptionLogService.listUploadDocStatus();
        if (null != list && list.size() > 0) {
            list.stream().forEach(item -> {
                log.info("开始上传:" + item.getTradeCode() + ":" + item.getSerialNumber());
                uploadService.upload(item);
            });
            return list.size();
        }
        return 0;
    }




}
