"""
Integration tests for Phase 1 Daily Helper API endpoints
"""

import pytest
import json
from datetime import date, datetime
from fastapi.testclient import TestClient


class TestUserProfileAPI:
    """Tests for User Profile API endpoints"""

    def test_create_user_profile(self, client):
        """Test creating a user profile"""
        payload = {
            "email": "test@example.com",
            "username": "testuser",
            "timezone": "EST",
            "trading_style": "day_trader",
            "risk_tolerance": "moderate",
            "preferred_trading_start": "09:00",
            "preferred_trading_end": "17:00",
            "daily_target": 1000.0,
            "max_loss": 500.0,
        }

        response = client.post("/api/daily-helper/profile", json=payload)

        assert response.status_code == 201
        data = response.json()
        assert data["email"] == "test@example.com"
        assert data["timezone"] == "EST"

    def test_get_user_profile(self, client, user_profile):
        """Test retrieving user profile"""
        response = client.get("/api/daily-helper/profile")

        assert response.status_code == 200
        data = response.json()
        assert "id" in data
        assert "email" in data

    def test_update_user_profile(self, client, user_profile):
        """Test updating user profile"""
        payload = {
            "timezone": "PST",
            "daily_target": 2000.0,
        }

        response = client.put("/api/daily-helper/profile", json=payload)

        assert response.status_code == 200
        data = response.json()
        assert data["timezone"] == "PST"
        assert data["daily_target"] == 2000.0

    def test_profile_validation(self, client):
        """Test profile input validation"""
        # Missing required fields
        payload = {
            "email": "test@example.com",
        }

        response = client.post("/api/daily-helper/profile", json=payload)

        # Should still succeed with defaults
        assert response.status_code in [200, 201]


class TestDailyRoutineAPI:
    """Tests for Daily Routine API endpoints"""

    def test_create_routine(self, client):
        """Test creating a daily routine"""
        payload = {
            "routine_type": "morning",
            "scheduled_time": "08:30",
            "tasks": ["market_brief", "checklist", "review_plan"],
            "enabled": True,
        }

        response = client.post("/api/daily-helper/routines", json=payload)

        assert response.status_code == 201
        data = response.json()
        assert data["routine_type"] == "morning"
        assert len(data["tasks"]) == 3

    def test_list_routines(self, client, daily_routine):
        """Test listing routines"""
        response = client.get("/api/daily-helper/routines")

        assert response.status_code == 200
        data = response.json()
        assert isinstance(data, list)
        assert len(data) > 0

    def test_get_routine(self, client, daily_routine):
        """Test retrieving a specific routine"""
        response = client.get(f"/api/daily-helper/routines/{daily_routine.id}")

        assert response.status_code == 200
        data = response.json()
        assert data["id"] == daily_routine.id

    def test_update_routine(self, client, daily_routine):
        """Test updating a routine"""
        payload = {
            "scheduled_time": "09:00",
            "enabled": False,
        }

        response = client.put(
            f"/api/daily-helper/routines/{daily_routine.id}",
            json=payload
        )

        assert response.status_code == 200
        data = response.json()
        assert data["scheduled_time"] == "09:00"
        assert data["enabled"] == False

    def test_filter_routines(self, client, daily_routine):
        """Test filtering routines"""
        response = client.get(
            f"/api/daily-helper/routines?routine_type=morning"
        )

        assert response.status_code == 200
        data = response.json()
        for routine in data:
            assert routine["routine_type"] == "morning"

    def test_execute_routine(self, client, daily_routine):
        """Test executing a routine"""
        response = client.post(
            f"/api/daily-helper/routines/{daily_routine.id}/execute"
        )

        assert response.status_code == 201
        data = response.json()
        assert "completion_status" in data

    def test_get_routine_executions(self, client, daily_routine):
        """Test retrieving routine execution history"""
        response = client.get(
            f"/api/daily-helper/routines/{daily_routine.id}/executions"
        )

        assert response.status_code == 200
        data = response.json()
        assert isinstance(data, list)


