#!/usr/bin/env python3
"""
Validator cho output file hiệu đính (edited.md)

Kiểm tra:
- File tồn tại, không rỗng
- Có header trang đúng format (## Trang X)
- Có phân cách trang (---)
- Có đủ số trang như batch khai báo
- Không chứa garbage text (Lào, Khmer, replacement chars)
- Tỉ lệ Unicode Myanmar hợp lý (>50% text)

Usage:
    python3 scripts/validate_output.py edited/vdp-011-015.md 11 15
    python3 scripts/validate_output.py edited/Sadi-001-005.md 1 5
"""

import re
import sys
import os
import unicodedata


# Unicode ranges
MYANMAR_RANGE = (0x1000, 0x109F)
MYANMAR_EXT_A = (0xAA60, 0xAA7F)
MYANMAR_EXT_B = (0xA9E0, 0xA9FF)
LAO_RANGE = (0x0E80, 0x0EFF)
KHMER_RANGE = (0x1780, 0x17FF)
REPLACEMENT_CHAR = '\ufffd'


def is_myanmar(char: str) -> bool:
    cp = ord(char)
    return (MYANMAR_RANGE[0] <= cp <= MYANMAR_RANGE[1] or
            MYANMAR_EXT_A[0] <= cp <= MYANMAR_EXT_A[1] or
            MYANMAR_EXT_B[0] <= cp <= MYANMAR_EXT_B[1])


def parse_page_range(pages_str: str) -> tuple[int, int]:
    """Parse '11-15' -> (11, 15)"""
    parts = pages_str.split("-")
    return int(parts[0]), int(parts[-1])


