"""Price comparison service: search comparable listings and calculate average price.""" from __future__ import annotations import logging import random import uuid from typing import Any from sqlalchemy.ext.asyncio import AsyncSession from app.models.vehicle import Vehicle from app.schemas.retouch import ComparableListing, PriceCompareResponse from app.services.vehicle_service import get_vehicle_by_id logger = logging.getLogger(__name__) def _generate_mock_listings(vehicle: Vehicle) -> list[ComparableListing]: """Generate mock mobile.de comparable listings based on vehicle data. In production, this would call the mobile.de Search API. For now, we generate realistic mock data based on the vehicle's make, model, year, and price. """ listings: list[ComparableListing] = [] base_price = float(vehicle.price) if vehicle.price else 25000.0 # Generate 3-7 comparable listings with price variation num_listings = random.randint(3, 7) for i in range(num_listings): # Vary price by +/- 15% price_variation = random.uniform(-0.15, 0.15) listing_price = round(base_price * (1 + price_variation), 2) # Vary mileage if vehicle has mileage base_mileage = vehicle.mileage_km or 100000 mileage_variation = random.randint(-20000, 20000) listing_mileage = max(0, base_mileage + mileage_variation) locations = ["Berlin", "Hamburg", "München", "Köln", "Frankfurt", "Stuttgart"] listing = ComparableListing( title=f"{vehicle.make} {vehicle.model} {vehicle.year or ''}".strip(), make=vehicle.make, model=vehicle.model, year=vehicle.year, price=listing_price, mileage_km=listing_mileage, location=random.choice(locations), url=f"https://suchen.mobile.de/fahrzeuge/details.html?id={random.randint(1000000, 9999999)}", source="mobile.de", ) listings.append(listing) return listings async def compare_prices( db: AsyncSession, vehicle_id: uuid.UUID, ) -> PriceCompareResponse: """Compare prices for a vehicle by searching comparable listings. Args: db: Async database session vehicle_id: UUID of the vehicle to compare Returns: PriceCompareResponse with comparable listings and average price. If vehicle not found, raises ValueError. If no comparable listings found, returns empty list with null average. """ vehicle = await get_vehicle_by_id(db, vehicle_id) if vehicle is None: raise ValueError(f"Vehicle {vehicle_id} not found") # Search for comparable listings # In production: call mobile.de Search API with make, model, year filters # For now: generate mock listings listings = _generate_mock_listings(vehicle) # Calculate average price if listings: average_price = round(sum(l.price for l in listings) / len(listings), 2) else: average_price = None return PriceCompareResponse( vehicle_id=vehicle_id, comparable_listings=listings, average_price=average_price, listing_count=len(listings), )