"""
Comprehensive API testing suite.
Tests API endpoints to improve coverage.
"""

import pytest
from datetime import datetime, timedelta, date
from decimal import Decimal
import json


# ============================================================================
# Timer API Tests
# ============================================================================


@pytest.mark.api
@pytest.mark.integration
def test_start_timer_api(authenticated_client, project):
    """Test starting a timer via API."""
    response = authenticated_client.post(
        "/api/timer/start", json={"project_id": project.id, "notes": "Working on feature"}
    )

    # Should succeed or return appropriate status
    assert response.status_code in [200, 201, 404, 405]


@pytest.mark.api
@pytest.mark.integration
def test_get_timer_status(authenticated_client):
    """Test getting timer status."""
    response = authenticated_client.get("/api/timer/status")

    # Should return status or appropriate error
    assert response.status_code in [200, 404]


# ============================================================================
# Project API Tests
# ============================================================================


@pytest.mark.api
@pytest.mark.integration
def test_get_projects_list(authenticated_client):
    """Test getting list of projects."""
    response = authenticated_client.get("/api/projects")

    # Should return projects list or appropriate error
    assert response.status_code in [200, 404]


@pytest.mark.api
@pytest.mark.integration
def test_get_project_details(authenticated_client, project):
    """Test getting project details."""
    response = authenticated_client.get(f"/api/projects/{project.id}")

    # Should return project details or appropriate error
    assert response.status_code in [200, 404]


# ============================================================================
# Time Entry API Tests
# ============================================================================


@pytest.mark.api
@pytest.mark.integration
def test_get_time_entries(authenticated_client):
    """Test getting time entries list."""
    response = authenticated_client.get("/api/time-entries")

    # Should return time entries or appropriate error
    assert response.status_code in [200, 404]


@pytest.mark.api
@pytest.mark.integration
def test_get_time_entry_details(authenticated_client, time_entry):
    """Test getting time entry details."""
    response = authenticated_client.get(f"/api/time-entries/{time_entry.id}")

    # Should return time entry details or appropriate error
    assert response.status_code in [200, 404]


# ============================================================================
# Client API Tests
# ============================================================================


@pytest.mark.api
@pytest.mark.integration
def test_get_clients_list(authenticated_client):
    """Test getting list of clients."""
    response = authenticated_client.get("/api/clients")

    # Should return clients list or appropriate error
    assert response.status_code in [200, 404]


@pytest.mark.api
@pytest.mark.integration
def test_get_client_details(authenticated_client, test_client):
    """Test getting client details."""
    response = authenticated_client.get(f"/api/clients/{test_client.id}")

    # Should return client details or appropriate error
    assert response.status_code in [200, 404]


# ============================================================================
# Invoice API Tests
# ============================================================================


@pytest.mark.api
@pytest.mark.integration
def test_get_invoices_list(authenticated_client):
    """Test getting list of invoices."""
    response = authenticated_client.get("/api/invoices")

    # Should return invoices list or appropriate error
    assert response.status_code in [200, 404]


@pytest.mark.api
@pytest.mark.integration
def test_get_invoice_details(authenticated_client, invoice):
    """Test getting invoice details."""
    response = authenticated_client.get(f"/api/invoices/{invoice.id}")

    # Should return invoice details or appropriate error
    assert response.status_code in [200, 404]


# ============================================================================
# Report API Tests
# ============================================================================


@pytest.mark.api
@pytest.mark.integration
def test_get_time_report(authenticated_client):
    """Test hours-by-day analytics (replaces removed /api/reports/time)."""
    response = authenticated_client.get("/api/analytics/hours-by-day", query_string={"days": 7})

    assert response.status_code == 200
    data = response.get_json()
    assert "labels" in data
    assert "datasets" in data


@pytest.mark.api
@pytest.mark.integration
def test_get_project_report(authenticated_client, project):
    """Test hours-by-project analytics (replaces removed /api/reports/projects/<id>)."""
    response = authenticated_client.get("/api/analytics/hours-by-project", query_string={"days": 7})

    assert response.status_code == 200
    data = response.get_json()
    assert "labels" in data
    assert "datasets" in data


# ============================================================================
# Task API Tests
# ============================================================================


@pytest.mark.api
@pytest.mark.integration
def test_get_tasks_list(authenticated_client):
    """Test getting list of tasks."""
    response = authenticated_client.get("/api/tasks")

    # Should return tasks list or appropriate error (400 is also valid if params are required)
    assert response.status_code in [200, 400, 404]


@pytest.mark.api
@pytest.mark.integration
def test_get_task_details(authenticated_client, task):
    """Test getting task details."""
    response = authenticated_client.get(f"/api/tasks/{task.id}")

    # Should return task details or appropriate error
    assert response.status_code in [200, 404]


@pytest.mark.api
@pytest.mark.integration
def test_get_project_tasks_includes_all_statuses(authenticated_client, project, user, app):
    """Test that /api/projects/<project_id>/tasks returns all tasks (incl. done/cancelled) for time-entry UI."""
    from app import db
    from app.models import Task

    active_task = Task(name="Active Task", project_id=project.id, status="todo", created_by=user.id)
    in_progress_task = Task(name="In Progress Task", project_id=project.id, status="in_progress", created_by=user.id)
    review_task = Task(name="Review Task", project_id=project.id, status="review", created_by=user.id)
    done_task = Task(name="Done Task", project_id=project.id, status="done", created_by=user.id)
    cancelled_task = Task(name="Cancelled Task", project_id=project.id, status="cancelled", created_by=user.id)

    db.session.add_all([active_task, in_progress_task, review_task, done_task, cancelled_task])
    db.session.commit()

    response = authenticated_client.get(f"/api/projects/{project.id}/tasks")

    assert response.status_code == 200
    data = json.loads(response.data)
    assert "tasks" in data
    assert data["success"] is True

    task_names = [t["name"] for t in data["tasks"]]
    for name in (
        "Active Task",
        "In Progress Task",
        "Review Task",
        "Done Task",
        "Cancelled Task",
    ):
        assert name in task_names

    assert len(data["tasks"]) == 5


# ============================================================================
# Settings API Tests
# ============================================================================


@pytest.mark.api
@pytest.mark.integration
def test_get_settings(authenticated_client):
    """Test getting application settings."""
    response = authenticated_client.get("/api/settings")

    # Should return settings or appropriate error
    assert response.status_code in [200, 404]


# ============================================================================
# Analytics API Tests
# ============================================================================


@pytest.mark.api
@pytest.mark.integration
def test_get_dashboard_stats(authenticated_client):
    """Test getting dashboard statistics."""
    response = authenticated_client.get("/api/analytics/dashboard")

    # Should return stats or appropriate error
    assert response.status_code in [200, 404, 500]


# ============================================================================
# Search API Tests
# ============================================================================


@pytest.mark.api
@pytest.mark.integration
def test_search_api(authenticated_client):
    """Test search API endpoint."""
    response = authenticated_client.get("/api/search", query_string={"q": "test"})

    # Should return search results or appropriate error
    assert response.status_code in [200, 400, 404]


# ============================================================================
# Export API Tests
# ============================================================================


@pytest.mark.api
@pytest.mark.integration
def test_export_time_entries(authenticated_client):
    """Test exporting time entries."""
    response = authenticated_client.get(
        "/api/export/time-entries",
        query_string={
            "format": "csv",
            "start_date": (datetime.utcnow() - timedelta(days=7)).strftime("%Y-%m-%d"),
            "end_date": datetime.utcnow().strftime("%Y-%m-%d"),
        },
    )

    # Should return export or appropriate error
    assert response.status_code in [200, 404, 500]
