package com.dsk.component;

import cn.hutool.core.date.DatePattern;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dsk.common.exception.ServiceException;
import com.dsk.common.utils.DateUtils;
import com.dsk.cscec.domain.CbProjectRecord;
import com.dsk.cscec.domain.CbQuantitySummary;
import com.dsk.cscec.domain.CbSubject;
import com.dsk.cscec.domain.SMaterielProject;
import com.dsk.cscec.mapper.CbSubjectMapper;
import com.dsk.cscec.service.CbProjectRecordService;
import com.dsk.cscec.service.ICbQuantitySummaryService;
import com.dsk.cscec.service.ISMaterielProjectService;
import com.glodon.cloudt.rest.client.RestServiceClient;
import com.glodon.cloudt.rest.client.data.HmacRestAuthInfo;
import com.glodon.cloudt.rest.client.data.RestResponseInfo;
import com.glodon.cloudt.rest.client.exception.AuthenticateException;
import com.glodon.cloudt.rest.client.exception.InvalidUriException;
import com.glodon.cloudt.rest.client.exception.NoAuthenticateException;
import com.glodon.cloudt.rest.client.impl.HmacRestServiceClient;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 物料相关组件
 *
 * @Author lcl
 * @Data 2024/3/14 15:56
 */
@Component
public class MaterielComponent {

    @Resource
    private ISMaterielProjectService materielProjectService;
    @Resource
    private ICbQuantitySummaryService quantitySummaryService;
    @Resource
    private CbProjectRecordService projectRecordService;
    @Resource
    private CbSubjectMapper subjectMapper;

    /**
     * 物料项目定时拉取
     */
    @Scheduled(cron = "0 0 1 20 * ? ")
    public void materielProjectPull() {
        String apiURI = "/api/inspection/v1.0/project/getTenantHasCodeProject";
        String resStr = materielRequest(apiURI);
        JSONObject jsonObject = JSONObject.parseObject(resStr);
        if (!ObjectUtils.isEmpty(jsonObject.getString("data"))) {
            List<SMaterielProject> list = JSON.parseArray(jsonObject.getString("data"), SMaterielProject.class);
            materielProjectService.saveOrUpdateBatch(list);
        }
    }

    /**
     * 物料数据定时拉取
     */
    @Scheduled(cron = "0 0 2 20 * ? ")
    public void materielDataPull() {
        String beginTimestamp = DatePattern.PURE_DATETIME_MS_FORMAT.format(DateUtils.addMonths(new Date(), -1));
        String apiURI = "/gys/inspection-api-service/integrate-v2/getSLlist?beginTimestamp=" + beginTimestamp;
        String resStr = materielRequest(apiURI);
        JSONObject jsonObject = JSONObject.parseObject(resStr);
        JSONObject data = JSONObject.parseObject(jsonObject.getString("data"));
        JSONArray bills = JSONObject.parseArray(data.getString("Bills"));
        if(ObjectUtils.isEmpty(bills)) return;
        List<CbQuantitySummary> list = new ArrayList<>();
        for (int i = 0; i < bills.size(); i++) {
            JSONObject obj = bills.getJSONObject(i);
            JSONArray bdcls = JSONObject.parseArray(obj.getString("BDCL"));
            for (int j = 0; j < bdcls.size(); j++) {
                JSONObject bean = bdcls.getJSONObject(j);
                //材料code
                String code = bean.getString("CLLBBM").substring(bean.getString("CLLBBM").lastIndexOf(".") + 1);
                CbSubject subject = subjectMapper.selectOne(Wrappers.<CbSubject>lambdaQuery().eq(CbSubject::getCode, code));
                //获取项目id 通过第三方项目id->ipm编码->系统项目id
                String projectId = bean.getString("projectId");
                if (ObjectUtils.isEmpty(projectId)) {
                    continue;
                }
                SMaterielProject materielProject = materielProjectService.getById(projectId);
                if (ObjectUtils.isEmpty(materielProject) || ObjectUtils.isEmpty(materielProject.getSyncCode())) {
                    continue;
                }
                CbProjectRecord one = projectRecordService.getOne(Wrappers.<CbProjectRecord>lambdaQuery()
                        .eq(CbProjectRecord::getIpmProjectNo, materielProject.getSyncCode())
                        .orderByDesc(CbProjectRecord::getCbStage));
                if(ObjectUtils.isEmpty(one)){
                    continue;
                }

                CbQuantitySummary cb = new CbQuantitySummary();
                cb.setProjectId(one.getId());
                cb.setCbStage(one.getCbStage());
                cb.setCbSubjectName(bean.getString("CLLBMC"));
                cb.setCbSubjectNo(subject.getCbSubjectNo());
                cb.setCbName(bean.getString("CLMC"));
                cb.setUnit(bean.getString("JLDW"));
                cb.setQuantity(bean.getDouble("SJSL"));


                list.add(cb);
            }
        }
        quantitySummaryService.batchInsert(list);
        System.out.println(list);
    }

