"""
Smoke tests for DAO voting endpoints in mimic_dao/main.py.

This is a focused test for the DAO voting scope. It exercises:
- DAO creation and membership (prerequisites)
- Proposal creation (prerequisite)
- Casting votes (for/against/abstain)
- Vote tallying
- Closing a proposal and final tally
"""

import os
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / ".openclaw/workspace/zenmirage-deploy"))

# Keep tests from polluting the production DAO state file.
os.environ.setdefault("MIMIC_DAO_STATE_PATH", str(Path(__file__).parent / "test_dao_voting_state.json"))

from fastapi.testclient import TestClient

from mimic_dao.main import app, API_KEY, dao_registry


def setup_module() -> None:
    """Reset in-memory DAO state and clear any persisted test state file."""
    dao_registry.daos.clear()
    if dao_registry.state_path and os.path.exists(dao_registry.state_path):
        os.remove(dao_registry.state_path)


def teardown_module() -> None:
    """Clean up the temporary test state file."""
    if dao_registry.state_path and os.path.exists(dao_registry.state_path):
        os.remove(dao_registry.state_path)


def test_dao_voting_flow() -> None:
    client = TestClient(app)
    headers = {"X-Diamond-Key": API_KEY}
    creator = "voter_test_creator"
    member_a = "voter_test_alice"
    member_b = "voter_test_bob"

    # Create a DAO
    r = client.post("/dao", json={"name": "Voting Test DAO", "description": "test", "creator": creator}, headers=headers)
    assert r.status_code == 200
    data = r.json()
    assert data["success"] is True
    dao_id = data["dao_id"]

    # Add members
    for user in (member_a, member_b):
        r = client.post(f"/dao/{dao_id}/join", json={"user_id": user}, headers=headers)
        assert r.status_code == 200, r.text

    # Create a proposal
    r = client.post(
        f"/dao/{dao_id}/proposals",
        json={"title": "Should we upgrade the protocol?", "description": "Vote yes or no", "creator": creator},
        headers=headers,
    )
    assert r.status_code == 200, r.text
    data = r.json()
    assert data["success"] is True
    proposal_id = data["proposal_id"]

    # Cast votes
    votes = [
        (member_a, "for"),
        (member_b, "against"),
        (creator, "for"),
    ]
    for user, vote in votes:
        r = client.post(
            f"/proposals/{proposal_id}/vote",
            json={"user_id": user, "vote": vote},
            headers=headers,
        )
        assert r.status_code == 200, r.text
        body = r.json()
        assert body["success"] is True
        assert body["proposal_id"] == proposal_id
        assert body["vote_type"] == vote
        assert "tally" in body

    # Verify vote can be changed before the proposal closes
    r = client.post(
        f"/proposals/{proposal_id}/vote",
        json={"user_id": member_a, "vote": "abstain"},
        headers=headers,
    )
    assert r.status_code == 200, r.text
    assert r.json()["tally"] == {"for": 1, "against": 1, "abstain": 1}

    # Close the proposal
    r = client.post(f"/proposals/{proposal_id}/close", json={"user_id": creator}, headers=headers)
    assert r.status_code == 200, r.text
    body = r.json()
    assert body["success"] is True
    assert body["status"] == "closed"
    assert body["tally"] == {"for": 1, "against": 1, "abstain": 1}

    # Voting on a closed proposal is rejected
    r = client.post(
        f"/proposals/{proposal_id}/vote",
        json={"user_id": "late_voter", "vote": "for"},
        headers=headers,
    )
    assert r.status_code == 400, r.text

    # Invalid vote type is rejected
    new_r = client.post(
        f"/dao/{dao_id}/proposals",
        json={"title": "Second proposal", "description": "test", "creator": creator},
        headers=headers,
    )
    pid2 = new_r.json()["proposal_id"]
    r = client.post(
        f"/proposals/{pid2}/vote",
        json={"user_id": creator, "vote": "maybe"},
        headers=headers,
    )
    assert r.status_code == 422, r.text


def test_vote_on_missing_proposal() -> None:
    client = TestClient(app)
    headers = {"X-Diamond-Key": API_KEY}
    r = client.post(
        "/proposals/nosuch/vote",
        json={"user_id": "anyone", "vote": "for"},
        headers=headers,
    )
    assert r.status_code == 400, r.text
    assert "not found" in r.json()["detail"].lower()
