"""
Integration smoke tests for admin-user and DAO features.

Tests both direct localhost access and the ez-input.com nginx proxy paths.
"""

import base64
import os
import sys
from pathlib import Path

import httpx
import pytest

# Allow importing the backend plugin system if needed
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))

ADMIN_URL = os.environ.get("ADMIN_URL", "http://localhost:8082")
DAO_URL = os.environ.get("DAO_URL", "http://localhost:18003")
EZ_URL = os.environ.get("EZ_URL", "https://ez-input.com")
DAO_KEY = os.environ.get("DAO_KEY", "zenmirage-internal")


def _basic_token(username: str, password: str) -> str:
    return base64.b64encode(f"{username}:{password}".encode()).decode()


@pytest.fixture
def admin_token() -> str:
    return _basic_token("admin", "admin")


class TestAdminUserAPI:
    def test_login(self, admin_token: str):
        r = httpx.post(
            f"{ADMIN_URL}/api/auth/login",
            json={"username": "admin", "password": "admin"},
        )
        assert r.status_code == 200
        data = r.json()
        assert data["user"]["username"] == "admin"
        assert data["user"]["role"] == "admin"

    def test_list_users(self, admin_token: str):
        r = httpx.get(
            f"{ADMIN_URL}/api/users",
            headers={"Authorization": f"Basic {admin_token}"},
        )
        assert r.status_code == 200
        users = r.json()
        assert isinstance(users, list)
        assert any(u["username"] == "admin" and u["role"] == "admin" for u in users)

    def test_user_crud(self, admin_token: str):
        headers = {"Authorization": f"Basic {admin_token}"}
        new_user = {
            "username": "integration_test_user",
            "password": "testpass123",
            "role": "user",
            "display_name": "Integration Test",
        }

        # Create
        r = httpx.post(f"{ADMIN_URL}/api/users", json=new_user, headers=headers)
        assert r.status_code == 200, r.text
        created = r.json()
        user_id = created["id"]
        assert created["username"] == new_user["username"]

        # Read
        r = httpx.get(f"{ADMIN_URL}/api/users/{user_id}", headers=headers)
        assert r.status_code == 200
        assert r.json()["display_name"] == new_user["display_name"]

        # Update
        r = httpx.put(
            f"{ADMIN_URL}/api/users/{user_id}",
            json={"display_name": "Updated Name"},
            headers=headers,
        )
        assert r.status_code == 200
        assert r.json()["display_name"] == "Updated Name"

        # Delete
        r = httpx.delete(f"{ADMIN_URL}/api/users/{user_id}", headers=headers)
        assert r.status_code == 200

        r = httpx.get(f"{ADMIN_URL}/api/users/{user_id}", headers=headers)
        assert r.status_code == 404

    def test_me_endpoint(self, admin_token: str):
        headers = {"Authorization": f"Basic {admin_token}"}
        r = httpx.get(f"{ADMIN_URL}/api/me", headers=headers)
        assert r.status_code == 200
        assert r.json()["username"] == "admin"


class TestMimicDAO:
    def test_health(self):
        r = httpx.get(f"{DAO_URL}/health")
        assert r.status_code == 200
        assert r.json()["status"] == "ok"

    def test_dao_lifecycle(self):
        headers = {"X-Diamond-Key": DAO_KEY}

        # Create
        r = httpx.post(
            f"{DAO_URL}/dao",
            json={"name": "Integration DAO", "description": "test", "creator": "admin"},
            headers=headers,
        )
        assert r.status_code == 200, r.text
        data = r.json()
        assert data["success"]
        dao_id = data["dao_id"]

        # Get info
        r = httpx.get(f"{DAO_URL}/dao/{dao_id}", headers=headers)
        assert r.status_code == 200
        assert r.json()["name"] == "Integration DAO"

        # Join
        r = httpx.post(
            f"{DAO_URL}/dao/{dao_id}/join",
            json={"user_id": "member1"},
            headers=headers,
        )
        assert r.status_code == 200
        assert r.json()["member_count"] == 2

        # Proposal
        r = httpx.post(
            f"{DAO_URL}/dao/{dao_id}/proposals",
            json={"title": "Test Proposal", "description": "integration", "creator": "admin"},
            headers=headers,
        )
        assert r.status_code == 200
        proposal_id = r.json()["proposal_id"]

        # List proposals
        r = httpx.get(f"{DAO_URL}/dao/{dao_id}/proposals", headers=headers)
        assert r.status_code == 200
        proposals = r.json()["proposals"]
        assert any(p["proposal_id"] == proposal_id for p in proposals)

        # Vote
        r = httpx.post(
            f"{DAO_URL}/proposals/{proposal_id}/vote",
            json={"user_id": "member1", "vote_type": "for"},
            headers=headers,
        )
        assert r.status_code == 200
        assert r.json()["votes_for"] == 1

        # Treasury deposit
        r = httpx.post(
            f"{DAO_URL}/dao/{dao_id}/treasury/deposit",
            json={"user_id": "admin", "amount": 99.99},
            headers=headers,
        )
        assert r.status_code == 200, r.text
        assert r.json()["balance"] == 99.99

        # Treasury balance
        r = httpx.get(f"{DAO_URL}/dao/{dao_id}/treasury", headers=headers)
        assert r.status_code == 200
        assert r.json()["balance"] == 99.99


class TestEzInputProxy:
    """Verify the public ez-input.com proxy routes are reachable."""

    def test_landing(self):
        r = httpx.get(EZ_URL, follow_redirects=True)
        assert r.status_code == 200
        assert "EZ-Input" in r.text or "Emergent" in r.text

    def test_health(self):
        r = httpx.get(f"{EZ_URL}/health", follow_redirects=True)
        assert r.status_code == 200
        assert r.text.strip() == "ez-input-ok"

    def test_admin_panel_proxy(self):
        r = httpx.get(f"{EZ_URL}/admin-panel/static/index.html", follow_redirects=True)
        assert r.status_code == 200

    def test_dao_health_proxy(self):
        r = httpx.get(f"{EZ_URL}/api/dao/health", follow_redirects=True)
        assert r.status_code == 200
        assert r.json()["status"] == "ok"
