#!/usr/bin/env python3

from __future__ import annotations

import re
import sys
from pathlib import Path


def fail(message: str) -> None:
    print(f"[FAIL] {message}", file=sys.stderr)
    raise SystemExit(1)


def main() -> None:
    if len(sys.argv) != 2:
        fail("사용법: ./validate_html.py 문서.html")

    html_path = Path(sys.argv[1]).resolve()

    if not html_path.is_file():
        fail(f"HTML 파일을 찾을 수 없습니다: {html_path}")

    try:
        html = html_path.read_text(encoding="utf-8")
    except UnicodeDecodeError:
        fail("HTML 파일이 UTF-8 형식이 아닙니다.")

    lowered = html.lower()

    # 필수 문서 구조
    required_patterns = {
        r"<!doctype\s+html": "DOCTYPE 선언",
        r"<html\b[^>]*\blang=[\"']ko[\"']": 'html lang="ko"',
        r"<meta\b[^>]*charset=[\"']?utf-8": "UTF-8 문자셋",
        r"<title\b[^>]*>.*?</title>": "title 태그",
        r"<body\b[^>]*>": "body 태그",
        r"<h1\b[^>]*>": "H1 문서 제목",
        r"<h2\b[^>]*>": "H2 본문 제목",
    }

    for pattern, label in required_patterns.items():
        if not re.search(
            pattern,
            lowered,
            flags=re.IGNORECASE | re.DOTALL,
        ):
            fail(f"{label}가 없습니다.")

    # 디자인 시스템 연결 확인
    if "design-system.css" not in lowered:
        fail("pdf-studio/design-system.css가 연결되지 않았습니다.")

    # 허용하지 않는 요소
    forbidden_patterns = {
        r"<script\b": "JavaScript",
        r"<iframe\b": "iframe",
        r"<style\b": "문서 내부 style 태그",
        r"\sstyle\s*=": "inline style",
        r"javascript\s*:": "javascript URL",
        r"@import\s+": "CSS @import",
        r"https?://": "외부 URL",
    }

    for pattern, label in forbidden_patterns.items():
        if re.search(pattern, lowered, flags=re.IGNORECASE):
            fail(f"허용되지 않은 요소가 포함되어 있습니다: {label}")

    # 최소 문서 분량
    if len(html.strip()) < 800:
        fail("HTML 내용이 지나치게 짧습니다.")

    # 제목 개수 확인
    h1_count = len(re.findall(r"<h1\b", lowered))
    h2_count = len(re.findall(r"<h2\b", lowered))

    if h1_count > 2:
        print(f"[WARN] H1이 {h1_count}개입니다. 문서 계층을 확인하세요.")

    # 표 열 개수 확인
    table_rows = re.findall(
        r"<tr\b[^>]*>(.*?)</tr>",
        lowered,
        flags=re.IGNORECASE | re.DOTALL,
    )

    for row_number, row in enumerate(table_rows, start=1):
        cell_count = len(re.findall(r"<t[hd]\b", row))

        if cell_count > 5:
            fail(
                f"{row_number}번째 표 행이 "
                f"5열을 초과합니다: {cell_count}열"
            )

    # 정의되지 않은 class 후보 확인
    allowed_classes = {
        "theme-navy",
        "theme-teal",
        "theme-plum",
        "cover",
        "cover-label",
        "cover-content",
        "cover-title",
        "cover-subtitle",
        "cover-meta",
        "report-section",
        "section-header",
        "section-kicker",
        "section-title",
        "section-description",
        "executive-summary",
        "metric-grid",
        "metric-card",
        "metric-label",
        "metric-value",
        "metric-description",
        "card-grid",
        "info-card",
        "badge",
        "success",
        "warning",
        "danger",
        "process-flow",
        "process-step",
        "process-number",
        "timeline",
        "timeline-item",
        "timeline-period",
        "insight-box",
        "risk-box",
        "action-box",
        "box-label",
        "conclusion-panel",
        "figure-block",
        "figure-caption",
        "report-table",
        "two-column",
        "three-column",
        "keep-together",
        "page-break",
        "toc",
        "toc-page",
    }

    class_values = re.findall(
        r'class=[\"\']([^\"\']+)[\"\']',
        html,
        flags=re.IGNORECASE,
    )

    unknown_classes: set[str] = set()

    for class_value in class_values:
        for class_name in class_value.split():
            if class_name not in allowed_classes:
                unknown_classes.add(class_name)

    if unknown_classes:
        unknown_text = ", ".join(sorted(unknown_classes))
        fail(f"정의되지 않은 CSS class가 있습니다: {unknown_text}")

    # 문서 구성 권장 사항
    if "cover" not in lowered:
        print("[WARN] 표지 컴포넌트가 없습니다.")

    if "executive-summary" not in lowered:
        print("[WARN] 핵심 요약 컴포넌트가 없습니다.")

    if "conclusion-panel" not in lowered:
        print("[WARN] 결론 패널이 없습니다.")

    print(f"[PASS] HTML 검증 완료: {html_path}")
    print(f"       파일 크기: {html_path.stat().st_size:,} bytes")
    print(f"       H1: {h1_count}개")
    print(f"       H2: {h2_count}개")
    print(f"       표 행: {len(table_rows)}개")


if __name__ == "__main__":
    main()
