package com.ningdatech.pmapi.irs.manage;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ningdatech.basic.function.VUtils;
import com.ningdatech.irs.service.IRefreshTokenService;
import com.ningdatech.pmapi.common.enumeration.CommonEnum;
import com.ningdatech.pmapi.common.statemachine.util.StateMachineUtils;
import com.ningdatech.pmapi.common.util.CryptUtils;
import com.ningdatech.pmapi.common.util.HttpUtil;
import com.ningdatech.pmapi.common.util.RefreshKeyUtil;
import com.ningdatech.pmapi.irs.model.dto.ApiApplyDTO;
import com.ningdatech.pmapi.irs.model.dto.ApiApplySearchResult;
import com.ningdatech.pmapi.irs.model.dto.PushProjectAppToIrsDTO;
import com.ningdatech.pmapi.irs.model.res.ApiResponse;
import com.ningdatech.pmapi.projectlib.model.dto.ProjectDTO;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.entity.ProjectApplication;
import com.ningdatech.pmapi.projectlib.service.IProjectApplicationService;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Classname AppIrsManage
 * @Description
 * @Date 2023/7/12 11:43
 * @Author PoffyZhang
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class AppIrsManage {

    private final IProjectService projectService;

    private final IProjectApplicationService applicationService;

    private final StateMachineUtils stateMachineUtils;

    @Value("${irs.push-app.appKey}")
    private String pushAppKey;

    @Value("${irs.push-app.appScret}")
    private String pushAppScret;

    @Value("${irs.push-app.url}")
    private String pushUrl;

    @Value("${irs.search-app.appKey}")
    private String searchAppKey;

    @Value("${irs.search-app.appScret}")
    private String searchAppScret;

    @Value("${irs.search-app.url}")
    private String searchUrl;
    @Resource
    private IRefreshTokenService refreshTokenService;

    @Value("${irs.interface-refresh.request-token-url}")
    private String govRequestTokenUrl;
    @Value("${irs.interface-refresh.refresh-token-url}")
    private String govRefreshTokenUrl;

    @Value("${irs.push-project-detail.url}")
    private String pushProjectUrl;

    @Value("${irs.push-project-detail.interfaceName}")
    private String pushProjectInterfaceName;

    @Value("${irs.push-project-detail.appKey}")
    private String pushProjectAppKey;

    @Value("${irs.push-project-detail.appSecret}")
    private String pushProjectAppSecret;

    //=============数字资源指标获取========================================================================================

    @Value("${irs.digital-resource-indicators.app-key}")
    private String driAppKey;

    @Value("${irs.digital-resource-indicators.app-secret}")
    private String driAppSecret;

    @Value("${irs.digital-resource-indicators.interface-name}")
    private String driInterfaceName;

    @Value("${irs.digital-resource-indicators.url}")
    private String driUrl;

    /**
     * 推送 项目和应用关系
     *
     * @param dto
     * @return
     * @throws NoSuchAlgorithmException
     */
    public Boolean pushProjectApp(PushProjectAppToIrsDTO dto) throws Exception {
        String appCode = dto.getAppCode();
        Long appId = dto.getAppId();
        String projectCode = dto.getProjectCode();
        ProjectApplication app = applicationService.getById(appId);
        VUtils.isTrue(Objects.isNull(app)).throwMessage("应用不存在!");
        VUtils.isTrue(CommonEnum.NO.getCode().equals(app.getIsFirst())).throwMessage("应用不是初次新建!");
        Project project = projectService.getProjectByCode(projectCode);
        VUtils.isTrue(Objects.isNull(project)).throwMessage("项目不存在!");

        ApiApplyDTO apiApply = new ApiApplyDTO();
        apiApply.setAppId(appCode);
        JSONObject jsonObject = this.searchApp(apiApply);
        ApiApplySearchResult apiApplySearchResult = JSON.parseObject(JSON.toJSONString(jsonObject), ApiApplySearchResult.class);
        VUtils.isTrue(Objects.isNull(apiApplySearchResult)).throwMessage("应用在IRS不存在!");

        long timestamp = System.currentTimeMillis();
        String areaCode = project.getAreaCode();
        String projectName = project.getProjectName();
        String requestSecret = RefreshKeyUtil.getRequestSecret(pushAppKey, pushAppScret);
        String capCode = CryptUtils.encryptHMAC(timestamp + areaCode, "bcb4fc0f517fc168ee543fcf4d231f3b");
        String capTime = String.valueOf(timestamp);
        String sign = CryptUtils.MD5Encode(pushAppKey + requestSecret + timestamp);
        String url = pushUrl + "?requestTime=" + timestamp +
                "&sign=" + sign + "&appKey=" + pushAppKey + "&capCode=" + capCode + "&capTime=" + capTime +
                "&baseProjSys=" + apiApplySearchResult.getName() + "&areaCode=" + areaCode + "&baseProjName=" + projectName +
                "&baseProjId=" + project.getProjectCode() +
                "&isEffective=1&baseProjSysCode=" + appCode;
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<ApiResponse> forEntity = restTemplate.getForEntity(url, ApiResponse.class);

        log.info("推送 项目和应用结果 : {}", JSON.toJSONString(forEntity));

        ApiResponse body = forEntity.getBody();

        if (Objects.isNull(body) || Objects.isNull(body.getCode())
                || 0 != body.getCode()) {
            return Boolean.FALSE;
        }

        //保存关系
        app.setAppCode(appCode);
        if (applicationService.updateById(app)) {
            /**
             * 判断下 如果成功的话 那么判断下 这个项目的初次创建的app 是否都已经被注册
             * 如果都已经注册 要调用状态机 进入下一个状态
             */
            List<ProjectApplication> apps = applicationService.list(Wrappers.lambdaQuery(ProjectApplication.class)
                    .eq(ProjectApplication::getProjectId, project.getId()));
            //筛选出 初次新建的app 但是没有appCode的
            apps = apps.stream().filter(a -> {
                        if (CommonEnum.YES.getCode().equals(a.getIsFirst()) &&
                                StringUtils.isBlank(app.getAppCode())) {
                            return Boolean.TRUE;
                        }
                        return Boolean.FALSE;
                    })
                    .collect(Collectors.toList());

            //如果筛选出来的 为空的话 就调用状态机
            if (CollUtil.isEmpty(apps)) {
                stateMachineUtils.pass(project);
                project.setUpdateOn(LocalDateTime.now());
                projectService.updateById(project);
            }
        }

        return body.getSuccess();
    }

    /**
     * 查询app
     *
     * @param apply
     * @return
     * @throws NoSuchAlgorithmException
     */
    public JSONObject searchApp(ApiApplyDTO apply) throws NoSuchAlgorithmException {
        long timestamp = System.currentTimeMillis();
        String appCode = apply.getAppId();
        String requestSecret = RefreshKeyUtil.getRequestSecret(searchAppKey, searchAppScret);
        String sign = CryptUtils.MD5Encode(searchAppKey + requestSecret + timestamp);
        String url = searchUrl + "?requestTime=" + timestamp + "&sign=" + sign +
                "&appKey=" + searchAppKey + "&" +
                "pageSize=10&pageNum=1&appCode=" + appCode +
                "&areaCode=&deptCode=&name=";
        log.info("url : {}", url);
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);

        log.info("查询应用目录 : {}", JSON.toJSONString(forEntity));

        if (Objects.nonNull(forEntity.getBody()) && Objects.nonNull(forEntity.getBody())) {
            JSONObject body = JSON.parseObject(forEntity.getBody());
            if (Objects.isNull(body)) {
                return null;
            }
            JSONObject datas = body.getJSONObject("datas");
            if (Objects.isNull(datas)) {
                return null;
            }
            JSONObject data = datas.getJSONObject("data");
            if (Objects.isNull(data)) {
                return null;
            }
            JSONArray apiApplySearchResult = data.getJSONArray("apiApplySearchResult");
            if (CollUtil.isEmpty(apiApplySearchResult)) {
                return null;
            }
            return apiApplySearchResult.getJSONObject(0);
        }
        return null;
    }

    public JSONArray searchApps(ApiApplyDTO apply) throws NoSuchAlgorithmException {
        long timestamp = System.currentTimeMillis();
        String areaCode = StringUtils.isNotBlank(apply.getAreaCode()) ?
                apply.getAreaCode() : null;
        String requestSecret = RefreshKeyUtil.getRequestSecret(searchAppKey, searchAppScret);
        String sign = CryptUtils.MD5Encode(searchAppKey + requestSecret + timestamp);
        String url = searchUrl + "?requestTime=" + timestamp + "&sign=" + sign +
                "&appKey=" + searchAppKey + "&pageSize=1000&" +
                "pageNum=1&areaCode=" + areaCode +
                "&deptCode=&name=";
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);

        log.info("查询应用目录 : {}", JSON.toJSONString(forEntity));

        if (Objects.nonNull(forEntity.getBody())) {
            JSONObject body = JSON.parseObject(forEntity.getBody());
            if (Objects.isNull(body)) {
                return null;
            }
            JSONObject datas = body.getJSONObject("datas");
            if (Objects.isNull(datas)) {
                return null;
            }
            JSONObject data = datas.getJSONObject("data");
            if (Objects.isNull(data)) {
                return null;
            }
            JSONArray apiApplySearchResult = data.getJSONArray("apiApplySearchResult");
            return apiApplySearchResult;
        }
        return null;
    }

    public String testGuibing() throws Exception {
        long timestamp = System.currentTimeMillis();
        String appSecret = "496f0f2a19994f76b4fd9dae087366c7";
        String appKey = "A331101453557202109017383";
        String method = "POST";
        String interfaceName = "5crv7i4727abLCv0";
        String secret = refreshTokenService.refreshToken(appKey, appSecret, govRequestTokenUrl, govRefreshTokenUrl, interfaceName, method);
        log.info("secret :{}", secret);
        String sign = MD5.create().digestHex(appKey + secret + timestamp);
        HttpComponentsClientHttpRequestFactory factory = HttpUtil.generateHttpRequestFactory();
        RestTemplate restTemplate;
        if (Objects.nonNull(factory)) {
            restTemplate = new RestTemplate(factory);
        } else {
            restTemplate = new RestTemplate();
        }
        String appId = "A330000100000202105005790";
        String capCode = CryptUtils.encryptHMAC(timestamp + appId, "bcb4fc0f517fc168ee543fcf4d231f3b");
        String url = "https://interface.zjzwfw.gov.cn/gateway/api/proxy/001003001029/" +
                "dataSharing/5crv7i4727abLCv0.htm?requestTime=" + timestamp +
                "&sign=" + sign + "&appKey=" + appKey +
                "&capCode=" + capCode + "&capTime=" + timestamp +
                "&appId=" + appId;
        log.info("url :{}", url);
        ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
        log.info(forEntity.getBody());
        return forEntity.getBody();
    }

    /**
     * 推送项目详情
     *
     * @return
     */
    public String pushProjectDetail(ProjectDTO projectDto) {
        long timestamp = System.currentTimeMillis();
        String appSecret = pushProjectAppSecret;
        String appKey = pushProjectAppKey;
        String method = HttpMethod.POST.name();
        String interfaceName = pushProjectInterfaceName;
        String secret = refreshTokenService.refreshToken(appKey, appSecret, govRequestTokenUrl, govRefreshTokenUrl, interfaceName, method);
        log.info("secret :{}", secret);
        String sign = MD5.create().digestHex(appKey + secret + timestamp);
        HttpComponentsClientHttpRequestFactory factory = HttpUtil.generateHttpRequestFactory();
        RestTemplate restTemplate;
        if (Objects.nonNull(factory)) {
            restTemplate = new RestTemplate(factory);
        } else {
            restTemplate = new RestTemplate();
        }
        String baseProjPrincipal = projectDto.getResponsibleMan();//"蒋国海"
        String baseProjSetYear = String.valueOf(projectDto.getProjectYear());//"2022"
        String baseProjId = projectDto.getProjectCode();//"331123220130969000000"
        String baseManDeprt = projectDto.getBuildOrgName();//"遂昌县大数据和金融发展中心"
        String baseProjBasis = projectDto.getBaseProjBasis();//"2"
        String baseLowestLevel = projectDto.getBaseLowestLevel();//"C"
        String ProjPrincipalCall = projectDto.getResponsibleManMobile();//"13884366607"
        //内容类别
        String baseConstructionType = projectDto.getBaseConstructionType();//"01"
        String baseProjType = projectDto.getBaseProjType();//"1"
        String baseProjContacts = projectDto.getContactName();//"毛以林"
        String isEffective = "1";
        String baseConsDeprtDing = projectDto.getBuildOrgCode();//"GO_9a7dce7fbaf54787998fa004f1b7c0e1";
        String baseProjSetProg = projectDto.getBaseProjSetProg();//"04"
        String baseProjContactsCall = projectDto.getContactPhone();//"13857049999"
        String baseProjName = projectDto.getProjectName();//"遂昌县大数据和金融发展中心天工系统"
        String baseProjConsClass = projectDto.getBaseProjConsClass();//"C"
        String areaCode = projectDto.getAreaCode() + "000";//"331123000"
        String baseAreaName = projectDto.getArea();//"遂昌县";
        String baseManDeprtDing = projectDto.getSuperOrgCode();//"GO_9a7dce7fbaf54787998fa004f1b7c0e1";
        String baseProvManDeprtDing = projectDto.getHigherSuperOrgCode();//"GO_6c383c049d95461f9a0df780140ceb32";
        String baseBasisEstablish = projectDto.getBuildBasis();//"中共遂昌县委办公室关于研究开发“天工”智能化管理平台（三期）的函";
        String capCode = null;
        try {
            capCode = CryptUtils.encryptHMAC(timestamp + areaCode, "bcb4fc0f517fc168ee543fcf4d231f3b");
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        String url = pushProjectUrl + "?" +
                "requestTime=" + timestamp + "&sign=" + sign +
                "&appKey=" + appKey + "&baseProjPrincipal=" + baseProjPrincipal + "" +
                "&baseProjSetYear=" + baseProjSetYear + "&baseProjId=" + baseProjId +
                "&baseManDeprt=" + baseManDeprt + "&baseProjBasis=" + baseProjBasis +
                "&baseLowestLevel=" + baseLowestLevel + "&ProjPrincipalCall=" + ProjPrincipalCall +
                "&baseConstructionType=" + baseConstructionType + "&baseProjType=" + baseProjType +
                "&baseProjContacts=" + baseProjContacts + "&isEffective=" + isEffective +
                "&baseConsDeprtDing=" + baseConsDeprtDing + "&baseProjSetProg=" + baseProjSetProg +
                "&baseProjContactsCall=" + baseProjContactsCall + "&baseProjName=" + baseProjName +
                "&baseProjConsClass=" + baseProjConsClass + "&capCode=" + capCode + "&baseManDeprtDing=" + baseManDeprtDing +
                "&baseProvManDeprtDing=" + baseProvManDeprtDing + "&baseBasisEstablish=" + baseBasisEstablish +
                "&baseAreaCode=" + areaCode + "&capTime=" + timestamp + "&baseAreaName=" + baseAreaName;
        log.info("url :{}", url);
        ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
        log.info(forEntity.getBody());
        return forEntity.getBody();
    }

    public JSONObject getDigitalResourceIndicatorsByAppCode(String appCode, Integer pageSize) {
        long timestamp = System.currentTimeMillis();
        String appSecret = driAppSecret;
        String appKey = driAppKey;
        String method = HttpMethod.POST.name();
        String interfaceName = driInterfaceName;
        String secret = refreshTokenService.refreshToken(appKey, appSecret, govRequestTokenUrl, govRefreshTokenUrl, interfaceName, method);
        log.info("secret : {}", secret);
        String sign = MD5.create().digestHex(appKey + secret + timestamp);
        HttpComponentsClientHttpRequestFactory factory = HttpUtil.generateHttpRequestFactory();
        RestTemplate restTemplate;
        if (Objects.nonNull(factory)) {
            restTemplate = new RestTemplate(factory);
        } else {
            restTemplate = new RestTemplate();
        }

        String url = driUrl + "?" +
                "requestTime=" + timestamp + "&sign=" + sign +
                "&appKey=" + appKey + "&appCode=" + appCode + "&pageIndex=1&pageSize=" + pageSize;
        log.info("url :{}", url);
        ResponseEntity<JSONObject> forEntity = restTemplate.getForEntity(url, JSONObject.class);
        log.info(Objects.requireNonNull(forEntity.getBody()).toJSONString());
        return forEntity.getBody();
    }

}
