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

import os
import sys
import json
import re
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 NaverSchoolDomLogger:
    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"
            f"?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).lower()

            if not self.is_json_response(response):
                return

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

        except Exception:
            pass

    def get_article_meta(self):
        if not self.article_data:
            print("[ARTICLE META] not captured")
            return {}

        detail = self.article_data.get("articleDetail") or {}

        meta = {
            "article_no": detail.get("articleNo") or self.article_no,
            "article_name": detail.get("articleName"),
            "hscp_no": detail.get("hscpNo"),
            "latitude": detail.get("latitude"),
            "longitude": detail.get("longitude"),
            "cortar_no": detail.get("cortarNo"),
            "realtor_id": detail.get("realtorId"),
            "detail_description": detail.get("detailDescription") or "",
            "feature_description": detail.get("articleFeatureDescription") or "",
        }

        print("=" * 80)
        print("[ARTICLE META]")

        for key, value in meta.items():
            if key in ["detail_description", "feature_description"]:
                value = str(value or "")[:250]
            print(f"{key}: {value}")

        print("=" * 80)

        return meta

    def click_school_related(self):
        candidates = [
            "text=학군",
            "text=학교",
            "text=교육",
            "text=주변",
            "text=주변시설",
            "button:has-text('학군')",
            "button:has-text('학교')",
            "button:has-text('교육')",
            "button:has-text('주변')",
            "button:has-text('주변시설')",
            "a:has-text('학군')",
            "a:has-text('학교')",
            "a:has-text('교육')",
            "a:has-text('주변')",
            "a:has-text('주변시설')",
        ]

        print("=" * 80)
        print("[SCHOOL CLICK START]")

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

                if count <= 0:
                    continue

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

                loc.first.click(
                    force=True,
                    timeout=2500,
                )

                self.page.wait_for_timeout(2500)

                self.dump_body_text(
                    label=self.safe_label(selector)
                )

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

        print("[SCHOOL CLICK END]")
        print("=" * 80)

    def safe_label(self, text):
        text = str(text or "")
        text = re.sub(r"[^0-9A-Za-z가-힣_]+", "_", text)
        return text[:50] or "dump"

    def dump_body_text(self, label="body"):
        try:
            text = self.page.locator("body").inner_text(timeout=5000)
        except Exception as e:
            print("[BODY TEXT FAIL]", str(e)[:160])
            return ""

        out_dir = os.path.join(ROOT_DIR, "storage", "debug")
        os.makedirs(out_dir, exist_ok=True)

        file_path = os.path.join(
            out_dir,
            f"school_dom_{self.article_no}_{label}.txt"
        )

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

        print("[BODY TEXT SAVED]", file_path)

        self.print_school_lines(text)

        return text

    def print_school_lines(self, text):
        lines = []
        keywords = [
            "초등학교",
            "중학교",
            "고등학교",
            "학교",
            "학군",
            "교육",
            "초,중,고",
            "초·중·고",
            "초중고",
        ]

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

            if not line:
                continue

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

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

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

        print("=" * 80)

    def extract_school_candidates_from_text(self, text):
        result = []

        # 명확한 학교명만 추출
        patterns = [
            (r"([가-힣A-Za-z0-9]{2,30}초등학교)", "초등학교", "elementary"),
            (r"([가-힣A-Za-z0-9]{2,30}중학교)", "중학교", "middle"),
            (r"([가-힣A-Za-z0-9]{2,30}고등학교)", "고등학교", "high"),
        ]

        seen = set()

        for pattern, school_type, level in patterns:
            for name in re.findall(pattern, text or ""):
                name = str(name or "").strip()

                if not name:
                    continue

                if name in seen:
                    continue

                seen.add(name)

                result.append({
                    "school_name": name,
                    "school_type": school_type,
                    "school_level": level,
                    "source": "dom",
                })

        return result

    def print_dom_school_candidates(self):
        try:
            text = self.page.locator("body").inner_text(timeout=5000)
        except Exception as e:
            print("[DOM CANDIDATE FAIL]", str(e)[:160])
            return []

        candidates = self.extract_school_candidates_from_text(text)

        print("=" * 80)
        print("[DOM SCHOOL CANDIDATES]", len(candidates))

        for item in candidates:
            print(
                item.get("school_name"),
                item.get("school_type"),
                item.get("school_level"),
            )

        print("=" * 80)

        return candidates

    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(7000)

            self.get_article_meta()

            # 초기 화면 DOM 덤프
            self.dump_body_text(label="initial")

            # 학군/학교/교육/주변시설 관련 UI 클릭 후 DOM 덤프
            self.click_school_related()

            # 최종 DOM에서 학교명 후보 추출
            self.print_dom_school_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",
        help="headless mode",
    )

    args = parser.parse_args()

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

    logger.run()


if __name__ == "__main__":
    main()
