package kr.lunaticbum.back.lun.services

import kotlinx.coroutines.delay
import kr.lunaticbum.back.lun.utils.LogService
import kr.lunaticbum.back.lun.utils.RssFeedsParser
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.select.Elements
import org.openqa.selenium.By
import org.openqa.selenium.chrome.ChromeOptions
import org.openqa.selenium.remote.RemoteWebDriver
import org.springframework.stereotype.Service
import java.net.URL
import java.net.URLEncoder

@Service
class ScraperService(
    private val logService: LogService
) {
    private val waitTime = 1500L
    private val remoteDriverUrl = "https://video.lunaticbum.kr" // 기존 코드 설정 유지

    /**
     * URL 유효성 검사
     */
    fun isValidUrl(url: String): Boolean {
        val urlRegex = "^(https?|ftp)://[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_+.~#?&/=]*)$".toRegex()
        return url.matches(urlRegex)
    }

    /**
     * Selenium RemoteWebDriver 생성 (사용 후 반드시 종료해야 함)
     */
    private fun createWebDriver(): RemoteWebDriver? {
        return try {
            val options = ChromeOptions().apply {
                addArguments("--headless")
                addArguments("--disable-popup-blocking")
                addArguments("--disable-default-apps")
                addArguments("--disable-notifications")
                addArguments("--disable-blink-features=AutomationControlled")
            }
            RemoteWebDriver(URL(remoteDriverUrl), options)
        } catch (e: Exception) {
            logService.log("Failed to create WebDriver: ${e.message}")
            null
        }
    }

    /**
     * 구글 검색을 수행하고 상위 결과 URL 목록을 반환합니다.
     */
    suspend fun searchGoogle(query: String, topCount: Int = 2): Set<String> {
        val targetUrls = HashSet<String>()
        val driver = createWebDriver() ?: return targetUrls

        try {
            // 1. Selenium을 이용한 구글 검색
            driver.get("https://www.google.com/search?q=${URLEncoder.encode(query, "UTF-8")}")
            delay(waitTime)

            val pageSource = driver.pageSource
            val doc = Jsoup.parse(pageSource)

            var count = 0
            doc.select("[href*=https]").forEach {
                val href = it.attr("href")
                if (isValidLink(href) && count < topCount) {
                    targetUrls.add(href)
                    count++
                }
            }
        } catch (e: Exception) {
            logService.log("Google search failed for query '$query': ${e.message}")
        } finally {
            try { driver.quit() } catch (e: Exception) {}
        }

        // 2. RSS 피드를 이용한 검색 보완
        try {
            val rssUrl = "https://news.google.com/rss/search?q=${URLEncoder.encode(query, "UTF-8")}=ko&gl=KR&ceid=KR%3Ako/"
            var count = 0
            RssFeedsParser().readFeed(rssUrl)?.messages?.forEach { msg ->
                val url = msg.link
                if (url != null && isValidLink(url) && count < topCount) {
                    targetUrls.add(url)
                    count++
                }
            }
        } catch (e: Exception) {
            logService.log("RSS search failed: ${e.message}")
        }

        return targetUrls
    }

    /**
     * 특정 URL의 웹페이지 내용을 텍스트로 추출합니다.
     */
    suspend fun fetchPageContent(url: String): String {
        val driver = createWebDriver() ?: return ""
        var content = ""
        try {
            driver.get(url)
            delay(waitTime)
            val pageSource = driver.pageSource
            content = extractMainContent(Jsoup.parse(pageSource))
        } catch (e: Exception) {
            logService.log("Failed to fetch content from $url: ${e.message}")
        } finally {
            try { driver.quit() } catch (e: Exception) {}
        }
        return content
    }

    /**
     * Jsoup을 사용하여 HTML 본문에서 핵심 텍스트만 추출합니다.
     */
    private fun extractMainContent(doc: Document): String {
        val url = doc.baseUri()
        val body = doc.body()
        var elements: Elements = Elements()

        // 주요 뉴스 사이트별 셀렉터 처리
        val specificElements = when {
            url.contains("nate.com", true) -> if (url.contains("view")) body.select("[class*=articleView]") else body.select("[class*=postRankSubjectList]")
            url.contains("newsis.com/view", true) -> body.select("[class*=articleView]")
            url.contains("blog.naver.com", true) -> body.select("[class*=se-viewer]")
            url.contains("bbc.com", true) -> body.select("main[role$=main]")
            url.contains("chosun.com", true) -> body.select("[class*=articleBody]")
            url.contains("nocutnews.co.kr", true) -> body.select("[class*=container]")
            url.contains("hani.co.kr", true) -> body.select("[class*=ArticleDetail]")
            url.contains("yna.co.kr", true) -> body.select("[class*=container]")
            else -> Elements()
        }

        if (specificElements.isNotEmpty()) {
            elements.addAll(specificElements)
        } else {
            // 일반적인 구조에서 본문 찾기 시도
            arrayOf("container", "article", "main", "viewer", "content").forEach { keyword ->
                body.select("[class*=$keyword], [id*=$keyword], $keyword").forEach {
                    if (it.text().length > 100 && it.children().size < 5) {
                        elements.add(it)
                    }
                }
            }
        }

        return if (elements.isNotEmpty()) elements.text() else body.text()
    }

    private fun isValidLink(href: String?): Boolean {
        return href != null && href.length > 5 && href.startsWith("https://") &&
                !href.contains("google") && !href.contains("youtube")
    }
}