def validate_output(filepath: str, start_page: int, end_page: int) -> tuple[bool, list[str]]:
    """Validate output file structure."""
    errors = []
    warnings = []

    # 1. File tồn tại
    if not os.path.exists(filepath):
        errors.append(f"MISSING: File {filepath} không tồn tại")
        return False, errors

    # 2. File không rỗng
    size = os.path.getsize(filepath)
    if size == 0:
        errors.append(f"EMPTY: File {filepath} rỗng (0 bytes)")
        return False, errors

    # 3. Đọc nội dung
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            content = f.read()
    except Exception as e:
        errors.append(f"READ ERROR: {e}")
        return False, errors

    # 4. Kiểm tra garbage
    foreign_chars = []
    for ch in content:
        cp = ord(ch)
        if LAO_RANGE[0] <= cp <= LAO_RANGE[1]:
            foreign_chars.append(('Lào', ch, content.find(ch)))
        elif KHMER_RANGE[0] <= cp <= KHMER_RANGE[1]:
            foreign_chars.append(('Khmer', ch, content.find(ch)))
        elif ch == REPLACEMENT_CHAR:
            foreign_chars.append(('Replacement', '�', content.find('�')))

    if foreign_chars:
        for script, char, pos in foreign_chars[:5]:  # max 5
            errors.append(f"GARBAGE: Ký tự {script} '{char}' ở vị trí {pos}")
        if len(foreign_chars) > 5:
            errors.append(f"GARBAGE: ... còn {len(foreign_chars)-5} ký tự lạ khác")

    # 5. Kiểm tra Vietnamese garbage phrases
    garbage_phrases = [
        "Ok, đây là dữ liệu bạn yêu cầu",
        "Dưới đây là",
        "Here is the",
        "I'll extract",
        "Let me",
    ]
    for phrase in garbage_phrases:
        if phrase in content:
            errors.append(f"GARBAGE: Chứa cụm tiếng Việt/Anh không mong muốn: '{phrase}'")

    # 6. Kiểm tra page markers
    expected_pages = list(range(start_page, end_page + 1))
    found_pages = []

    # Tìm tất cả "## Trang X" hoặc "## Trang XX - XX"
    page_pattern = re.compile(r'^##\s+Trang\s+(\d+)', re.MULTILINE)
    for match in page_pattern.finditer(content):
        found_pages.append(int(match.group(1)))

    # Cũng chấp nhận format "## Trang pdf XXX"
    page_pdf_pattern = re.compile(r'^##\s+Trang\s+pdf\s+(\d+)', re.MULTILINE)
    for match in page_pdf_pattern.finditer(content):
        p = int(match.group(1))
        if p not in found_pages:
            found_pages.append(p)

    missing_pages = set(expected_pages) - set(found_pages)
    extra_pages = set(found_pages) - set(expected_pages)

    if missing_pages:
        errors.append(f"MISSING PAGES: Thiếu trang {sorted(missing_pages)}")
    if extra_pages:
        warnings.append(f"EXTRA PAGES: Có thêm trang {sorted(extra_pages)}")

    # 7. Kiểm tra separator giữa các trang
    separators = content.count('\n---\n')
    expected_separators = len(expected_pages) - 1
    if separators < expected_separators:
        warnings.append(f"SEPARATOR: Thiếu phân cách trang ({separators}/{expected_separators} dấu ---)")
    elif separators > expected_separators + 3:
        warnings.append(f"SEPARATOR: Quá nhiều phân cách ({separators} vs expected ~{expected_separators})")

    # 8. Tỉ lệ Myanmar text
    total_chars = len(content.strip())
    if total_chars > 100:
        myanmar_count = sum(1 for ch in content if is_myanmar(ch))
        myanmar_ratio = myanmar_count / total_chars if total_chars > 0 else 0

        if myanmar_ratio < 0.1:
            errors.append(f"LOW MYANMAR: Chỉ {myanmar_ratio:.1%} ký tự Myanmar (cần >10%)")
        elif myanmar_ratio < 0.3 and total_chars > 500:
            warnings.append(f"LOW MYANMAR: {myanmar_ratio:.1%} ký tự Myanmar — kiểm tra lại")

    # 9. Kiểm tra không có heading level quá cao (h1)
    h1_count = len(re.findall(r'^#\s[^#]', content, re.MULTILINE))
    if h1_count > 0:
        warnings.append(f"H1 FOUND: {h1_count} heading level 1 (# ) — nên dùng ## hoặc ###")

    # 10. Kiểm tra bold markers có cặp không
    bold_open = content.count('**')
    if bold_open % 2 != 0:
        errors.append("BOLD MISMATCH: Số dấu ** lẻ — có bold marker chưa đóng")

    # 11. Dòng quá dài (có thể là nối file lỗi)
    long_lines = [i+1 for i, line in enumerate(content.split('\n')) if len(line) > 2000]
    if long_lines:
        warnings.append(f"LONG LINES: {len(long_lines)} dòng >2000 ký tự (dòng {long_lines[:5]})")

    return len(errors) == 0, errors + warnings


def main():
    if len(sys.argv) < 3:
        print("Usage: python3 validate_output.py <file.md> <start_page> <end_page>")
        print("Example: python3 validate_output.py edited/vdp-011-015.md 11 15")
        sys.exit(1)

    filepath = sys.argv[1]
    start_page = int(sys.argv[2])
    end_page = int(sys.argv[3])

    valid, messages = validate_output(filepath, start_page, end_page)

    errors = [m for m in messages if not m.startswith(('EXTRA', 'SEPARATOR', 'LOW MYANMAR', 'H1', 'LONG'))]
    warnings = [m for m in messages if m not in errors]

    if warnings:
        for w in warnings:
            print(f"⚠️  {w}")

    if errors:
        print(f"❌ VALIDATION FAILED ({len(errors)} lỗi):")
        for e in errors:
            print(f"   • {e}")
        sys.exit(1)

    print(f"✅ VALID — {os.path.basename(filepath)} OK ({os.path.getsize(filepath):,} bytes, {len(open(filepath).readlines())} dòng)")
    sys.exit(0)


if __name__ == "__main__":
    main()
