package org.stm.spider.service.impl;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.stm.compliane.info.entity.StComplianeInfo;
import org.stm.compliane.info.service.IStComplianeInfoService;
import org.stm.compliane.item.entity.StComplianePunish;
import org.stm.compliane.item.service.IStComplianePunishService;
import org.stm.spider.entity.WbTmpCfg;
import org.stm.spider.entity.WbTmpData;
import org.stm.spider.mapper.WbTmpCfgMapper;
import org.stm.spider.service.IWbTmpCfgService;
import org.stm.spider.service.IWbTmpDataService;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: 数据源配置
 * @Author: jeecg-boot
 * @Date:   2023-05-08
 * @Version: V1.0
 */
@Service
public class WbTmpCfgServiceImpl extends ServiceImpl<WbTmpCfgMapper, WbTmpCfg> implements IWbTmpCfgService {
    @Autowired
    private IWbTmpDataService wbTmpDataService;
    @Autowired
    private IStComplianePunishService stComplianePunishService;
    @Autowired
    private IStComplianeInfoService stComplianeInfoService;
    @Override
    public int processWbTmpCfg(WbTmpCfg wbTmpCfg, List<Integer> existDocIdList, int pageInd,List<Integer> docidList) {
        Integer endDocid = wbTmpCfg.getEndDocid();
        int docidEnd = (endDocid != null) ? endDocid.intValue() : 0;
        String rootPathStatic = wbTmpCfg.getRootPath();
        HttpURLConnection conn = null;
        int flag=0;
        try {
            int itemId = wbTmpCfg.getItemid().intValue();
            int total = wbTmpCfg.getTotal();
            int pageSize = wbTmpCfg.getPsize()==null?18:wbTmpCfg.getPsize();
            StringBuffer sbUrlPath = new StringBuffer();

            if(pageInd<4) {
                sbUrlPath.append(rootPathStatic).append("/data_itemId=").append(itemId).append(",pageIndex=").append(pageInd).append(",pageSize=18.json");
            } else {
                if(itemId==4113||itemId==4114) { //总局和省局
                    sbUrlPath.append("https://www.cbirc.gov.cn/cbircweb/DocInfo/SelectDocByItemIdAndChild?itemId=");
                } else {
                    sbUrlPath.append("https://www.cbirc.gov.cn/cbircweb/DocInfo/SelectDocItemByItemPId?itemId=");
                }
                sbUrlPath.append(itemId).append("&pageSize=").append(pageSize).append("&pageIndex=").append(pageInd);
            }

            java.io.InputStream inputStream = null;
            try {
                URL url = new URL(sbUrlPath.toString());
                conn = createURLConn(url);
                inputStream = conn.getInputStream();
                if (inputStream == null) {
                    System.out.println(url);
                    return -1;
                }
            } catch (Exception e) {
                System.out.println(itemId);
                e.printStackTrace();
                return -1;
            }

            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
            StringBuilder sb = new StringBuilder();
            String output;
            while ((output = br.readLine()) != null) {
                sb.append(output);
            }
            br.close();

            Gson gson = new Gson();
            JsonObject jsonObject = gson.fromJson(sb.toString(), JsonObject.class);
            int rptCode = jsonObject.get("rptCode").getAsInt();
            if (rptCode == 200) {
                JsonObject jsonData = jsonObject.getAsJsonObject("data");
                JsonArray list = jsonData.get("rows").getAsJsonArray();
                if(list==null ||list.size()==0) {
                    return -1;
                }
                Integer maxDocId = list.get(0).getAsJsonObject().get("docId").getAsInt();
                int newtotal = jsonData.get("total").getAsInt();
                int newPages = getPageNum(newtotal,wbTmpCfg.getPsize());
                int oldTotal = wbTmpCfg.getTotal();
                if(pageInd==1){
                    if(oldTotal==newtotal) {
                        return 1;
                    }
                    wbTmpCfg.setPind(wbTmpCfg.getPages());  //前一次页数
                    wbTmpCfg.setPages(newPages); //最新的页数
                    wbTmpCfg.setTotal(newtotal);
                    wbTmpCfg.setEndDocid(maxDocId);
                    this.baseMapper.updateById(wbTmpCfg);
                }

                for (JsonElement rowEle : list) {
                    int docId = rowEle.getAsJsonObject().get("docId").getAsInt();
                    if(docidList!=null&&docidList.contains(docId)){
                        continue;
                    } else {
                        if (docId <= docidEnd || existDocIdList.contains(docId)) {
                            return 1;
                        }
                    }
                    String docTitle = rowEle.getAsJsonObject().get("docTitle").getAsString();
                    if (docTitle.indexOf("处罚决定书") > -1) {
                        continue;
                    } else if(docTitle.indexOf("处罚信息公开表")>-1) {
                        parseDocDetail(docId, wbTmpCfg,docTitle);
                    } else {
                        continue;
                    }
                    existDocIdList.add(docId);
                    Thread.sleep(1000);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(conn!=null) {
                conn.disconnect();
            }
            return flag;
        }

    }

    private void parseDocDetail(int docId, WbTmpCfg wbTmpCfg,String title) throws Exception {
        String urlDetail = "http://www.cbirc.gov.cn/cn/static/data/DocInfo/SelectByDocId/data_docId=" + docId + ".json";
        URL url = new URL(urlDetail);
        HttpURLConnection conn =createURLConn(url);
        try {
            try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
                StringBuilder sb = new StringBuilder();
                String output;
                while ((output = br.readLine()) != null) {
                    sb.append(output);
                }
                Gson gson = new Gson();
                JsonObject jsonObject = gson.fromJson(sb.toString(), JsonObject.class);
                int rptCode = jsonObject.get("rptCode").getAsInt();
                if (rptCode == 200) {
                    JsonObject jsonData = jsonObject.getAsJsonObject("data");
                    String docClob = jsonData.get("docClob").getAsString();
                    // 解析文档详情
                    parseDocumentDetail(docClob, docId, wbTmpCfg,title);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            conn.disconnect();
        }
    }

    private void parseDocumentDetail(String docClob, int docId, WbTmpCfg wbTmpCfg,String title) {
        try {
            Document doc = Jsoup.parse(docClob);
            List<String> tmpList = new ArrayList();
            Element table = doc.select("table").first();
            if (table == null) return;
            Elements rows = table.select("tr");
            for (Element row : rows) {
                //			String strLabes = row.select("td").get(row.childNodeSize()-2).text();
                //			int ind = getElementInd(strLabes);
                //			if(ind==-1) {
                //				System.out.println(strLabes);
                //			}
                String textVal = "";
                if (row.select("td").last() != null) {
                    textVal = row.select("td").last().text();
                } else {
                    textVal = null;
                }

                //tmpAry[ind] = textVal;
                tmpList.add(textVal);
            }

            WbTmpData wbTmpData = new WbTmpData();
            wbTmpData.setComplianeNo(docId);
            wbTmpData.setTp(wbTmpCfg.getTp());
            wbTmpData.setItemid(wbTmpCfg.getItemid());

            if (tmpList.size() == 9) {
                wbTmpData.setDocNo(tmpList.get(0));
                wbTmpData.setPunishedUsers(tmpList.get(1));
                wbTmpData.setPunishedOrg(tmpList.get(2));
                wbTmpData.setPunishedOrgHead(tmpList.get(3));
                wbTmpData.setViolationFact(tmpList.get(4));
                wbTmpData.setPunishBasis(tmpList.get(5));
                wbTmpData.setPunishDecision(tmpList.get(6));
                wbTmpData.setPunishCom(tmpList.get(7));
                wbTmpData.setPunishDate(handleDate(tmpList.get(8)));
            } else if (tmpList.size() == 7) {
                wbTmpData.setDocNo(tmpList.get(0));
                wbTmpData.setPunishedOrg(tmpList.get(1));
                wbTmpData.setViolationFact(tmpList.get(2));
                wbTmpData.setPunishBasis(tmpList.get(3));
                wbTmpData.setPunishDecision(tmpList.get(4));
                wbTmpData.setPunishCom(tmpList.get(5));
                wbTmpData.setPunishDate(handleDate(tmpList.get(6)));
            } else if (tmpList.size() == 8) {
                wbTmpData.setDocNo(tmpList.get(0));
                wbTmpData.setPunishedUsers(tmpList.get(1));
                wbTmpData.setPunishedOrg(tmpList.get(2));
                wbTmpData.setViolationFact(tmpList.get(3));
                wbTmpData.setPunishBasis(tmpList.get(4));
                wbTmpData.setPunishDecision(tmpList.get(5));
                wbTmpData.setPunishCom(tmpList.get(6));
                wbTmpData.setPunishDate(handleDate(tmpList.get(7)));
            }

            String strTitle = wbTmpData.getPunishDecision();
            if(strTitle==null){
                wbTmpData.setTitle(title);
            } else {
                wbTmpData.setTitle(handleTitle(strTitle));
            }
            wbTmpData.setCreatedTime(new Date());
            wbTmpDataService.save(wbTmpData);
            saveToPunish(wbTmpData);
        } catch(Exception e) {
            e.printStackTrace();
        }
    }


    private int getElementInd(String key) {
        if(key.startsWith("行政处罚决定书文号")) {
            return 0;
        } else if(key.startsWith("个人")) {
            return 1;
        } else if(key.startsWith("名称")||key.startsWith("被处罚当事人")) {
            return 2;
        } else if(key.startsWith("法定代表人")||key.startsWith("主要负责人姓名")) {
            return 3;
        } else if(key.startsWith("主要违法违规事实")) {
            return 4;
        } else if(key.startsWith("行政处罚依据")) {
            return 5;
        } else if(key.startsWith("行政处罚决定")) {
            return 6;
        } else if(key.startsWith("作出行政处罚决定的")) {
            return 7;
        } else if(key.startsWith("作出处罚决定的日期")) {
            return 8;
        } else {
            return -1;
        }
    }


    private HttpURLConnection createURLConn(URL url) throws Exception{
        try {
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(50000);
            conn.setReadTimeout(100000);
            conn.setRequestProperty("Referer", "http://www.cbirc.gov.cn/");
            conn.setRequestProperty("Accept", "application/json");
            conn.setRequestProperty("Accept-Language", "zh-CN,zh;q=0.9");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36");
            return conn;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    private String handleDate(String strDate){
        try {
            strDate = strDate.replaceAll("\\s+", "");
            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy年M月d日");
            SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date date = inputFormat.parse(strDate);
            return outputFormat.format(date);
        } catch (ParseException e) {
            return strDate;
        }
    }

    private int getPageNum(int total, int pageSize){
        int s = total%pageSize;
        int pageNum = s>0?(total-s)/pageSize+1:(total/pageSize);
        return pageNum;
    }

    private String handleTitle(String strTitle) {
        String result = strTitle.replaceAll("[\\s（）\\(\\)\\[\\]【】]+|\\（[^\\（\\）]*\\）+$", "");
        if(result.length() > 32) {
            result = result.substring(0,32);
        }
        int pos = result.lastIndexOf("。");
        pos = pos==-1?result.lastIndexOf("."):pos;
        pos = pos==-1?result.lastIndexOf(";"):pos;
        pos = pos==-1?result.lastIndexOf("!"):pos;
        pos = pos==-1?result.lastIndexOf("?"):pos;
        pos = pos==-1?result.lastIndexOf(";"):pos;

        if(pos>5) {
            result = result.substring(0,pos);
        } else if(pos>-1){
            result = result.substring(pos+1);
        }
        return result;
    }

    private Date strToDate(String strDate){
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = dateFormat.parse(strDate);
            return date;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return  null;
    }

    private void saveToPunish(WbTmpData wbTmpData){
        StComplianePunish scPuninsh = new StComplianePunish();
        scPuninsh.setPunishBasis(wbTmpData.getPunishBasis());
        scPuninsh.setDocNo(wbTmpData.getDocNo());
        scPuninsh.setPunishCom(wbTmpData.getPunishCom());
        scPuninsh.setPunishDate(strToDate(wbTmpData.getPunishDate()));
        scPuninsh.setCreatedTime(wbTmpData.getCreatedTime());
        scPuninsh.setComplianeNo(wbTmpData.getComplianeNo().toString());
        scPuninsh.setPunishedUsers(wbTmpData.getPunishedUsers());
        scPuninsh.setPunishedOrgHead(wbTmpData.getPunishedOrgHead());
        scPuninsh.setPunishDecision(wbTmpData.getPunishDecision());
        scPuninsh.setPunishedOrg(wbTmpData.getPunishedOrg());
        scPuninsh.setApproveFlag("1");
        scPuninsh.setValid("1");
        scPuninsh.setViolationFact(wbTmpData.getViolationFact());
        scPuninsh.setCreatedUser("admin");
        stComplianePunishService.save(scPuninsh);

        StComplianeInfo stComplianeInfo = new StComplianeInfo();
        stComplianeInfo.setCreatedTime(scPuninsh.getCreatedTime());
        stComplianeInfo.setDocNo(scPuninsh.getDocNo());
        stComplianeInfo.setComplianeNo(scPuninsh.getComplianeNo());
        stComplianeInfo.setComplianeDesc(scPuninsh.getPunishDecision());
        stComplianeInfo.setCreatedUser(scPuninsh.getCreatedUser());
        stComplianeInfo.setApproveFlag("1");
        stComplianeInfo.setStatus("1");
        stComplianeInfo.setValid("1");
        stComplianeInfo.setFileName(wbTmpData.getTitle());
        stComplianeInfo.setIssued(scPuninsh.getPunishCom());
        stComplianeInfo.setIssuedTime(scPuninsh.getPunishDate());
        stComplianeInfo.setComplianeClass("5");
        stComplianeInfoService.save(stComplianeInfo);
    }
}