class TestNotificationAPI:
    """Tests for Notification API endpoints"""

    def test_create_notification(self, client):
        """Test creating a notification"""
        payload = {
            "notification_type": "price_alert",
            "title": "Price Alert",
            "message": "Gold price exceeded $2000",
            "priority": "high",
            "delivery_method": "push",
        }

        response = client.post("/api/daily-helper/notifications", json=payload)

        assert response.status_code == 201
        data = response.json()
        assert data["notification_type"] == "price_alert"
        assert data["read"] == False

    def test_list_notifications(self, client, notification):
        """Test listing notifications"""
        response = client.get("/api/daily-helper/notifications")

        assert response.status_code == 200
        data = response.json()
        assert "notifications" in data
        assert "unread_count" in data
        assert "total_count" in data

    def test_get_notification(self, client, notification):
        """Test retrieving a specific notification"""
        response = client.get(f"/api/daily-helper/notifications/{notification.id}")

        assert response.status_code == 200
        data = response.json()
        assert data["id"] == notification.id

    def test_mark_notification_read(self, client, notification):
        """Test marking notification as read"""
        response = client.put(
            f"/api/daily-helper/notifications/{notification.id}/read"
        )

        assert response.status_code == 200
        data = response.json()
        assert data["read"] == True

    def test_mark_all_notifications_read(self, client, notification):
        """Test marking all notifications as read"""
        response = client.post(
            "/api/daily-helper/notifications/mark-all-read"
        )

        assert response.status_code == 200

    def test_filter_notifications(self, client, notification):
        """Test filtering notifications"""
        response = client.get(
            "/api/daily-helper/notifications?notification_type=price_alert"
        )

        assert response.status_code == 200
        data = response.json()
        for notif in data["notifications"]:
            assert notif["notification_type"] == "price_alert"


class TestDailyChecklistAPI:
    """Tests for Daily Checklist API endpoints"""

    def test_create_checklist(self, client):
        """Test creating a daily checklist"""
        payload = {
            "checklist_type": "morning",
            "items": [
                {"id": "1", "title": "Check Economic Calendar", "completed": False},
                {"id": "2", "title": "Create Trading Plan", "completed": False},
            ],
            "notes": "Daily morning checklist",
        }

        response = client.post("/api/daily-helper/checklists", json=payload)

        assert response.status_code == 201
        data = response.json()
        assert data["checklist_type"] == "morning"
        assert len(data["items"]) == 2

    def test_get_today_checklist(self, client, daily_checklist):
        """Test retrieving today's checklist"""
        response = client.get("/api/daily-helper/checklists/today")

        assert response.status_code == 200
        data = response.json()
        if data:  # Might be None if none exists
            assert data["checklist_date"] == date.today().isoformat()

    def test_list_checklists(self, client, daily_checklist):
        """Test listing checklists"""
        response = client.get("/api/daily-helper/checklists")

        assert response.status_code == 200
        data = response.json()
        assert isinstance(data, list)

    def test_update_checklist(self, client, daily_checklist):
        """Test updating a checklist"""
        payload = {
            "notes": "Updated notes",
        }

        response = client.put(
            f"/api/daily-helper/checklists/{daily_checklist.id}",
            json=payload
        )

        assert response.status_code == 200
        data = response.json()
        assert data["notes"] == "Updated notes"

    def test_update_checklist_item(self, client, daily_checklist):
        """Test updating a specific checklist item"""
        # Assume first item exists
        item_id = daily_checklist.items[0]["id"] if daily_checklist.items else "1"

        response = client.put(
            f"/api/daily-helper/checklists/{daily_checklist.id}/items/{item_id}",
            json={"completed": True}
        )

        assert response.status_code == 200
        data = response.json()
        # Should have updated completion percentage
        assert data["completion_percentage"] >= 0


