import os
import re
from pathlib import Path
from urllib.parse import urlparse


ROOT = Path(__file__).resolve().parents[1]

TEXT_EXTS = {".php", ".html", ".htm"}

HREF_SRC_RE = re.compile(
    r"""(?ix)
    \b(?:href|src)\s*=\s*
    (?:
      "([^"]+)" |
      '([^']+)'
    )
    """
)

PHP_BROKEN_RE = re.compile(r"<\.php\?php", re.IGNORECASE)


def is_external(url: str) -> bool:
    if url.startswith(("mailto:", "tel:", "javascript:", "#", "data:")):
        return True
    parsed = urlparse(url)
    return parsed.scheme in {"http", "https"} or url.startswith("//")


def normalize_local(url: str) -> str:
    # strip query/hash
    url = url.split("#", 1)[0].split("?", 1)[0]
    return url


def iter_files():
    for dirpath, dirnames, filenames in os.walk(ROOT):
        # Skip common heavy folders
        dirnames[:] = [d for d in dirnames if d not in {"_next", "__website-next", "cdn-cgi", "node_modules"}]
        for fn in filenames:
            p = Path(dirpath) / fn
            if p.suffix.lower() in TEXT_EXTS:
                try:
                    if p.stat().st_size > 800_000:
                        continue
                except Exception:
                    pass
                yield p


def main():
    broken_php = []
    missing_targets = []  # (file, url)
    missing_local_assets = []  # (file, url)

    for p in iter_files():
        try:
            data = p.read_text(encoding="utf-8", errors="ignore")
        except Exception:
            continue

        if PHP_BROKEN_RE.search(data):
            broken_php.append(str(p.relative_to(ROOT)))

        for m in HREF_SRC_RE.finditer(data):
            url = m.group(1) or m.group(2) or ""
            url = url.strip()
            if not url or is_external(url):
                continue

            local = normalize_local(url)
            # absolute-from-root like /aaa/foo.php
            if local.startswith("/"):
                # map /aaa/... to workspace root
                if local.startswith("/aaa/"):
                    local_path = ROOT / local.removeprefix("/aaa/")
                else:
                    local_path = ROOT / local.lstrip("/")
            else:
                local_path = (p.parent / local).resolve()

            # Only check if inside root
            try:
                local_path.relative_to(ROOT)
            except Exception:
                continue

            # If it's a directory link, allow (might be routed)
            if local.endswith("/"):
                if not local_path.exists():
                    missing_targets.append((str(p.relative_to(ROOT)), url))
                continue

            if not local_path.exists():
                # Distinguish pages vs assets
                if local_path.suffix.lower() in {".php", ".html", ".htm"}:
                    missing_targets.append((str(p.relative_to(ROOT)), url))
                else:
                    missing_local_assets.append((str(p.relative_to(ROOT)), url))

    print("=== AUDIT SUMMARY ===")
    print(f"Broken PHP tag patterns (<.php?php): {len(broken_php)} files")
    print(f"Missing internal page targets: {len(missing_targets)}")
    print(f"Missing local assets (images/css/js): {len(missing_local_assets)}")
    print()

    if broken_php:
        print("== Files with broken PHP tag pattern ==")
        for f in sorted(set(broken_php))[:200]:
            print(f"- {f}")
        if len(set(broken_php)) > 200:
            print("... truncated ...")
        print()

    if missing_targets:
        print("== Missing internal page targets (first 200) ==")
        for f, url in missing_targets[:200]:
            print(f"- {f} -> {url}")
        if len(missing_targets) > 200:
            print("... truncated ...")
        print()

    if missing_local_assets:
        print("== Missing local assets (first 200) ==")
        for f, url in missing_local_assets[:200]:
            print(f"- {f} -> {url}")
        if len(missing_local_assets) > 200:
            print("... truncated ...")


if __name__ == "__main__":
    main()

