# -*- coding: utf-8 -*-

import os
import sys
import re
import json
from playwright.sync_api import sync_playwright

CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
ROOT_DIR = os.path.dirname(CURRENT_DIR)

if ROOT_DIR not in sys.path:
    sys.path.append(ROOT_DIR)

USER_AGENT = (
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
    "AppleWebKit/537.36 (KHTML, like Gecko) "
    "Chrome/136.0.0.0 Safari/537.36"
)


class NaverSchoolTabLogger:
    def __init__(self, article_no, headless=False):
        self.article_no = str(article_no or "").strip()
        self.headless = headless
        self.playwright = None
        self.browser = None
        self.context = None
        self.page = None
        self.article_data = None

    def start(self):
        print("=" * 80)
        print("[BROWSER START]")

        self.playwright = sync_playwright().start()
        self.browser = self.playwright.chromium.launch(
            headless=self.headless,
            args=[
                "--disable-blink-features=AutomationControlled",
                "--no-sandbox",
            ],
        )

        self.context = self.browser.new_context(
            locale="ko-KR",
            viewport={"width": 1365, "height": 900},
            user_agent=USER_AGENT,
        )

        self.page = self.context.new_page()
        self.page.on("response", self.handle_response)

        print("[BROWSER READY]")

    def close(self):
        print("[BROWSER CLOSED]")

        try:
            if self.browser:
                self.browser.close()
        except Exception:
            pass

        try:
            if self.playwright:
                self.playwright.stop()
        except Exception:
            pass

    def build_url(self):
        return "https://new.land.naver.com/complexes?articleNo=" + self.article_no

    def is_json_response(self, response):
        try:
            content_type = response.headers.get("content-type", "")
            return "json" in content_type.lower()
        except Exception:
            return False

    def handle_response(self, response):
        try:
            url = str(response.url)

            if not self.is_json_response(response):
                return

            lowered = url.lower()

            if f"/api/articles/{self.article_no}" in lowered:
                self.article_data = response.json()
                print("[ARTICLE API CAPTURED]", url)

            watch = [
                "school",
                "schools",
                "education",
                "edu",
                "complex",
                "facility",
                "around",
                "article",
            ]

            if any(x in lowered for x in watch):
                print("[API]", url)

        except Exception:
            pass

    def dump(self, label):
        out_dir = os.path.join(ROOT_DIR, "storage", "debug")
        os.makedirs(out_dir, exist_ok=True)

        label = re.sub(r"[^0-9A-Za-z_]+", "_", str(label or "dump"))
        path = os.path.join(out_dir, f"school_tab_{self.article_no}_{label}.txt")

        try:
            text = self.page.locator("body").inner_text(timeout=5000)
        except Exception as e:
            print("[DUMP FAIL]", label, str(e)[:200])
            return ""

        with open(path, "w", encoding="utf-8") as f:
            f.write(text)

        print("[DUMP SAVED]", path)
        self.print_useful_lines(text)
        return text

    def print_useful_lines(self, text):
        keywords = [
            "초등학교",
            "중학교",
            "고등학교",
            "학군",
            "학교",
            "교육",
            "관리비",
            "공용관리비",
            "난방비",
            "취득세",
            "보유세",
            "재산세",
            "중개보수",
            "교통",
            "공원",
            "편의시설",
        ]

        lines = []

        for line in str(text or "").splitlines():
            line = line.strip()

            if not line:
                continue

            if any(k in line for k in keywords):
                lines.append(line)

        print("=" * 80)
        print("[USEFUL LINES]", len(lines))

        for line in lines[:160]:
            print(line)

        print("=" * 80)

    def print_clickable_candidates(self):
        print("=" * 80)
        print("[CLICKABLE CANDIDATES]")

        selectors = [
            "a",
            "button",
            "[role='tab']",
            ".tab",
            ".tab_item",
            ".complex_tab",
            ".detail_tab",
            "li",
        ]

        for selector in selectors:
            try:
                items = self.page.locator(selector)
                count = min(items.count(), 120)

                for i in range(count):
                    try:
                        text = items.nth(i).inner_text(timeout=500).strip()

                        if any(k in text for k in ["학군", "학교", "교육", "주변", "시설", "관리비"]):
                            print(f"[{selector} #{i}]", repr(text[:120]))
                    except Exception:
                        pass

            except Exception:
                pass

        print("=" * 80)

    def click_by_text_variants(self):
        targets = [
            ("school_info", "학군정보"),
            ("school", "학군"),
            ("school_word", "학교"),
            ("education", "교육"),
            ("around", "주변"),
            ("facility", "주변시설"),
            ("maintenance", "관리비"),
        ]

        for label, text in targets:
            print("=" * 80)
            print("[TARGET CLICK]", label, text)

            selectors = [
                f"text={text}",
                f"a:has-text('{text}')",
                f"button:has-text('{text}')",
                f"li:has-text('{text}')",
                f"span:has-text('{text}')",
                f"div:has-text('{text}')",
                f"[role='tab']:has-text('{text}')",
            ]

            for selector in selectors:
                try:
                    loc = self.page.locator(selector)
                    count = loc.count()

                    if count <= 0:
                        continue

                    print("[TRY]", selector, "count=", count)

                    # first visible-like candidate 우선
                    clicked = False

                    for i in range(min(count, 8)):
                        try:
                            box = loc.nth(i).bounding_box(timeout=1000)

                            if not box:
                                continue

                            if box["width"] <= 0 or box["height"] <= 0:
                                continue

                            print("[CLICK BOX]", selector, i, box)
                            loc.nth(i).click(force=True, timeout=3000)
                            clicked = True
                            break

                        except Exception as e:
                            print("[BOX CLICK FAIL]", selector, i, str(e)[:120])

                    if not clicked:
                        loc.first.click(force=True, timeout=3000)

                    self.page.wait_for_timeout(3500)
                    self.dump(label)
                    break

                except Exception as e:
                    print("[CLICK FAIL]", selector, str(e)[:160])

    def try_url_hashes(self):
        # 네이버 내부 라우팅이 탭 클릭 대신 hash/query를 볼 가능성 대비
        hashes = [
            "school",
            "education",
            "facility",
            "around",
            "maintenance",
        ]

        current = self.page.url

        for h in hashes:
            try:
                print("[HASH TRY]", h)
                self.page.goto(current + "#" + h, wait_until="commit", timeout=15000)
                self.page.wait_for_timeout(3000)
                self.dump("hash_" + h)
            except Exception as e:
                print("[HASH FAIL]", h, str(e)[:160])

    def extract_candidates(self):
        try:
            text = self.page.locator("body").inner_text(timeout=5000)
        except Exception:
            text = ""

        patterns = [
            (r"([가-힣A-Za-z0-9]{2,30}초등학교)", "초등학교"),
            (r"([가-힣A-Za-z0-9]{2,30}중학교)", "중학교"),
            (r"([가-힣A-Za-z0-9]{2,30}고등학교)", "고등학교"),
        ]

        seen = set()
        result = []

        for pattern, school_type in patterns:
            for name in re.findall(pattern, text):
                if name in seen:
                    continue

                seen.add(name)
                result.append((name, school_type))

        print("=" * 80)
        print("[SCHOOL NAME CANDIDATES]", len(result))

        for name, school_type in result:
            print(name, school_type)

        print("=" * 80)

    def run(self):
        if not self.article_no:
            raise ValueError("article_no is required")

        self.start()

        try:
            url = self.build_url()
            print("[OPEN]", url)

            self.page.goto(url, wait_until="commit", timeout=30000)
            self.page.wait_for_timeout(8000)

            self.dump("initial")
            self.print_clickable_candidates()
            self.click_by_text_variants()
            self.try_url_hashes()
            self.extract_candidates()

        finally:
            self.close()


def main():
    import argparse

    parser = argparse.ArgumentParser()
    parser.add_argument("--article-no", type=str, default="2627920510")
    parser.add_argument("--headless", action="store_true")

    args = parser.parse_args()

    logger = NaverSchoolTabLogger(
        article_no=args.article_no,
        headless=args.headless,
    )

    logger.run()


if __name__ == "__main__":
    main()
