#!/usr/bin/env python3
"""
validate-blog-post.py
Post-publish validation for CannaDeals FL blog posts.

Usage: python3 validate-blog-post.py <slug>
       python3 validate-blog-post.py --status

Checks:
  1. Blog post URL returns 200
  2. Image URL extracted from page returns 200 (not HTML/text)
  3. /blog listing page includes the post
  4. Screenshots the live post (via Playwright) for visual verification

Tracks consecutive successes. After 5, auto-disables visual check.
Results logged to: scripts/blog-validation-log.json
"""

import sys
import json
import re
import subprocess
import os
import argparse
from datetime import datetime, timezone
from pathlib import Path
import urllib.request
import urllib.error

BASE_URL = "https://cannadealsfl.com"
LOG_FILE = Path(__file__).parent / "blog-validation-log.json"
AUTO_DISABLE_AFTER = 5

def load_log():
    if LOG_FILE.exists():
        return json.loads(LOG_FILE.read_text())
    return {"consecutive_successes": 0, "visual_check_enabled": True, "results": []}

def save_log(data):
    LOG_FILE.write_text(json.dumps(data, indent=2))

def http_check(url, expect_content_type=None):
    """Returns (status_code, content_type, error)"""
    try:
        req = urllib.request.Request(url, headers={"User-Agent": "CannadealsValidator/1.0"})
        with urllib.request.urlopen(req, timeout=15) as r:
            ct = r.headers.get("Content-Type", "")
            return r.status, ct, None
    except urllib.error.HTTPError as e:
        return e.code, "", str(e)
    except Exception as e:
        return 0, "", str(e)

def extract_image_url(slug):
    """Fetch the blog post page and extract the featured image URL."""
    url = f"{BASE_URL}/blog/{slug}"
    try:
        req = urllib.request.Request(url, headers={"User-Agent": "CannadealsValidator/1.0"})
        with urllib.request.urlopen(req, timeout=15) as r:
            html = r.read().decode("utf-8", errors="ignore")
        # Look for og:image or img src with blog/headers
        for pattern in [
            r'<meta[^>]+property="og:image"[^>]+content="([^"]+)"',
            r'src="(https://cannadealsfl\.com/api/images/images/blog/headers/[^"]+)"',
            r'src="(/api/images/images/blog/headers/[^"]+)"',
        ]:
            m = re.search(pattern, html)
            if m:
                img = m.group(1)
                if img.startswith("/"):
                    img = BASE_URL + img
                return img
    except Exception as e:
        return None
    return None

def check_blog_listing(slug):
    """Verify the post appears on /blog listing page."""
    try:
        req = urllib.request.Request(f"{BASE_URL}/blog", headers={"User-Agent": "CannadealsValidator/1.0"})
        with urllib.request.urlopen(req, timeout=15) as r:
            html = r.read().decode("utf-8", errors="ignore")
        return slug in html
    except:
        return False

def screenshot_post(slug):
    """Take a screenshot using Playwright on carl via SSH."""
    try:
        cmd = [
            "ssh", "carl",
            f"cd ~/cannadealsfl && source venv/bin/activate && python3 -c \""
            f"import asyncio; from playwright.async_api import async_playwright\n"
            f"async def main():\n"
            f"    async with async_playwright() as p:\n"
            f"        b = await p.chromium.launch()\n"
            f"        page = await b.new_page(viewport={{'width':1280,'height':720}})\n"
            f"        await page.goto('{BASE_URL}/blog/{slug}', wait_until='networkidle', timeout=20000)\n"
            f"        await page.screenshot(path='/tmp/validate-{slug[:40]}.png')\n"
            f"        await b.close()\n"
            f"asyncio.run(main())\n\""
        ]
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=40)
        if result.returncode == 0:
            # SCP screenshot back
            local_path = f"/tmp/validate-{slug[:40]}.png"
            subprocess.run(["scp", f"carl:/tmp/validate-{slug[:40]}.png", local_path],
                         capture_output=True, timeout=15)
            return local_path if Path(local_path).exists() else None
    except Exception as e:
        return None

