"""Test role switching lifecycle — owner→engineer→reset, etc.

These tests verify that the session remains consistent after role switches.
The critical check: after a reset, the original role's access is fully restored.
"""

import httpx
from tests.conftest import SERVER_URL, PASSWORD


class TestRoleSwitch:

    def _login(self, role: str) -> httpx.Client:
        """Create a fresh authenticated client."""
        c = httpx.Client(base_url=SERVER_URL, follow_redirects=False, timeout=10)
        resp = c.post("/service/login", data={"login": role, "password": PASSWORD})
        assert resp.status_code == 302
        return c

    def _switch_role(self, client: httpx.Client, target: str):
        resp = client.post("/service/api/role/switch", json={"role": target})
        assert resp.status_code == 200
        data = resp.json()
        assert data["ok"] is True
        return data

    def _reset_role(self, client: httpx.Client):
        resp = client.post("/service/api/role/reset")
        assert resp.status_code == 200
        data = resp.json()
        assert data["ok"] is True
        return data

    def test_owner_to_engineer_and_back(self):
        """Owner switches to engineer, then resets — full access restored."""
        client = self._login("owner")

        # Owner can access owner pages
        r = client.get("/service/users")
        assert r.status_code == 200

        # Switch to engineer
        data = self._switch_role(client, "engineer")
        assert data["role"] == "engineer"
        assert data["original_role"] == "owner"

        # Engineer cannot access owner pages
        r = client.get("/service/users")
        assert r.status_code == 403, "Engineer should be denied owner pages"

        # Engineer CAN access shared pages
        r = client.get("/service/customers")
        assert r.status_code == 200

        # Reset to owner
        data = self._reset_role(client)
        assert data["role"] == "owner"

        # CRITICAL: Owner access restored
        r = client.get("/service/users")
        assert r.status_code == 200, "Owner access not restored after reset!"

        # Dashboard still works
        r = client.get("/service/dashboard")
        assert r.status_code == 200

    def test_owner_to_technician_and_back(self):
        """Owner switches directly to technician."""
        client = self._login("owner")

        r = client.get("/service/users")
        assert r.status_code == 200

        self._switch_role(client, "technician")

        r = client.get("/service/users")
        assert r.status_code == 403

        r = client.get("/service/tasks")
        assert r.status_code == 200

        self._reset_role(client)

        r = client.get("/service/users")
        assert r.status_code == 200

    def test_engineer_to_technician_and_back(self):
        """Engineer switches to technician, then resets."""
        client = self._login("engineer")

        # Engineer can access engineer pages
        r = client.get("/service/customers")
        assert r.status_code == 200

        self._switch_role(client, "technician")

        # Technician cannot access engineer pages
        r = client.get("/service/customers")
        assert r.status_code == 403

        r = client.get("/service/checklist")
        assert r.status_code == 200

        self._reset_role(client)

        # Engineer access restored
        r = client.get("/service/customers")
        assert r.status_code == 200

    def test_double_switch_owner_engineer_technician_then_reset(self):
        """Multi-step: owner→engineer→technician→reset→owner."""
        client = self._login("owner")

        self._switch_role(client, "engineer")
        r = client.get("/service/users")
        assert r.status_code == 403

        # Switch deeper while already impersonating
        self._switch_role(client, "technician")
        r = client.get("/service/users")
        assert r.status_code == 403
        r = client.get("/service/tasks")
        assert r.status_code == 200

        # Single reset should restore owner
        self._reset_role(client)
        r = client.get("/service/users")
        assert r.status_code == 200

    def test_forbidden_switch_technician_cannot_switch(self):
        """Technician cannot use role switch (not in allowed_roles)."""
        client = self._login("technician")
        resp = client.post("/service/api/role/switch", json={"role": "owner"})
        assert resp.status_code == 403

    def test_reset_without_switch_does_not_error(self):
        """Reset without an active override should still work."""
        client = self._login("owner")
        resp = client.post("/service/api/role/reset")
        assert resp.status_code == 200
        data = resp.json()
        assert data["role"] == "owner"
