"""Tests for flight search functionality."""

from unittest.mock import patch, MagicMock

from flight_search.search import search_flights, Flight, SearchResult


class TestFlight:
    """Tests for Flight dataclass."""

    def test_flight_to_dict(self):
        flight = Flight(
            airline="United",
            departure_time="10:00 AM",
            arrival_time="1:00 PM",
            duration="3 hr",
            stops=0,
            stop_info=None,
            price=199,
            is_best=True,
            arrival_ahead=None,
        )

        result = flight.to_dict()

        assert result["airline"] == "United"
        assert result["price"] == 199
        assert result["is_best"] is True
        assert result["stops"] == 0

    def test_flight_with_stops(self):
        flight = Flight(
            airline="Delta",
            departure_time="8:00 AM",
            arrival_time="5:00 PM",
            duration="9 hr",
            stops=1,
            stop_info="ATL",
            price=299,
            is_best=False,
            arrival_ahead=None,
        )

        assert flight.stops == 1
        assert flight.stop_info == "ATL"

    def test_flight_next_day_arrival(self):
        flight = Flight(
            airline="American",
            departure_time="11:00 PM",
            arrival_time="6:00 AM",
            duration="7 hr",
            stops=0,
            stop_info=None,
            price=350,
            is_best=False,
            arrival_ahead="+1",
        )

        assert flight.arrival_ahead == "+1"


class TestSearchResult:
    """Tests for SearchResult dataclass."""

    def test_search_result_to_dict(self):
        flight = Flight(
            airline="Southwest",
            departure_time="2:00 PM",
            arrival_time="4:30 PM",
            duration="2 hr 30 min",
            stops=0,
            stop_info=None,
            price=150,
            is_best=True,
            arrival_ahead=None,
        )

        result = SearchResult(
            flights=[flight],
            current_price="low",
            origin="DEN",
            destination="LAX",
            date="2025-03-01",
            return_date=None,
        )

        data = result.to_dict()

        assert data["origin"] == "DEN"
        assert data["destination"] == "LAX"
        assert data["current_price"] == "low"
        assert len(data["flights"]) == 1
        assert data["flights"][0]["airline"] == "Southwest"

    def test_round_trip_result(self):
        result = SearchResult(
            flights=[],
            current_price="typical",
            origin="JFK",
            destination="LHR",
            date="2025-06-15",
            return_date="2025-06-22",
        )

        data = result.to_dict()

        assert data["date"] == "2025-06-15"
        assert data["return_date"] == "2025-06-22"


class TestSearchFlights:
    """Tests for search_flights function."""

    @patch("fast_flights.get_flights")
    def test_basic_search(self, mock_get_flights):
        """Test basic one-way search."""
        # Mock flight result
        mock_flight = MagicMock()
        mock_flight.name = "United"
        mock_flight.departure = "10:00 AM"
        mock_flight.arrival = "12:30 PM"
        mock_flight.duration = "2 hr 30 min"
        mock_flight.stops = 0
        mock_flight.price = "$199"
        mock_flight.is_best = True
        mock_flight.arrival_time_ahead = None

        mock_result = MagicMock()
        mock_result.flights = [mock_flight]
        mock_result.current_price = "typical"

        mock_get_flights.return_value = mock_result

        result = search_flights(
            origin="DEN",
            destination="LAX",
            date="2025-03-01",
        )

        assert result.origin == "DEN"
        assert result.destination == "LAX"
        assert len(result.flights) == 1
        assert result.flights[0].airline == "United"
        assert result.flights[0].price == 199

    @patch("fast_flights.get_flights")
    def test_round_trip_search(self, mock_get_flights):
        """Test round trip search."""
        mock_result = MagicMock()
        mock_result.flights = []
        mock_result.current_price = "high"

        mock_get_flights.return_value = mock_result

        search_flights(
            origin="JFK",
            destination="LHR",
            date="2025-06-15",
            return_date="2025-06-22",
        )

        # Verify get_flights was called with round-trip
        call_kwargs = mock_get_flights.call_args[1]
        assert call_kwargs["trip"] == "round-trip"
        assert len(call_kwargs["flight_data"]) == 2

    @patch("fast_flights.get_flights")
    def test_passengers(self, mock_get_flights):
        """Test passenger count handling."""
        mock_result = MagicMock()
        mock_result.flights = []
        mock_result.current_price = None

        mock_get_flights.return_value = mock_result

        search_flights(
            origin="SFO",
            destination="NRT",
            date="2025-04-01",
            adults=2,
            children=1,
        )

        # Just verify the function was called with passengers
        call_kwargs = mock_get_flights.call_args[1]
        assert "passengers" in call_kwargs

    @patch("fast_flights.get_flights")
    def test_seat_class(self, mock_get_flights):
        """Test seat class mapping."""
        mock_result = MagicMock()
        mock_result.flights = []
        mock_result.current_price = None

        mock_get_flights.return_value = mock_result

        search_flights(
            origin="ORD",
            destination="CDG",
            date="2025-05-01",
            seat_class="business",
        )

        call_kwargs = mock_get_flights.call_args[1]
        assert call_kwargs["seat"] == "business"

    @patch("fast_flights.get_flights")
    def test_price_parsing(self, mock_get_flights):
        """Test various price formats."""
        # Test with different price formats
        mock_flight = MagicMock()
        mock_flight.name = "Test"
        mock_flight.departure = "10:00 AM"
        mock_flight.arrival = "12:00 PM"
        mock_flight.duration = "2 hr"
        mock_flight.stops = 0
        mock_flight.is_best = False
        mock_flight.arrival_time_ahead = None
        mock_flight.price = "$1,234"  # With comma

        mock_result = MagicMock()
        mock_result.flights = [mock_flight]
        mock_result.current_price = None

        mock_get_flights.return_value = mock_result

        result = search_flights(
            origin="LAX",
            destination="JFK",
            date="2025-03-01",
        )

        assert result.flights[0].price == 1234

    @patch("fast_flights.get_flights")
    def test_max_results(self, mock_get_flights):
        """Test max results limiting."""
        # Create 10 mock flights
        mock_flights = []
        for i in range(10):
            f = MagicMock()
            f.name = f"Airline {i}"
            f.departure = "10:00 AM"
            f.arrival = "12:00 PM"
            f.duration = "2 hr"
            f.stops = 0
            f.price = 100 + i * 10
            f.is_best = i == 0
            f.arrival_time_ahead = None
            mock_flights.append(f)

        mock_result = MagicMock()
        mock_result.flights = mock_flights
        mock_result.current_price = "typical"

        mock_get_flights.return_value = mock_result

        result = search_flights(
            origin="DEN",
            destination="LAX",
            date="2025-03-01",
            max_results=5,
        )

        assert len(result.flights) == 5
