import requests
import time
import json
import sys
import os

BASE = "http://127.0.0.1:5000"
PASS = "\033[92mPASS\033[0m"
FAIL = "\033[91mFAIL\033[0m"
WARN = "\033[93mWARN\033[0m"
RUN_AI = os.environ.get("RUN_AI_TESTS", "0") == "1"

results = {"passed": 0, "failed": 0, "warnings": 0}


def test(name, condition, detail=""):
    if condition:
        print(f"  {PASS}  {name}")
        results["passed"] += 1
    else:
        print(f"  {FAIL}  {name}  {detail}")
        results["failed"] += 1


def warn(name, detail=""):
    print(f"  {WARN}  {name}  {detail}")
    results["warnings"] += 1


def section(title):
    print(f"\n{'='*60}")
    print(f"  {title}")
    print(f"{'='*60}")


def poll_job(job_id, timeout=120):
    start = time.time()
    while time.time() - start < timeout:
        r = requests.get(f"{BASE}/api/job/{job_id}")
        if r.status_code != 200:
            return None
        data = r.json()
        status = data.get("status", "")
        if status == "complete":
            return data
        if status in ("failed", "error"):
            return data
        time.sleep(2)
    return {"status": "timeout"}


section("1. Dashboard & Static Assets")

r = requests.get(f"{BASE}/")
test("Dashboard loads (200)", r.status_code == 200)
test("Dashboard contains Aura branding", "Aura" in r.text)
test("Dashboard links app.js", "app.js" in r.text)
test("Cache-Control header present", "cache-control" in {k.lower(): v for k, v in r.headers.items()})

r = requests.get(f"{BASE}/static/app.js")
test("app.js loads (200)", r.status_code == 200)
test("app.js has confirmBlueprint", "confirmBlueprint" in r.text)
test("app.js has submitPackageBuild", "submitPackageBuild" in r.text)
test("app.js has showToast", "showToast" in r.text)

r = requests.get(f"{BASE}/static/style.css")
test("style.css loads (200)", r.status_code == 200)


section("2. Blueprint API")

r = requests.get(f"{BASE}/api/blueprint/default?depth=comprehensive")
test("Default blueprint loads (200)", r.status_code == 200)
bp = r.json()
test("Blueprint has sections", "sections" in bp and len(bp.get("sections", [])) > 0)
test("Blueprint has depth", "depth" in bp)
test("Blueprint depth is comprehensive", bp.get("depth") == "comprehensive")

section_keys = [s["key"] for s in bp.get("sections", [])]
test("Has hero section", "hero" in section_keys)

for depth in ["minimal", "standard", "comprehensive", "legendary"]:
    r = requests.get(f"{BASE}/api/blueprint/default?depth={depth}")
    test(f"Blueprint preset '{depth}' loads", r.status_code == 200 and "sections" in r.json())

r = requests.get(f"{BASE}/api/blueprint/presets")
test("Blueprint presets endpoint (200)", r.status_code == 200)
presets_data = r.json()
test("Presets has presets key", "presets" in presets_data)
test("Presets has categories key", "categories" in presets_data)


section("3. Blueprint Validation")

valid_bp = {"sections": [{"key": "hero", "label": "Hero", "enabled": True, "fields": {"headline": "Test"}}]}
r = requests.post(f"{BASE}/api/blueprint/validate", json=valid_bp)
test("Blueprint validation endpoint works", r.status_code == 200)

empty_bp = {"sections": []}
r = requests.post(f"{BASE}/api/blueprint/validate", json=empty_bp)
test("Empty blueprint validation returns result", r.status_code == 200)


section("4. Content Import")

csv_text = "headline,subheadline\nTest Title,Test Subtitle"
r = requests.post(f"{BASE}/api/blueprint/import-content", json={"text": csv_text, "format": "csv"})
test("CSV import endpoint works", r.status_code == 200)
import_data = r.json()
test("CSV import returns parsed data", "parsed" in import_data)
test("CSV import has field_count", "field_count" in import_data)

r = requests.post(f"{BASE}/api/blueprint/import-content", json={"text": "", "format": "auto"})
test("Empty import returns 400", r.status_code == 400)


section("5. Domain Analysis (End-to-End)")

r = requests.post(f"{BASE}/api/analyze-domain", json={"domain": "quicktest.com"})
test("Analyze domain starts (200)", r.status_code == 200)
analysis_result = r.json()
test("Analyze returns job_id", "job_id" in analysis_result)

if RUN_AI:
    test_domain = f"testdomain{int(time.time()) % 10000}.com"
    r = requests.post(f"{BASE}/api/analyze-domain", json={"domain": test_domain})
    job_id = r.json().get("job_id", "")
    if job_id:
        print(f"  ... Polling job {job_id} (up to 120s)")
        job_result = poll_job(job_id)
        if job_result:
            status = job_result.get("status", "")
            test("Analysis job completed", status == "complete", f"status={status}")
        else:
            warn("Analysis job timed out")
else:
    print(f"  ... Skipping AI analysis poll (set RUN_AI_TESTS=1 to enable)")


section("6. Package Build & Existing Data Tests")

r = requests.get(f"{BASE}/api/domains")
domains = r.json()
test("Domains list endpoint works", r.status_code == 200)
test("Domains list is array", isinstance(domains, list))