    private String materielRequest(String apiURI) {
        try {
            /** ------------ 授权认证 --------------*/
            //第3步：创建客户端实例
            RestServiceClient serviceClient = HmacRestServiceClient.getInstance();
            //第4步：加载/验证授权文件
            //4.1构建认证信息
            HmacRestAuthInfo restAuthInfo = new HmacRestAuthInfo();
            //4.2设置授权文件路径
//            restAuthInfo.setLicPath("src/main/resource/auth/auth.lic");
            restAuthInfo.setLicStream(this.getClass().getResourceAsStream("/auth/auth.lic"));
            //4.3权限认证
            serviceClient.authenticate(restAuthInfo);

            /** ------------ 拼接请求地址 --------------*/
            //第5步：获取授权文件关联的GYS平台地址hostAddress
            String hostAddress = serviceClient.getRestRootAddress();
            //第6步：设置请求接口的URI地址apiURI(以获取集成项目列表信息为例)
            //第7步：拼装完整的请求网址
            String fullURL = hostAddress + apiURI;
            //第8步：请求数据准备（本例中为从GYS平台获取数据，无需进行请求数据的准备）

            //第9步：发送请求，用来推送/获取数据
            RestResponseInfo restResponseInfo = serviceClient.get(fullURL);

            /** ------------ 处理请求返回结果 --------------*/
            if (restResponseInfo.isSuccess()) {
                //请求成功：
                //第10步：处理请求结果（第三方系统自行处理）
                return restResponseInfo.getStringContent();
            } else {
                //请求失败:
                //第11步：拼接完整的上报请求失败地址
                String faultLogApiURI = "/gys/tl/services/trace/api-fault-log";
                String faultLogFullURL = hostAddress + faultLogApiURI;
                //第12步：构建上报请求失败数据
                JSONObject faultLog = new JSONObject();
                faultLog.put("requestUrl", fullURL);
                faultLog.put("requestMethod", "GET");
                faultLog.put("requestBody", "");
                faultLog.put("statusCode", restResponseInfo.getErrorCode());
                faultLog.put("response", restResponseInfo.getStringContent());
                faultLog.put("description", restResponseInfo.getErrorMessage());
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");//时间戳格式，到秒
                LocalDateTime dateTime = LocalDateTime.now();
                String searchKey = formatter.format(dateTime);
                faultLog.put("searchKey", searchKey);  //能表征本次请求记录的标识，方便进行问题排查
                //第13步：上报请求失败数据
                serviceClient.post(faultLogFullURL, faultLog.toJSONString());
            }
        } catch (AuthenticateException e) {
            e.printStackTrace();
        } catch (InvalidUriException e) {
            e.printStackTrace();
        } catch (NoAuthenticateException e) {
            e.printStackTrace();
        }
        throw new ServiceException("物料接口调用失败！");
    }
}
