"""Tests 1, 2, 6, 10: API integration tests for profiles, build, context hooks, CRUD."""
import pytest
import json


EXPECTED_PROFILE_SLUGS = {"default", "affiliate-landing", "authority-knowledge", "saas-product", "local-services"}


class TestProfilesSeededList:
    """Test 1: GET /api/profiles returns all seeded profiles."""

    def test_profiles_returns_200(self, client):
        resp = client.get("/api/profiles")
        assert resp.status_code == 200

    def test_profiles_has_minimum_count(self, client):
        resp = client.get("/api/profiles")
        data = resp.json()
        profiles = data if isinstance(data, list) else data.get("profiles", [])
        assert len(profiles) >= 5, f"Expected at least 5 profiles, got {len(profiles)}"

    def test_profiles_contain_expected_slugs(self, client):
        resp = client.get("/api/profiles")
        data = resp.json()
        profiles = data if isinstance(data, list) else data.get("profiles", [])
        slugs = {p["slug"] for p in profiles}
        assert EXPECTED_PROFILE_SLUGS.issubset(slugs), f"Missing slugs: {EXPECTED_PROFILE_SLUGS - slugs}"

    def test_each_profile_has_required_fields(self, client):
        resp = client.get("/api/profiles")
        data = resp.json()
        profiles = data if isinstance(data, list) else data.get("profiles", [])
        for p in profiles:
            assert "name" in p, f"Profile missing 'name': {p}"
            assert "slug" in p, f"Profile missing 'slug': {p}"
            assert "section_count" in p or "id" in p

    def test_default_profile_is_marked_default(self, client):
        resp = client.get("/api/profiles")
        data = resp.json()
        profiles = data if isinstance(data, list) else data.get("profiles", [])
        defaults = [p for p in profiles if p.get("is_default")]
        assert len(defaults) >= 1, "No profile marked as default"
        assert defaults[0]["slug"] == "default"


class TestProfileGetBySlug:
    """Test 10 (partial): GET /api/profiles/{slug} returns correct profile."""

    def test_get_default_profile(self, client):
        resp = client.get("/api/profiles/default")
        assert resp.status_code == 200
        data = resp.json()
        assert data["slug"] == "default"
        assert "config" in data

    def test_get_affiliate_profile(self, client):
        resp = client.get("/api/profiles/affiliate-landing")
        assert resp.status_code == 200
        data = resp.json()
        assert data["slug"] == "affiliate-landing"
        assert "config" in data

    def test_get_nonexistent_profile_404(self, client):
        resp = client.get("/api/profiles/nonexistent-profile-xyz")
        assert resp.status_code == 404


