package com.eitc.quartz.task;


import com.eitc.common.monitor.FileSizeMonitor;
import com.eitc.common.utils.InterfaceVerificationUtil;
import com.eitc.common.utils.ShellUtils;
import com.eitc.common.utils.spring.SpringUtils;
import com.eitc.patient.domain.ClinicInfo;
import com.eitc.patient.service.IClinicInfoService;
import com.eitc.patient.vo.ClinicInfoVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;
import org.springframework.web.client.ResponseExtractor;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;










@Component("sysClinicInfoTask")
public class SysClinicInfoTask {
    @Resource
    private RestTemplate restTemplate;

    @Value("${Total.ip}")
    private String fileUrl;

    private final IClinicInfoService clinicInfoService = SpringUtils.getBean(IClinicInfoService.class);

    /**
     * 定时获取履约信息
     * @return
     */
    public void getFulfillmentInformation() {
        List<ClinicInfo> list = clinicInfoService.list();
        if (!list.isEmpty()) {
            ClinicInfo clinicInfo = list.get(0);
            Map<String, Object> uriVariables = new HashMap<>();
//        final String plainText = "{\"phone\":\"12345678901\",\"serverCode\":\"ED39BA70-393D-4B28-ADE6-68184C0D6BAC\",\"clinicIp\":\"192.168.3.17\"}";
//        SM4Utils.encryptHex_CBC(plainText,uriVariables);
            String saSignStr = InterfaceVerificationUtil.getSaSignStr(uriVariables);
            ResponseExtractor<Boolean> responseExtractor = clientHttpResponse -> {

                // 开启线程 下载版本并且修改数据版本
                HttpHeaders headers = clientHttpResponse.getHeaders();
                // 设置响应头，直接用第三方文件服务的响应头
                clientHttpResponse.getHeaders().forEach((name, values) -> {
                    if (name.equals("versionRepair")) {
                        clinicInfo.setVersionRepairNew(values.get(0));
                    }
                    if (name.equals("versionInfo")) {
                        clinicInfo.setVersionInfoNew(values.get(0));
                    }

                });
                clinicInfoService.updateById(clinicInfo);
                getVersionChanges(headers);
                return true;
            };
            String url = fileUrl + "api/sys/clinict/getClinictListInfo" + "?" + saSignStr;
            restTemplate.execute(url, HttpMethod.GET, null, responseExtractor, uriVariables);
        }
    }

    /**
     * 拉取文件流操作
     * @param headers
     */
//    @Async(value = "CommonThreadPoolExecutor")
    public void getVersionChanges(HttpHeaders headers) {
        Integer version = 0;
        ClinicInfoVO clinicInfo = clinicInfoService.findClinicInfo();
        if (!clinicInfo.getVersionInfo().equals(clinicInfo.getVersionInfoNew())){
            // 购买版本的版本号
             version = 1;
        }
        if (!clinicInfo.getVersionRepair().equals(clinicInfo.getVersionRepairNew())){
            // bug版本的版本对比
             version = 2;
        }
        if(version != 0){
            String url = fileUrl+"api/sys/clinict/downloadLocal?";
            Map<String, Object> uriVariables = new HashMap<>();
            uriVariables.put("version",version);
            // 这个是为了防止恶意请求来做的参数增加
            String saSignStr = InterfaceVerificationUtil.getSaSignStr(uriVariables);

            Integer finalVersion = version;
            ResponseExtractor<Boolean> responseExtractor = clientHttpResponse -> {
                // 设置响应头，直接用第三方文件服务的响应头
                AtomicLong fileLength = new AtomicLong();
                AtomicReference<String> vCode = new AtomicReference<>("");
                AtomicReference<String> repairCode = new AtomicReference<>("");
                // 获取请求头信息
                clientHttpResponse.getHeaders().forEach((name, values) -> {
                    if (name.equals("Content-Length")) {
                        fileLength.set(Long.parseLong(values.get(0)));
                    }
                    if (name.equals("vCode")) {
                        vCode.set(values.get(0));
                    }
                    if (name.equals("Content-Length")) {
                        repairCode.set(values.get(0));
                    }
                    if (name.equals("Content-Type")) {
                        if (!values.get(0).equals("application/octet-stream")){
                            throw new RuntimeException("文件下载失败");
                        }
                    }
                });

                String versionStr = vCode.get();
                if (finalVersion == 2){
                    versionStr = repairCode.get();
                }
                String path = "/home/uppackage/server_" + versionStr + ".tar"; // 文件的URL地址
//                String path = "F:\\Desktop\\test\\server_" + versionStr + ".tar"; // 文件的URL地址
//            String path = "F:\\Desktop\\test\\server_"+versionStr+".tar"; // 文件的URL地址
                try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(Files.newOutputStream(Paths.get(path)))) {
                    // 这是我想监控文件下载多少而做的线程监控 可以做进度条给前端
                    FileSizeMonitor monitor = new FileSizeMonitor(new File(path),fileLength.get());
                    monitor.startMonitoring();
                    StreamUtils.copy(clientHttpResponse.getBody(), bufferedOutputStream);
                    clinicInfo.setVersionInfo(clinicInfo.getVersionInfoNew());
                    clinicInfo.setVersionRepair(clinicInfo.getVersionRepairNew());
                    clinicInfoService.updateById(clinicInfo);
                } catch (IOException e) {
                    // 处理异常，比如文件找不到或读写错误
                    System.err.println("文件下载失败: " + e.getMessage());
                    throw new RuntimeException("文件下载失败" + e.getMessage());
                }
                return true;
            };
            restTemplate.execute(url+saSignStr, HttpMethod.GET, null, responseExtractor, uriVariables);
        }
    }

}