def validate(slug):
    log = load_log()
    result = {
        "slug": slug,
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "checks": {},
        "passed": False,
    }

    print(f"\n🔍 Validating: {BASE_URL}/blog/{slug}")

    # Check 1: Post URL returns 200
    post_url = f"{BASE_URL}/blog/{slug}"
    code, ct, err = http_check(post_url)
    result["checks"]["post_url"] = {"url": post_url, "status": code, "pass": code == 200}
    icon = "✅" if code == 200 else "❌"
    print(f"  {icon} Post URL: HTTP {code}")

    # Check 2: Extract and validate image URL
    img_url = extract_image_url(slug)
    if img_url:
        img_code, img_ct, img_err = http_check(img_url)
        is_image = "image/" in img_ct
        result["checks"]["image_url"] = {
            "url": img_url,
            "status": img_code,
            "content_type": img_ct,
            "pass": img_code == 200 and is_image
        }
        icon = "✅" if (img_code == 200 and is_image) else "❌"
        print(f"  {icon} Image URL: HTTP {img_code} ({img_ct or 'unknown'})")
        if img_code == 200 and not is_image:
            print(f"     ⚠️  Content-Type is not image/* — serving HTML instead!")
    else:
        result["checks"]["image_url"] = {"url": None, "pass": False, "error": "Could not extract image URL"}
        print(f"  ❌ Image URL: Could not extract from page")

    # Check 3: Appears in /blog listing
    in_listing = check_blog_listing(slug)
    result["checks"]["blog_listing"] = {"pass": in_listing}
    icon = "✅" if in_listing else "❌"
    print(f"  {icon} Blog listing: {'Found' if in_listing else 'NOT found on /blog page'}")

    # Check 4: Screenshot (if visual check enabled)
    if log.get("visual_check_enabled", True):
        print(f"  📸 Taking screenshot...")
        screenshot_path = screenshot_post(slug)
        result["checks"]["screenshot"] = {"path": screenshot_path, "pass": screenshot_path is not None}
        icon = "✅" if screenshot_path else "⚠️"
        print(f"  {icon} Screenshot: {screenshot_path or 'Failed (non-blocking)'}")
    else:
        print(f"  ⏭️  Visual check disabled (5 consecutive successes reached)")
        result["checks"]["screenshot"] = {"pass": True, "skipped": True}

    # Determine overall pass
    critical_checks = ["post_url", "image_url", "blog_listing"]
    result["passed"] = all(result["checks"].get(c, {}).get("pass") for c in critical_checks)

    # Update consecutive success count
    if result["passed"]:
        log["consecutive_successes"] = log.get("consecutive_successes", 0) + 1
        if log["consecutive_successes"] >= AUTO_DISABLE_AFTER and log.get("visual_check_enabled", True):
            log["visual_check_enabled"] = False
            print(f"\n  🎉 {AUTO_DISABLE_AFTER} consecutive successes — visual check auto-disabled")
    else:
        log["consecutive_successes"] = 0
        log["visual_check_enabled"] = True  # Re-enable visual check on failure

    log.setdefault("results", []).append(result)
    log["results"] = log["results"][-50:]  # Keep last 50
    save_log(log)

    status = "✅ PASSED" if result["passed"] else "❌ FAILED"
    print(f"\n{status} — Consecutive successes: {log['consecutive_successes']}/{AUTO_DISABLE_AFTER}")

    if not result["passed"]:
        print("\n⚠️  ACTION NEEDED: Blog post has validation failures. Do not promote until fixed.")

    return result["passed"]

def show_status():
    log = load_log()
    print(f"Blog Validation Status")
    print(f"  Consecutive successes: {log.get('consecutive_successes', 0)}/{AUTO_DISABLE_AFTER}")
    print(f"  Visual check enabled: {log.get('visual_check_enabled', True)}")
    results = log.get("results", [])
    if results:
        print(f"  Last 5 results:")
        for r in results[-5:]:
            icon = "✅" if r["passed"] else "❌"
            print(f"    {icon} {r['timestamp'][:16]} — {r['slug'][:50]}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("slug", nargs="?", help="Blog post slug to validate")
    parser.add_argument("--status", action="store_true", help="Show validation status")
    args = parser.parse_args()

    if args.status:
        show_status()
    elif args.slug:
        success = validate(args.slug)
        sys.exit(0 if success else 1)
    else:
        parser.print_help()
        sys.exit(1)