class TestProfileCRUD:
    """Test 10: Create, read, update, delete, import/export."""

    TEST_SLUG = "test-crud-profile"

    def test_create_profile(self, client):
        client.delete(f"/api/profiles/{self.TEST_SLUG}")
        resp = client.post("/api/profiles", json={
            "name": "Test CRUD Profile",
            "slug": self.TEST_SLUG,
            "description": "Profile for automated testing",
            "config": {
                "sections": ["hero", "features", "footer"],
                "enabled_sections": ["hero", "features", "footer"],
                "depth_presets": {
                    "standard": {"label": "Standard", "sections": ["hero", "features", "footer"], "content_multiplier": 1.0},
                },
                "discovery_fields": [
                    {"step": 1, "step_title": "Test", "step_description": "Testing", "fields": [
                        {"key": "test_field", "label": "Test", "type": "input", "placeholder": "test"}
                    ]},
                ],
                "prompt_overrides": {},
                "visual_defaults": {},
                "meta": {"version": "1.0"},
            },
        })
        assert resp.status_code == 200, f"Create failed: {resp.text}"

    def test_read_created_profile(self, client):
        resp = client.get(f"/api/profiles/{self.TEST_SLUG}")
        assert resp.status_code == 200
        data = resp.json()
        assert data["slug"] == self.TEST_SLUG
        assert data["config"]["sections"] == ["hero", "features", "footer"]

    def test_update_profile(self, client):
        resp = client.put(f"/api/profiles/{self.TEST_SLUG}", json={
            "description": "Updated description for testing",
        })
        assert resp.status_code == 200

        resp2 = client.get(f"/api/profiles/{self.TEST_SLUG}")
        assert "Updated description" in resp2.json().get("description", "")

    def test_export_profile(self, client):
        resp = client.get(f"/api/profiles/{self.TEST_SLUG}/export")
        assert resp.status_code == 200
        data = resp.json()
        assert "name" in data
        assert "config" in data

    def test_delete_profile(self, client):
        resp = client.delete(f"/api/profiles/{self.TEST_SLUG}")
        assert resp.status_code == 200

        resp2 = client.get(f"/api/profiles/{self.TEST_SLUG}")
        assert resp2.status_code == 404

    def test_import_profile(self, client):
        import_data = {
            "name": "Imported Test Profile",
            "description": "Imported via test",
            "config": {
                "sections": ["hero", "footer"],
                "enabled_sections": ["hero", "footer"],
                "depth_presets": {
                    "standard": {"label": "Standard", "sections": ["hero", "footer"], "content_multiplier": 1.0},
                },
                "discovery_fields": [
                    {"step": 1, "step_title": "Basic", "step_description": "Basics", "fields": [
                        {"key": "f1", "label": "Field 1", "type": "input", "placeholder": "test"}
                    ]},
                ],
                "prompt_overrides": {},
                "visual_defaults": {},
                "meta": {"version": "1.0"},
            },
        }
        resp = client.post("/api/profiles/import", json=import_data)
        assert resp.status_code == 200, f"Import failed: {resp.text}"
        data = resp.json()
        imported_slug = data.get("slug", "imported-test-profile")

        resp2 = client.get(f"/api/profiles/{imported_slug}")
        assert resp2.status_code == 200

        client.delete(f"/api/profiles/{imported_slug}")


class TestContextHooks:
    """Test 6: Context hooks fire during operations — ProjectContext is updated."""

    def test_project_context_api_returns_data(self, client, db_session):
        from app.models import ProjectContext
        existing = db_session.query(ProjectContext).filter(ProjectContext.domain == "test-hooks.com").first()
        if not existing:
            ctx = ProjectContext(
                domain="test-hooks.com",
                context_state={"selected_niche": "test-niche", "profile_slug": "default"},
                event_log=[{"timestamp": "2026-01-01T00:00:00Z", "action": "build_started", "detail": "test"}],
            )
            db_session.add(ctx)
            db_session.commit()

        resp = client.get("/api/context/test-hooks.com")
        assert resp.status_code == 200
        data = resp.json()
        assert "context" in data or "assembled" in data or isinstance(data, dict)

    def test_global_context_get(self, client):
        resp = client.get("/api/global-context")
        assert resp.status_code == 200
        data = resp.json()
        assert "master_rules" in data

    def test_global_context_update(self, client):
        resp = client.put("/api/global-context", json={
            "master_rules": "Test rule: always be specific",
            "style_prefs": {"tone": "authoritative"},
        })
        assert resp.status_code == 200

        resp2 = client.get("/api/global-context")
        data = resp2.json()
        assert "Test rule" in data.get("master_rules", "")

        client.put("/api/global-context", json={"master_rules": "", "style_prefs": {}})


class TestBuildRequestWithProfileSlug:
    """Test 2: Build request accepts profile_slug and stores it in ProjectContext."""

    def test_build_request_schema_accepts_profile_slug(self, client, db_session):
        from app.models import Domain
        domain = db_session.query(Domain).first()
        if not domain or not domain.analysis:
            pytest.skip("No analyzed domain in DB to test build request")

        niches = domain.analysis.get("niches", [])
        if not niches:
            pytest.skip("No niches available")

        niche_name = niches[0].get("name", "")
        resp = client.post("/api/build-package", json={
            "domain": domain.domain,
            "niche_name": niche_name,
            "profile_slug": "affiliate-landing",
        })
        assert resp.status_code == 200
        data = resp.json()
        assert "job_id" in data
