package org.jeecg.modules.stm.spider.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.modules.stm.compliane.info.entity.StComplianeInfo;
import org.jeecg.modules.stm.compliane.info.service.IStComplianeInfoService;
import org.jeecg.modules.stm.compliane.item.entity.StComplianePunish;
import org.jeecg.modules.stm.compliane.item.service.IStComplianePunishService;
import org.jeecg.modules.stm.spider.entity.WbTmpCfg;
import org.jeecg.modules.stm.spider.entity.WbTmpData;
import org.jeecg.modules.stm.spider.mapper.WbTmpCfgMapper;
import org.jeecg.modules.stm.spider.service.IWbTmpCfgService;
import org.jeecg.modules.stm.spider.service.IWbTmpDataService;
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 org.springframework.transaction.annotation.Transactional;

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
    @Transactional(rollbackFor = Exception.class)
    public int processWbTmpCfg(WbTmpCfg wbTmpCfg, List<Integer> existDocIdList, int pageInd, List<Integer> docidList) {
        Integer endDocid = wbTmpCfg.getEndDocid();
        int docidEnd = (endDocid != null) ? endDocid : 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();
            StringBuilder sbUrlPath = new StringBuilder();

            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, "UTF-8"));
            StringBuilder sb = new StringBuilder();
            String output;
            while ((output = br.readLine()) != null) {
                sb.append(output);
            }
            br.close();

            JSONObject jsonObject = JSONObject.parseObject(sb.toString());
            int rptCode = jsonObject.getIntValue("rptCode");
            if (rptCode == 200) {
                JSONObject jsonData = jsonObject.getJSONObject("data");
                JSONArray list = jsonData.getJSONArray("rows");
                if (list == null || list.size() == 0) {
                    return -1;
                }
                Integer maxDocId = list.getJSONObject(0).getInteger("docId");
                int newtotal = jsonData.getIntValue("total");
                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.updateById(wbTmpCfg);
                }

                for (int i = 0; i < list.size(); i++) {
                    JSONObject rowEle = list.getJSONObject(i);
                    int docId = rowEle.getIntValue("docId");
                    if (docidList != null && docidList.contains(docId)) {
                        continue;
                    } else {
                        if (docId <= docidEnd || existDocIdList.contains(docId)) {
                            return 1;
                        }
                    }
                    String docTitle = rowEle.getString("docTitle");
                    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();
            throw new RuntimeException("处理配置时发生异常", e);
        } 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(), "UTF-8"))) {
                StringBuilder sb = new StringBuilder();
                String output;
                while ((output = br.readLine()) != null) {
                    sb.append(output);
                }
                JSONObject jsonObject = JSONObject.parseObject(sb.toString());
                int rptCode = jsonObject.getIntValue("rptCode");
                if (rptCode == 200) {
                    JSONObject jsonData = jsonObject.getJSONObject("data");
                    String docClob = jsonData.getString("docClob");
                    // 解析文档详情
                    parseDocumentDetail(docClob, docId, wbTmpCfg, title);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } 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 textVal = "";
                if (row.select("td").last() != null) {
                    textVal = row.select("td").last().text();
                } else {
                    textVal = null;
                }
                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();
            throw new RuntimeException("解析文档详情时发生异常", e);
        }
    }

    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, Integer pageSize) {
        if (pageSize == null || pageSize == 0) {
            pageSize = 18;
        }
        int s = total % pageSize;
        return s > 0 ? (total - s) / pageSize + 1 : (total / pageSize);
    }

    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) {
        if (strDate == null || strDate.trim().isEmpty()) {
            return null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return dateFormat.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


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

        StComplianeInfo stComplianeInfo = new StComplianeInfo();
        stComplianeInfo.setCreatedTime(scPunish.getCreatedTime());

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