"""Collection of tests to ensure correct implementation and track progress."""
import os
import time
import yaml
from fastapi.testclient import TestClient
import pytest

from .test_utils import load_trip_landmarks, log_trip_details
from ..supabase.supabase import SupabaseClient
from ..structs.preferences import Preferences, Preference
from ..constants import PARAMETERS_DIR
from ..main import app


# Create a supabase client
supabase = SupabaseClient()


@pytest.fixture(scope="module")
def client():
    """Client used to call the app."""
    return TestClient(app)


@pytest.mark.parametrize(
    "sightseeing, shopping, nature, max_time_minute, start_coords, end_coords",
    [
        # Edge cases
        (0, 0, 5, 240, [45.7576485, 4.8330241], None),                  # Lyon, Bellecour - test shopping only
        
        # Realistic
        (5, 0, 0, 20, [48.0845881, 7.2804050], None),                   # Turckheim
        (5, 5, 5, 120, [45.7576485, 4.8330241], None),                  # Lyon, Bellecour
        (5, 2, 5, 240, [50.9423526, 6.9577780], None),                  # Cologne, centre
        (3, 5, 0, 180, [48.5846589226, 7.74078715721], None),           # Strasbourg, centre
        (2, 4, 5, 180, [47.377884227, 8.5395114066], None),             # Zurich, centre
        (5, 0, 5, 200, [48.85468881798671, 2.3423925755998374], None),  # Paris, centre
        (5, 5, 5, 600, [40.72592726802, -73.9920434795], None),         # New York, Lower Manhattan
    ]
)
def test_trip(client, request, sightseeing, shopping, nature, max_time_minute, start_coords, end_coords):

    start_time = time.time()  # Start timer

    prefs = Preferences(
        sightseeing=Preference(type='sightseeing', score=sightseeing),
        shopping=Preference(type='shopping', score=shopping),
        nature=Preference(type='nature', score=nature),
        max_time_minute=max_time_minute,
        detour_tolerance_minute=0,
    )
    start = start_coords
    end = end_coords

    # Step 1: request the list of landmarks in the vicinty of the starting point
    response = client.post(
        "/get/landmarks",
        json={
            "preferences": prefs.model_dump(),
            "start": start_coords,
            "end": end_coords,
            }
        )

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

    # Step 2: Feed the landmarks to the optimizer to compute the trip
    response = client.post(
        "/optimize/trip",
        json={
            "user_id": supabase.SUPABASE_TEST_USER_ID,
            "preferences": prefs.model_dump(),
            "landmarks": landmarks,
            "start": start,
            "end": end,
            }
        )
    assert response.status_code == 200
    
    # Increment the user balance again
    supabase.increment_credit_balance(
        supabase.SUPABASE_TEST_USER_ID,
        amount=1
    )

    # Parse the response
    result = response.json()
    # print(result)
    landmarks = load_trip_landmarks(client, result['first_landmark_uuid'])

    # Get computation time
    comp_time = time.time() - start_time

    # Add details to report
    log_trip_details(request, landmarks, result['total_time'], prefs.max_time_minute)

    # checks :
    assert comp_time < 30, f"Computation time exceeded 30 seconds: {comp_time:.2f} seconds"
    assert prefs.max_time_minute*0.8 < result['total_time'], f"Trip too short: {result['total_time']} instead of {prefs.max_time_minute}"
    assert prefs.max_time_minute*1.2 > result['total_time'], f"Trip too long: {result['total_time']} instead of {prefs.max_time_minute}"
