from __future__ import annotations

from django.test import RequestFactory, TestCase
from django.urls import resolve, reverse

from core.context_processors import settings_hierarchy_nav
from core.security.capabilities import all_scope_keys
from core.models import CommandProfile, TaskProject, User


class SettingsIntegrityTests(TestCase):
    def setUp(self):
        self.user = User.objects.create_user(
            username="settings-user",
            email="settings@example.com",
            password="x",
        )
        self.client.force_login(self.user)
        self.factory = RequestFactory()

    def test_permissions_page_shows_gateway_capabilities(self):
        response = self.client.get(reverse("permission_settings"))
        self.assertEqual(200, response.status_code)
        self.assertContains(response, "Gateway contacts command")
        self.assertContains(response, "Gateway help command")
        self.assertContains(response, "Gateway whoami command")
        for scope_key in all_scope_keys(configurable_only=True):
            self.assertContains(response, scope_key)

    def test_capability_registry_excludes_removed_totp_scope(self):
        self.assertNotIn("gateway.totp", all_scope_keys())

    def test_tasks_settings_receives_modules_settings_nav(self):
        response = self.client.get(reverse("tasks_settings"))
        self.assertEqual(200, response.status_code)
        settings_nav = response.context.get("settings_nav")
        self.assertIsNotNone(settings_nav)
        self.assertEqual("Modules", settings_nav["title"])
        labels = [str(item["label"]) for item in settings_nav["tabs"]]
        self.assertIn("Commands", labels)
        self.assertIn("Task Automation", labels)
        self.assertNotIn("Codex", labels)
        group_labels = [str(item["label"]) for item in settings_nav["groups"]]
        self.assertEqual(["General", "Security", "AI", "Modules"], group_labels)

    def test_business_plan_inbox_receives_modules_settings_nav(self):
        response = self.client.get(reverse("business_plan_inbox"))
        self.assertEqual(200, response.status_code)
        settings_nav = response.context.get("settings_nav")
        self.assertIsNotNone(settings_nav)
        self.assertEqual("Modules", settings_nav["title"])
        active_tabs = [str(item["label"]) for item in settings_nav["tabs"] if item["active"]]
        self.assertEqual(["Business Plans"], active_tabs)

    def test_behavioral_settings_receives_modules_settings_nav(self):
        response = self.client.get(reverse("behavioral_signals_settings"))
        self.assertEqual(200, response.status_code)
        settings_nav = response.context.get("settings_nav")
        self.assertIsNotNone(settings_nav)
        self.assertEqual("Modules", settings_nav["title"])
        labels = [str(item["label"]) for item in settings_nav["tabs"]]
        self.assertIn("Behavioral Signals", labels)

    def test_security_settings_receives_group_and_child_tabs(self):
        response = self.client.get(reverse("encryption_settings"))
        self.assertEqual(200, response.status_code)
        settings_nav = response.context.get("settings_nav")
        self.assertIsNotNone(settings_nav)
        self.assertEqual("Security", settings_nav["title"])
        active_groups = [str(item["label"]) for item in settings_nav["groups"] if item["active"]]
        self.assertEqual(["Security"], active_groups)
        active_tabs = [str(item["label"]) for item in settings_nav["tabs"] if item["active"]]
        self.assertEqual(["Encryption"], active_tabs)

    def test_tasks_settings_cross_links_commands_and_permissions(self):
        TaskProject.objects.create(user=self.user, name="Integrity Project")
        response = self.client.get(reverse("tasks_settings"))
        self.assertEqual(200, response.status_code)
        self.assertContains(response, "Task Automation")
        self.assertContains(response, reverse("command_routing"))
        self.assertContains(response, reverse("permission_settings"))

    def test_command_routing_cross_links_tasks_and_permissions(self):
        CommandProfile.objects.create(
            user=self.user,
            slug="bp",
            name="Business Plan",
            enabled=True,
            trigger_token=".bp",
            reply_required=False,
            exact_match_only=False,
        )
        response = self.client.get(reverse("command_routing"))
        self.assertEqual(200, response.status_code)
        self.assertContains(response, reverse("tasks_settings"))
        self.assertContains(response, reverse("permission_settings"))

    def test_settings_nav_includes_tasks_route(self):
        request = self.factory.get(reverse("tasks_settings"))
        request.user = self.user
        request.resolver_match = resolve(reverse("tasks_settings"))
        settings_nav = settings_hierarchy_nav(request)["settings_nav"]
        self.assertEqual("Modules", settings_nav["title"])
        active_tabs = [str(item["label"]) for item in settings_nav["tabs"] if item["active"]]
        self.assertEqual(["Task Automation"], active_tabs)

    def test_settings_nav_includes_translation_preview_route(self):
        request = self.factory.post(reverse("translation_preview"))
        request.user = self.user
        request.resolver_match = resolve(reverse("translation_preview"))
        settings_nav = settings_hierarchy_nav(request)["settings_nav"]
        self.assertEqual("Modules", settings_nav["title"])
        active_tabs = [str(item["label"]) for item in settings_nav["tabs"] if item["active"]]
        self.assertEqual(["Translation"], active_tabs)

    def test_settings_pages_with_shared_shell_render_section_container(self):
        for route_name in (
            "notifications_settings",
            "security_2fa",
            "ai_models",
            "ai_execution_log",
        ):
            with self.subTest(route_name=route_name):
                response = self.client.get(reverse(route_name))
                self.assertEqual(200, response.status_code)
                self.assertContains(response, '<section class="section">', html=False)
                self.assertContains(response, '<div class="container">', html=False)

    def test_home_nav_no_longer_shows_search_page_link(self):
        response = self.client.get(reverse("home"))
        self.assertEqual(200, response.status_code)
        self.assertNotContains(response, 'href="/search/page/"', html=False)

    def test_removed_search_page_returns_404(self):
        response = self.client.get("/search/page/")
        self.assertEqual(404, response.status_code)
