package com.cslg.ppa.service.GetWebArticle;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cslg.ppa.common.utils.DateUtil;
import com.cslg.ppa.common.utils.RegexUtil;
import com.cslg.ppa.dto.GetArticleInfoDTO;
import com.cslg.ppa.entity.ArticleInfo;
import com.cslg.ppa.entity.SourceInfo;
import com.cslg.ppa.mapper.SourceInfoMapper;
import com.cslg.ppa.service.ArticleInfoService;
import com.cslg.ppa.service.commom.DifyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
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.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class GetZhiNanZhenArticleService {
    private final ArticleInfoService articleInfoService;
    @Autowired
    private DifyService difyService;
    @Autowired
    private SourceInfoMapper sourceInfoMapper;

    /**
     * 智南针
     *
     * @throws Exception
     */
    @Scheduled(cron = "0 30 4 * * ?")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
    public void crawZhiNanZhenArticle() throws Exception {
        System.out.println(new Date() + "ZhiNanZhen-Begin");
        SourceInfo sourceInfo = sourceInfoMapper.selectOne(new LambdaQueryWrapper<SourceInfo>()
                .eq(SourceInfo::getWebType, 4));
        if (ObjectUtils.isNotEmpty(sourceInfo)) {
            String sourceUrl = sourceInfo.getSourceUrl();
            Integer sourceInfoId = sourceInfo.getId();
            // 使用Jsoup连接并解析网页
            Document doc = Jsoup.connect(sourceUrl)
                    .timeout(20000) // 增加超时时间
                    .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36")
                    .followRedirects(true) // 跟随重定向
                    .get();
            List<String> list = Arrays.asList("海外知识产权动态信息", "海外知识产权实务指引", "海外知识产权官费专栏");
            // 遍历每个栏目并抓取资讯链接
            for (String sectionTitle : list) {
                this.extractSectionLinks(doc, sectionTitle, sourceInfoId, 11);
            }
        }
        System.out.println(new Date() + "ZhiNanZhen-End");
    }

    private void extractSectionLinks(Document doc, String sectionTitle, Integer sourceId, Integer type) throws Exception {
        List<String> links = new ArrayList<>();
        // 选择所有section元素
        Elements sections = doc.select("section.section");
        for (Element section : sections) {
            // 检查section的标题是否包含指定的栏目名称
            Element header = section.selectFirst(".section-header h2");
            if (header != null && header.text().contains(sectionTitle)) {
                // 提取该section下的所有资讯链接
                Elements newsItems = section.select("ul li a[href]");
                for (Element item : newsItems) {
                    String href = item.attr("href");
                    // 确保href属性存在且不是空值，并且不是非资讯链接
                    if (!href.isEmpty() && !isValidNewsLink(item, href, item.text())) {
                        links.add(href);
                    }
                }
            }
        }

        List<GetArticleInfoDTO> articleInfoDTOS = new ArrayList<>();
        if (!CollectionUtils.isEmpty(links)) {
            for (String link : links) {
                try {
                    GetArticleInfoDTO articleInfoDTO = this.addZhiNanZhenArticle(link, sourceId, type);
                    if (ObjectUtils.isNotEmpty(articleInfoDTO)) {
                        articleInfoDTOS.add(articleInfoDTO);
                    }
                } catch (Exception ignored) {
                }
            }
        }
        articleInfoService.batchAddArticleInfo(articleInfoDTOS);
    }

    /**
     * 添加智南针网资讯内容到资讯表中
     *
     * @param baseUrl
     * @return
     * @throws IOException
     */
    public GetArticleInfoDTO addZhiNanZhenArticle(String baseUrl, Integer sourceId, Integer type) throws IOException {
        // 使用Jsoup连接并解析网页
        Document doc = Jsoup.connect(baseUrl)
                .timeout(15000) // 增加超时时间
                .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36")
                .followRedirects(true) // 跟随重定向
                .get();

        Element initElement = doc.selectFirst("div.con_right");
        Element titleElement = initElement.selectFirst("h1");
        //获取时间
        String pubTime = titleElement.getElementsByTag("span").text().trim();
        String dateStr = RegexUtil.extractDate(pubTime);
        String yesterdayDateStr = DateUtil.getYesterdayDateStr();
        if (!StringUtils.equals(dateStr, yesterdayDateStr)) {
            return null;
        }
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            date = dateFormat.parse(dateStr);
        } catch (Exception e) {
            return null;
        }

        String titleContent = titleElement.text();
        String title = titleContent.substring(0, (titleContent.length() - 23)).trim();
        // 检查文章是否已存在
        long sum = articleInfoService.count(new LambdaQueryWrapper<ArticleInfo>()
                .eq(ArticleInfo::getTitle, title));
        if (sum > 0) {
            return null;
        }

        String digest = "";
        List<String> list = new ArrayList<>();
        Element textElement = initElement.selectFirst("div.dl");
        Elements elements = textElement.select("span");
        for (Element element : elements) {
            String text = element.text().trim();
            if (StringUtils.isNotEmpty(text)) {
                list.add(text);
            }
        }
        List<String> collect = list.stream().distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(collect)) {
            String articleContent = initElement.text();
            collect.add(articleContent);
            digest = StringUtils.join(collect, "\n");
        } else {
            digest = StringUtils.join(collect, "\n");
        }
        String condensedAbstract = "";
        try {
            condensedAbstract = difyService.getCondensedAbstract(digest);
        } catch (Exception e) {
            condensedAbstract = "";
        }
        GetArticleInfoDTO articleInfoDTO = new GetArticleInfoDTO();
        articleInfoDTO.setCategoryId(type);
        articleInfoDTO.setSourceId(sourceId);
        articleInfoDTO.setArticleUrl(baseUrl);
        articleInfoDTO.setTitle(title);
        articleInfoDTO.setPublicTime(date);
        articleInfoDTO.setDigest(condensedAbstract);
        return articleInfoDTO;
    }

    // 智能判断资讯链接的核心方法
    private static boolean isValidNewsLink(Element link, String href, String text) {
        /**
         * 过滤规则说明：
         * 1. 排除空链接和片段标识符（#）
         * 2. 排除JavaScript伪链接
         * 3. 排除短文本链接（通常非资讯链接）
         * 4. 排除PDF/DOC等非网页链接
         * 5. 排除已知非资讯路径模式
         */

        // 规则1：基础有效性检查
        if (href.isEmpty() || href.startsWith("#") || href.startsWith("javascript:")) {
            return false;
        }

        // 规则2：文本长度过滤（非资讯链接通常文本较短）
        if (text.length() < 5) return false;

        // 规则3：文件类型过滤
        String lowerHref = href.toLowerCase();
        if (lowerHref.endsWith(".pdf") || lowerHref.endsWith(".doc")
                || lowerHref.endsWith(".docx") || lowerHref.endsWith(".xls")) {
            return false;
        }

        // 规则4：路径模式过滤（根据实际网站路径模式调整）
        if (lowerHref.contains("/login/") || lowerHref.contains("/register/")
                || lowerHref.contains("/help/") || lowerHref.contains("/contact/")) {
            return false;
        }

        // 规则5：DOM结构验证（确保链接在资讯列表内）
        Element parentLi = link.parent();
        if (parentLi == null) return false;

        Element parentUl = parentLi.parent();
        if (parentUl == null) return false;

        // 验证父级容器是否为资讯列表
        return parentUl.hasClass("list-news")
                || parentUl.hasClass("guides")
                || parentUl.hasClass("fee-list");
    }
}
