import requests
import time
import random
import string

# Base URL for API tests
BASE_URL = "http://localhost:8000"

class TestTritriAPI:
    """Test suite for Tritri API endpoints"""

    def generate_share_code(self):
        """Generate a random 6-character share code"""
        return ''.join(random.choices(string.ascii_uppercase + string.digits, k=6))

    def test_health_check(self):
        """Test if API is running"""
        response = requests.get(f"{BASE_URL}/")
        assert response.status_code == 200

    def test_create_trip(self):
        """Test trip creation"""
        trip_data = {
            "name": "Test Trip Paris",
            "creator_name": "John Doe",
            "currency_code": "USD"
        }

        response = requests.post(f"{BASE_URL}/api/trips/", json=trip_data)
        assert response.status_code == 200

        trip = response.json()
        assert trip["name"] == "Test Trip Paris"
        assert trip["currency_code"] == "USD"
        assert "share_code" in trip
        assert len(trip["share_code"]) == 6
        assert "id" in trip

        return trip

    def test_get_trip_by_id(self):
        """Test retrieving trip by ID"""
        # First create a trip
        trip = self.test_create_trip()

        # Then retrieve it
        response = requests.get(f"{BASE_URL}/api/trips/{trip['id']}")
        assert response.status_code == 200

        retrieved_trip = response.json()
        assert retrieved_trip["id"] == trip["id"]
        assert retrieved_trip["name"] == trip["name"]
        assert len(retrieved_trip["participants"]) == 1  # Creator should be a participant

    def test_get_trip_by_share_code(self):
        """Test retrieving trip by share code"""
        # First create a trip
        trip = self.test_create_trip()

        # Then retrieve by share code
        response = requests.get(f"{BASE_URL}/api/trips/share/{trip['share_code']}")
        assert response.status_code == 200

        retrieved_trip = response.json()
        assert retrieved_trip["id"] == trip["id"]
        assert retrieved_trip["name"] == trip["name"]
        assert len(retrieved_trip["participants"]) == 1

    def test_add_participant(self):
        """Test adding a participant to a trip"""
        # Create a trip
        trip = self.test_create_trip()

        # Add a participant
        participant_data = {
            "name": "Jane Smith"
        }

        response = requests.post(
            f"{BASE_URL}/api/participants/{trip['id']}/participants",
            json=participant_data
        )
        assert response.status_code == 200

        participant = response.json()
        assert participant["name"] == "Jane Smith"
        assert not participant["is_creator"]
        assert participant["trip_id"] == trip["id"]

        return participant

    def test_identify_user(self):
        """Test user identification with device ID"""
        # Create a trip
        trip_data = {
            "name": "Identity Test Trip",
            "creator_name": "Test Creator",
            "currency_code": "USD"
        }
        response = requests.post(f"{BASE_URL}/api/trips/", json=trip_data)
        trip = response.json()

        # Add a participant to this specific trip
        participant_data = {
            "name": "Test Participant"
        }
        response = requests.post(
            f"{BASE_URL}/api/participants/{trip['id']}/participants",
            json=participant_data
        )
        participant = response.json()

        # Get the trip data to verify participant was added
        trip_response = requests.get(f"{BASE_URL}/api/trips/{trip['id']}")
        trip_data = trip_response.json()

        # Find the participant we just added
        target_participant = None
        for p in trip_data["participants"]:
            if p["name"] == "Test Participant":
                target_participant = p
                break

        assert target_participant is not None

        # Identify user
        device_id = f"test_device_{int(time.time())}"

        response = requests.post(
            f"{BASE_URL}/api/auth/identify",
            params={
                "trip_id": trip["id"],
                "participant_id": target_participant["id"],
                "device_id": device_id
            }
        )
        assert response.status_code == 200

        result = response.json()
        assert "message" in result
        assert result["message"] == "User identified successfully"

    def test_multi_trip_identity(self):
        """Test multi-trip identity scenario"""
        # Create first trip
        trip1_data = {
            "name": "Business Trip New York",
            "creator_name": "Alice Johnson",
            "currency_code": "USD"
        }
        response1 = requests.post(f"{BASE_URL}/api/trips/", json=trip1_data)
        trip1 = response1.json()

        # Create second trip
        trip2_data = {
            "name": "Vacation Tokyo",
            "creator_name": "Alice Johnson",
            "currency_code": "JPY"
        }
        response2 = requests.post(f"{BASE_URL}/api/trips/", json=trip2_data)
        trip2 = response2.json()

        # Add participant to second trip
        participant_data = {"name": "Bob Wilson"}
        response = requests.post(
            f"{BASE_URL}/api/participants/{trip2['id']}/participants",
            json=participant_data
        )
        participant = response.json()

        # Verify both trips exist and are separate
        assert trip1["id"] != trip2["id"]
        assert trip1["share_code"] != trip2["share_code"]

        # Verify user is creator of first trip
        trip1_response = requests.get(f"{BASE_URL}/api/trips/{trip1['id']}")
        trip1_data = trip1_response.json()
        creators = [p for p in trip1_data["participants"] if p["is_creator"]]
        assert len(creators) == 1
        assert creators[0]["name"] == "Alice Johnson"

        # Verify user can be added as participant to second trip
        trip2_response = requests.get(f"{BASE_URL}/api/trips/{trip2['id']}")
        trip2_data = trip2_response.json()
        participant_names = [p["name"] for p in trip2_data["participants"]]
        assert "Bob Wilson" in participant_names

if __name__ == "__main__":
    # Run basic functionality test
    test_suite = TestTritriAPI()

    print("🧪 Starting Tritri API Tests...")

    try:
        test_suite.test_health_check()
        print("✅ Health check passed")

        test_suite.test_create_trip()
        print("✅ Trip creation test passed")

        test_suite.test_get_trip_by_id()
        print("✅ Get trip by ID test passed")

        test_suite.test_get_trip_by_share_code()
        print("✅ Get trip by share code test passed")

        test_suite.test_add_participant()
        print("✅ Add participant test passed")

        test_suite.test_identify_user()
        print("✅ User identification test passed")

        test_suite.test_multi_trip_identity()
        print("✅ Multi-trip identity test passed")

        print("\n🎉 All API tests passed!")

    except Exception as e:
        print(f"❌ Test failed: {e}")
        raise