package com.ningdatech.kqapi.scheduler.task;

import cn.hutool.core.date.StopWatch;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.ningdatech.kqapi.common.model.entity.Item;
import com.ningdatech.kqapi.zzsfw.model.entity.KqZzsfwMenu;
import com.ningdatech.kqapi.zzsfw.service.IKqZzsfwMenuService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.net.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author ZPF
 * @since 2023/08/31 18:16
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class CheckMattersUrlTask {

    @Value("${hostname}")
    public String HOST;

    @Value("${task.switch.is-open}")
    private boolean flag;

    @Value("${spring.profiles.active}")
    public String active;

    @Autowired
    private IKqZzsfwMenuService menuService;

    /**
     * 每天9点 开始校检 链接 是不是可行
     */
    @Scheduled(cron = "0 0 9 * * ?")
    public void doTask() throws UnknownHostException, MalformedURLException {
//        if (!HOST.equals(InetAddress.getLocalHost().getHostName())) {
//            log.info("定时器没开启或者host不对! {}:{}",
//                    HOST,InetAddress.getLocalHost().getHostName());
//            return;
//        }

        // 线上环境运行
        if (flag && HOST.equals(InetAddress.getLocalHost().getHostName())) {
            StopWatch stopWatch = new StopWatch();
            stopWatch.start();

            log.info("==========开始校检事项表里的链接 会不会404 如果404就隐藏");

            List<KqZzsfwMenu> menus = menuService.list(Wrappers.lambdaQuery(KqZzsfwMenu.class)
                    .eq(KqZzsfwMenu::getHasUrl, 1)
                    .isNotNull(KqZzsfwMenu::getWebapplyurl));
            Integer errNum = 0;
            List<String> errUrls = Lists.newArrayList();

            for (KqZzsfwMenu menu : menus) {
                RestTemplate restTemplate = new RestTemplate(generateHttpRequestFactory());
                String url = "https://www.zjzwfw.gov.cn/jpaas-zjservice-server/open-api/item/getItemDetail";
                MultiValueMap<String, String> map = new LinkedMultiValueMap<>();

                String webapplyurl = menu.getWebapplyurl();
                webapplyurl = webapplyurl.replace("/#", "");
                Map<String, String> queryParams = getQueryParams(new URL(webapplyurl));
                String localInnerCode = queryParams.get("localInnerCode");
                log.info("localInnerCode :{}", localInnerCode);
                map.add("localInnerCode", localInnerCode);
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
                HttpEntity<MultiValueMap<String, String>> formEntity = new HttpEntity(map, headers);
                ResponseEntity<Item> response = restTemplate.postForEntity(url, formEntity, Item.class);
                System.out.println(response.getBody());
                Item body = response.getBody();
                assert body != null;
                Item.ItemData itemData = body.getData();
                //如果是空的
                if (Objects.isNull(itemData.getItem())) {
                    //隐藏
                    menuService.update(Wrappers.lambdaUpdate(KqZzsfwMenu.class)
                            .eq(KqZzsfwMenu::getId, menu.getId())
                            .set(KqZzsfwMenu::getHasUrl, 0)
                            .set(KqZzsfwMenu::getWebapplyurl, null));
                    errNum += 1;
                    errUrls.add(webapplyurl);
                }
            }

            log.info("不可用的链接有 :{}条 ,详情:{}", errNum, errUrls);

            stopWatch.stop();
            log.info("校检事项表里的链接结束====={}s", stopWatch.getTotalTimeSeconds());
        }
    }

    public static void main(String[] args) throws Exception {
        String url = "https://www.zjzwfw.gov.cn/zjservice-fe/#/workguide?localInnerCode=3bd735e2-ddfe-4377-86b3-beec85252f21&siteCode=330000000000";
        url = url.replace("/#","");
        Map<String, String> queryParams = getQueryParams(new URL(url));
        System.out.println(queryParams.get("localInnerCode"));
    }

    public static Map<String, String> getQueryParams(URL url) {
        Map<String, String> queryPairs = new HashMap<>();
        String query = url.getQuery();
        String[] pairs = query.split("&");
        for (String pair : pairs) {
            int idx = pair.indexOf("=");
            try {
                if (idx > 0) {
                    String key = pair.substring(0, idx);
                    String value = pair.substring(idx + 1);
                    queryPairs.put(key, value);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return queryPairs;
    }

    /**
     * 通过该工厂类创建的RestTemplate发送请求时，可忽略https证书认证
     * @return 工厂
     */
    public static HttpComponentsClientHttpRequestFactory generateHttpRequestFactory(){
        try{
            TrustStrategy acceptingTrustStrategy = ((x509Certificates, authType) -> true);
            SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
            SSLConnectionSocketFactory connectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());

            HttpClientBuilder httpClientBuilder = HttpClients.custom();
            httpClientBuilder.setSSLSocketFactory(connectionSocketFactory);
            CloseableHttpClient httpClient = httpClientBuilder.build();
            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
            factory.setHttpClient(httpClient);
            return factory;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
