"""Tests for internal admin dashboard endpoints."""

from app.services.account_service import create_user, record_file_history, set_user_role, update_user_plan
from app.services.contact_service import save_message
from app.services.rating_service import submit_rating


class TestInternalAdminRoutes:
    def test_overview_requires_authenticated_admin(self, client):
        response = client.get("/api/internal/admin/overview")

        assert response.status_code == 401

    def test_overview_rejects_non_admin_user(self, app, client):
        with app.app_context():
            create_user("member@example.com", "testpass123")

        login_response = client.post(
            "/api/auth/login",
            json={"email": "member@example.com", "password": "testpass123"},
        )
        assert login_response.status_code == 200

        response = client.get("/api/internal/admin/overview")
        assert response.status_code == 403

    def test_overview_returns_operational_summary(self, app, client):
        with app.app_context():
            first_user = create_user("admin-a@example.com", "testpass123")
            second_user = create_user("admin-b@example.com", "testpass123")
            set_user_role(first_user["id"], "admin")
            update_user_plan(second_user["id"], "pro")

            record_file_history(
                user_id=first_user["id"],
                tool="compress-pdf",
                original_filename="one.pdf",
                output_filename="one-small.pdf",
                status="completed",
                download_url="https://example.com/one-small.pdf",
            )
            record_file_history(
                user_id=second_user["id"],
                tool="repair-pdf",
                original_filename="broken.pdf",
                output_filename=None,
                status="failed",
                download_url=None,
                metadata={"error": "Repair failed."},
            )

            submit_rating("compress-pdf", 5, fingerprint="admin-rating")
            message = save_message("Admin User", "ops@example.com", "bug", "Need help", "Broken upload")

        login_response = client.post(
            "/api/auth/login",
            json={"email": "admin-a@example.com", "password": "testpass123"},
        )
        assert login_response.status_code == 200

        response = client.get("/api/internal/admin/overview")

        assert response.status_code == 200
        data = response.get_json()
        assert data["users"]["total"] == 2
        assert data["users"]["pro"] == 1
        assert data["processing"]["total_files_processed"] == 2
        assert data["processing"]["failed_files"] == 1
        assert data["ratings"]["rating_count"] == 1
        assert data["contacts"]["unread_messages"] == 1
        assert data["contacts"]["recent"][0]["id"] == message["id"]
        assert data["recent_failures"][0]["tool"] == "repair-pdf"

    def test_contacts_can_be_marked_read(self, app, client):
        with app.app_context():
            admin_user = create_user("admin-reader@example.com", "testpass123")
            set_user_role(admin_user["id"], "admin")
            message = save_message("Reader", "reader@example.com", "general", "Hello", "Please review")

        login_response = client.post(
            "/api/auth/login",
            json={"email": "admin-reader@example.com", "password": "testpass123"},
        )
        assert login_response.status_code == 200

        mark_response = client.post(f"/api/internal/admin/contacts/{message['id']}/read")
        assert mark_response.status_code == 200

        contacts_response = client.get("/api/internal/admin/contacts")
        assert contacts_response.status_code == 200
        contacts_data = contacts_response.get_json()
        assert contacts_data["unread"] == 0
        assert contacts_data["items"][0]["is_read"] is True

    def test_user_plan_can_be_updated(self, app, client):
        with app.app_context():
            admin_user = create_user("admin-plan@example.com", "testpass123")
            user = create_user("plan-change@example.com", "testpass123")
            set_user_role(admin_user["id"], "admin")

        login_response = client.post(
            "/api/auth/login",
            json={"email": "admin-plan@example.com", "password": "testpass123"},
        )
        assert login_response.status_code == 200

        response = client.post(
            f"/api/internal/admin/users/{user['id']}/plan",
            json={"plan": "pro"},
        )

        assert response.status_code == 200
        data = response.get_json()
        assert data["user"]["plan"] == "pro"

    def test_user_role_can_be_updated(self, app, client):
        with app.app_context():
            admin_user = create_user("admin-role@example.com", "testpass123")
            user = create_user("member-role@example.com", "testpass123")
            set_user_role(admin_user["id"], "admin")

        login_response = client.post(
            "/api/auth/login",
            json={"email": "admin-role@example.com", "password": "testpass123"},
        )
        assert login_response.status_code == 200

        response = client.post(
            f"/api/internal/admin/users/{user['id']}/role",
            json={"role": "admin"},
        )

        assert response.status_code == 200
        data = response.get_json()
        assert data["user"]["role"] == "admin"

    def test_allowlisted_admin_role_cannot_be_changed(self, app, client):
        app.config["INTERNAL_ADMIN_EMAILS"] = ("bootstrap-admin@example.com",)
        with app.app_context():
            actor = create_user("actor-admin@example.com", "testpass123")
            bootstrap = create_user("bootstrap-admin@example.com", "testpass123")
            set_user_role(actor["id"], "admin")

        login_response = client.post(
            "/api/auth/login",
            json={"email": "actor-admin@example.com", "password": "testpass123"},
        )
        assert login_response.status_code == 200

        response = client.post(
            f"/api/internal/admin/users/{bootstrap['id']}/role",
            json={"role": "user"},
        )

        assert response.status_code == 400
        assert "INTERNAL_ADMIN_EMAILS" in response.get_json()["error"]

    def test_admin_cannot_remove_own_role(self, app, client):
        with app.app_context():
            admin_user = create_user("self-admin@example.com", "testpass123")
            set_user_role(admin_user["id"], "admin")

        login_response = client.post(
            "/api/auth/login",
            json={"email": "self-admin@example.com", "password": "testpass123"},
        )
        assert login_response.status_code == 200

        response = client.post(
            f"/api/internal/admin/users/{admin_user['id']}/role",
            json={"role": "user"},
        )

        assert response.status_code == 400
        assert "cannot remove your own admin role" in response.get_json()["error"].lower()