class TestHabitTrackerAPI:
    """Tests for Habit Tracker API endpoints"""

    def test_create_habit(self, client):
        """Test creating a habit"""
        payload = {
            "habit_name": "Daily Planning",
            "frequency": "daily",
        }

        response = client.post("/api/daily-helper/habits", json=payload)

        assert response.status_code == 201
        data = response.json()
        assert data["habit_name"] == "Daily Planning"
        assert data["current_streak"] == 0

    def test_list_habits(self, client, habit):
        """Test listing habits"""
        response = client.get("/api/daily-helper/habits")

        assert response.status_code == 200
        data = response.json()
        assert isinstance(data, list)

    def test_get_habit(self, client, habit):
        """Test retrieving a specific habit"""
        response = client.get(f"/api/daily-helper/habits/{habit.id}")

        assert response.status_code == 200
        data = response.json()
        assert data["id"] == habit.id

    def test_log_habit_completion(self, client, habit):
        """Test logging habit completion"""
        payload = {
            "habit_id": habit.id,
        }

        response = client.post(
            f"/api/daily-helper/habits/{habit.id}/log",
            json=payload
        )

        assert response.status_code == 200
        data = response.json()
        assert data["total_completions"] >= 1

    def test_habit_streak_update(self, client, habit):
        """Test that habit streak updates on completion"""
        # Log completion
        payload = {"habit_id": habit.id}
        response = client.post(
            f"/api/daily-helper/habits/{habit.id}/log",
            json=payload
        )

        assert response.status_code == 200
        data = response.json()
        assert data["current_streak"] >= 0


class TestDashboardAPI:
    """Tests for Dashboard summary endpoint"""

    def test_get_dashboard_summary(self, client):
        """Test getting dashboard summary"""
        response = client.get("/api/daily-helper/dashboard")

        assert response.status_code == 200
        data = response.json()

        assert "today_date" in data
        assert "checklists" in data
        assert "unread_notifications" in data
        assert "habits_summary" in data
        assert "pending_routines" in data


class TestErrorHandling:
    """Tests for error handling"""

    def test_not_found_error(self, client):
        """Test 404 error handling"""
        response = client.get("/api/daily-helper/routines/99999")

        assert response.status_code == 404

    def test_invalid_data_error(self, client):
        """Test validation error handling"""
        payload = {
            "routine_type": "morning",
            # Missing required field: scheduled_time
        }

        response = client.post("/api/daily-helper/routines", json=payload)

        # Should fail validation
        assert response.status_code in [400, 422]


# Fixtures

@pytest.fixture
def client():
    """Create test client"""
    from fastapi.testclient import TestClient
    from app.main import app

    return TestClient(app)


@pytest.fixture
def user_profile(client, db):
    """Create a test user profile"""
    payload = {
        "email": "test@example.com",
        "timezone": "EST",
    }
    response = client.post("/api/daily-helper/profile", json=payload)
    return response.json()


@pytest.fixture
def daily_routine(client):
    """Create a test daily routine"""
    payload = {
        "routine_type": "morning",
        "scheduled_time": "08:30",
        "tasks": ["market_brief"],
        "enabled": True,
    }
    response = client.post("/api/daily-helper/routines", json=payload)
    return response.json()


@pytest.fixture
def notification(client):
    """Create a test notification"""
    payload = {
        "notification_type": "price_alert",
        "title": "Test Alert",
        "message": "Test message",
    }
    response = client.post("/api/daily-helper/notifications", json=payload)
    return response.json()


@pytest.fixture
def daily_checklist(client):
    """Create a test daily checklist"""
    payload = {
        "checklist_type": "morning",
        "items": [
            {"id": "1", "title": "Item 1", "completed": False},
        ],
    }
    response = client.post("/api/daily-helper/checklists", json=payload)
    return response.json()


@pytest.fixture
def habit(client):
    """Create a test habit"""
    payload = {
        "habit_name": "Test Habit",
        "frequency": "daily",
    }
    response = client.post("/api/daily-helper/habits", json=payload)
    return response.json()


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