analyzed_domain = None
has_packages = False
for d in domains:
    analysis = d.get("analysis")
    if analysis and isinstance(analysis, dict):
        niches = analysis.get("niches", [])
        if niches:
            analyzed_domain = d.get("domain")
            niche_name = niches[0].get("name", "Test Niche") if isinstance(niches[0], dict) else str(niches[0])
            break

if analyzed_domain:
    print(f"  Found analyzed domain: {analyzed_domain}")

    r = requests.get(f"{BASE}/api/packages/{analyzed_domain}")
    test("Packages API responds (200)", r.status_code == 200)
    pkg_data = r.json()
    test("Package data is list", isinstance(pkg_data, list))
    has_packages = len(pkg_data) > 0

    if has_packages:
        pkg = pkg_data[0]
        test("Package has brand", "brand" in pkg)
        test("Package has site_copy", "site_copy" in pkg)
        test("Package has domain_name", "domain_name" in pkg)

    if RUN_AI:
        print(f"  Building package for: {analyzed_domain} / {niche_name}")
        r = requests.post(f"{BASE}/api/build-package", json={
            "domain": analyzed_domain,
            "niche_name": niche_name,
            "template_type": "hero",
            "layout_style": "single-scroll",
            "density": "balanced",
        })
        test("Build package starts (200)", r.status_code == 200)
        build_job_id = r.json().get("job_id", "")
        if build_job_id:
            print(f"  ... Polling build job {build_job_id} (up to 120s)")
            build_job = poll_job(build_job_id)
            if build_job:
                bstatus = build_job.get("status", "")
                test("Package build completed", bstatus == "complete", f"status={bstatus}")
            else:
                warn("Build job timed out")
    else:
        print(f"  ... Skipping AI package build (set RUN_AI_TESTS=1 to enable)")

    if has_packages:
        section("7. Generated Site & Sales Pages")

        r = requests.get(f"{BASE}/site/{analyzed_domain}")
        test("Site page loads (200)", r.status_code == 200)
        test("Site page has content", len(r.text) > 500)

        r = requests.get(f"{BASE}/sales/{analyzed_domain}")
        test("Sales page loads (200)", r.status_code == 200)
        test("Sales page has content", len(r.text) > 500)

        section("8. Editor")

        r = requests.get(f"{BASE}/editor/{analyzed_domain}")
        test("Editor page loads (200)", r.status_code == 200)
        test("Editor page has content", len(r.text) > 500)

        section("9. Exports")

        r = requests.get(f"{BASE}/api/export/{analyzed_domain}")
        test("Export endpoint responds", r.status_code == 200)

        r = requests.get(f"{BASE}/api/export/{analyzed_domain}/niches-csv")
        test("Niches CSV export responds", r.status_code == 200)

        section("10. Blueprint Completeness")

        r = requests.get(f"{BASE}/api/blueprint/completeness/{analyzed_domain}")
        test("Completeness endpoint responds", r.status_code == 200)
        if r.status_code == 200:
            comp = r.json()
            test("Completeness has percentage", "percentage" in comp or "overall" in comp)
    else:
        print(f"  ... No existing packages - skipping site/editor/export tests")
else:
    print(f"  ... No analyzed domains found - skipping data-dependent tests")


section("12. Health Check / Validation")

r = requests.get(f"{BASE}/api/health/validate")
test("Health validate endpoint (200)", r.status_code == 200)
health = r.json()
test("Health has 'healthy' key", "healthy" in health)
test("Health has 'summary' key", "summary" in health)
if "summary" in health:
    s = health["summary"]
    test("Summary has domains_checked", "domains_checked" in s)
    test("Summary has packages_checked", "packages_checked" in s)
    test("Summary has total_errors", "total_errors" in s)
    test("No render failures", s.get("render_failures", 0) == 0, f"render_failures={s.get('render_failures', 0)}")


section("13. Error Handling")

r = requests.post(f"{BASE}/api/analyze-domain", json={"domain": ""})
test("Empty domain returns 400", r.status_code == 400)

r = requests.post(f"{BASE}/api/build-package", json={"domain": "nonexistent.fake", "niche_name": "test"})
test("Nonexistent domain build returns 404", r.status_code == 404)

r = requests.get(f"{BASE}/api/job/nonexistent-id")
test("Nonexistent job returns 404", r.status_code == 404)

r = requests.get(f"{BASE}/api/blueprint/completeness/nonexistent.fake")
test("Completeness for missing domain returns 404", r.status_code == 404)


section("14. Augment Types API")

r = requests.get(f"{BASE}/api/augment-types")
test("Augment types endpoint (200)", r.status_code == 200)


section("15. Roadmap")

r = requests.get(f"{BASE}/roadmap")
test("Roadmap page loads", r.status_code == 200)


print(f"\n{'='*60}")
print(f"  RESULTS")
print(f"{'='*60}")
print(f"  Passed:   {results['passed']}")
print(f"  Failed:   {results['failed']}")
print(f"  Warnings: {results['warnings']}")
print(f"{'='*60}")

if results["failed"] > 0:
    print(f"\n  {FAIL} {results['failed']} test(s) failed!")
    sys.exit(1)
else:
    print(f"\n  {PASS} All tests passed!")
    sys.exit(0)
