"""
Analytics API endpoints for TCO (Total Cost of Ownership) dashboard.
"""

import logging
import uuid
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio import AsyncSession

from app.api import deps
from app.schemas.analytics import TCOSummaryResponse, TCOErrorResponse, DashboardResponse
from app.services.analytics_service import TCOAnalytics
from app.models import Vehicle
from app.models.marketplace.organization import OrganizationMember

logger = logging.getLogger(__name__)

router = APIRouter()


async def verify_vehicle_access(
    vehicle_id: uuid.UUID,
    db: AsyncSession,
    current_user
) -> Vehicle:
    """
    Verify that the current user has access to the vehicle (either as owner or via organization).
    Raises HTTP 404 if vehicle not found, 403 if access denied.
    """
    # 1. Check if vehicle exists
    vehicle = await db.get(Vehicle, vehicle_id)
    if not vehicle:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"Vehicle with ID {vehicle_id} not found."
        )
    
    # 2. Check if user is superadmin (global access)
    if current_user.role == "superadmin":
        return vehicle
    
    # 3. Check if user is member of the vehicle's organization
    #    (Vehicle.organization_id matches user's organization membership)
    # First, get user's organization memberships
    from sqlalchemy import select
    stmt = select(OrganizationMember).where(
        OrganizationMember.user_id == current_user.id,
        OrganizationMember.organization_id == vehicle.organization_id
    )
    result = await db.execute(stmt)
    membership = result.scalar_one_or_none()
    
    if membership:
        return vehicle
    
    # 4. If user is not a member, check if they have fleet manager role with cross-org access
    # (This could be extended based on RBAC)
    # For now, deny access
    raise HTTPException(
        status_code=status.HTTP_403_FORBIDDEN,
        detail="You do not have permission to access this vehicle's analytics."
    )


@router.get(
    "/{vehicle_id}/summary",
    response_model=TCOSummaryResponse,
    responses={
        404: {"model": TCOErrorResponse, "description": "Vehicle not found"},
        403: {"model": TCOErrorResponse, "description": "Access denied"},
        500: {"model": TCOErrorResponse, "description": "Internal server error"},
    },
    summary="Get TCO summary for a vehicle",
    description="Returns Total Cost of Ownership analytics for a specific vehicle, "
                "including user-specific costs, lifetime costs, and benchmark comparisons."
)
async def get_tco_summary(
    vehicle_id: uuid.UUID,
    db: AsyncSession = Depends(deps.get_db),
    current_user = Depends(deps.get_current_active_user),
):
    """
    Retrieve TCO analytics for a vehicle.
    
    Steps:
    1. Verify user has access to the vehicle.
    2. Use TCOAnalytics service to compute user TCO, lifetime TCO, and benchmark.
    3. Transform results into the response schema.
    """
    try:
        # Access verification
        vehicle = await verify_vehicle_access(vehicle_id, db, current_user)
        
        analytics = TCOAnalytics()
        
        # 1. User TCO (current user's organization)
        user_tco_result = await analytics.get_user_tco(
            db=db,
            organization_id=current_user.organization_id or vehicle.organization_id,
            currency_target="HUF",
            include_categories=None,  # all categories
        )
        
        # 2. Lifetime TCO (across all owners, anonymized)
        lifetime_tco_result = await analytics.get_vehicle_lifetime_tco(
            db=db,
            vehicle_model_id=vehicle.vehicle_model_id,
            currency_target="HUF",
            anonymize=True,
        )
        
        # 3. Benchmark TCO (global benchmark for similar vehicles)
        benchmark_result = await analytics.get_global_benchmark(
            db=db,
            vehicle_model_id=vehicle.vehicle_model_id,
            currency_target="HUF",
        )
        
        # Transform results into schema objects
        # Note: This is a simplified transformation; you may need to adapt based on actual service output.
        user_tco_list = []
        if "by_category" in user_tco_result:
            for cat_code, cat_data in user_tco_result["by_category"].items():
                # Calculate percentage
                total = user_tco_result.get("total_amount", 0)
                percentage = (cat_data["total"] / total * 100) if total > 0 else 0
                user_tco_list.append({
                    "category_id": 0,  # TODO: map from category code to ID
                    "category_code": cat_code,
                    "category_name": cat_data.get("name", cat_code),
                    "amount": cat_data["total"],
                    "currency": user_tco_result.get("currency", "HUF"),
                    "amount_huf": cat_data["total"],  # already in HUF
                    "percentage": round(percentage, 2),
                })
        
        lifetime_tco_list = []
        if "by_category" in lifetime_tco_result:
            for cat_code, cat_data in lifetime_tco_result["by_category"].items():
                total = lifetime_tco_result.get("total_lifetime_cost", 0)
                percentage = (cat_data["total"] / total * 100) if total > 0 else 0
                lifetime_tco_list.append({
                    "category_id": 0,
                    "category_code": cat_code,
                    "category_name": cat_data.get("name", cat_code),
                    "amount": cat_data["total"],
                    "currency": lifetime_tco_result.get("currency", "HUF"),
                    "amount_huf": cat_data["total"],
                    "percentage": round(percentage, 2),
                })
        
        benchmark_tco_list = []
        if "by_category" in benchmark_result:
            for cat_code, cat_data in benchmark_result["by_category"].items():
                total = benchmark_result.get("total_cost_sum", 0)
                percentage = (cat_data["average"] / total * 100) if total > 0 else 0
                benchmark_tco_list.append({
                    "category_id": 0,
                    "category_code": cat_code,
                    "category_name": cat_data.get("name", cat_code),
                    "amount": cat_data["average"],
                    "currency": benchmark_result.get("currency", "HUF"),
                    "amount_huf": cat_data["average"],
                    "percentage": round(percentage, 2),
                })
        
        # Calculate cost per km if odometer data available
        cost_per_km = None
        if vehicle.odometer and vehicle.odometer > 0:
            total_cost = user_tco_result.get("total_amount", 0)
            cost_per_km = total_cost / vehicle.odometer
        
        stats = {
            "total_cost": user_tco_result.get("total_amount", 0),
            "cost_per_km": cost_per_km,
            "total_transactions": user_tco_result.get("total_transactions", 0),
            "date_range": user_tco_result.get("date_range"),
        }
        
        return TCOSummaryResponse(
            vehicle_id=vehicle_id,
            user_tco=user_tco_list,
            lifetime_tco=lifetime_tco_list,
            benchmark_tco=benchmark_tco_list,
            stats=stats,
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.exception(f"Unexpected error in TCO summary for vehicle {vehicle_id}: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Internal server error: {str(e)}"
        )


@router.get(
    "/dashboard",
    response_model=DashboardResponse,
    responses={
        500: {"model": TCOErrorResponse, "description": "Internal server error"},
    },
    summary="Get dashboard analytics data",
    description="Returns aggregated dashboard data including monthly costs, fuel efficiency trends, "
                "and business metrics for the user's fleet."
)
async def get_dashboard_analytics(
    db: AsyncSession = Depends(deps.get_db),
    current_user = Depends(deps.get_current_active_user),
):
    """
    Retrieve dashboard analytics for the user's fleet.
    
    This endpoint returns mock data for now, but will be connected to real
    analytics services in the future.
    """
    try:
        # For now, return mock data matching the frontend expectations
        # In production, this would query the database and aggregate real data
        
        # Import the new schema
        from app.schemas.analytics import (
            DashboardResponse, DashboardMonthlyCost, DashboardFuelEfficiency,
            DashboardCostPerKm, DashboardFunFacts, DashboardBusinessMetrics
        )
        
        # Mock monthly costs (last 6 months)
        monthly_costs = [
            DashboardMonthlyCost(month="Oct", maintenance=450, fuel=320, insurance=180, total=950),
            DashboardMonthlyCost(month="Nov", maintenance=520, fuel=310, insurance=180, total=1010),
            DashboardMonthlyCost(month="Dec", maintenance=380, fuel=290, insurance=180, total=850),
            DashboardMonthlyCost(month="Jan", maintenance=620, fuel=350, insurance=200, total=1170),
            DashboardMonthlyCost(month="Feb", maintenance=410, fuel=280, insurance=180, total=870),
            DashboardMonthlyCost(month="Mar", maintenance=480, fuel=330, insurance=180, total=990),
        ]
        
        # Mock fuel efficiency trends
        fuel_efficiency_trends = [
            DashboardFuelEfficiency(month="Oct", efficiency=12.5),
            DashboardFuelEfficiency(month="Nov", efficiency=12.8),
            DashboardFuelEfficiency(month="Dec", efficiency=13.2),
            DashboardFuelEfficiency(month="Jan", efficiency=12.9),
            DashboardFuelEfficiency(month="Feb", efficiency=13.5),
            DashboardFuelEfficiency(month="Mar", efficiency=13.8),
        ]
        
        # Mock cost per km trends
        cost_per_km_trends = [
            DashboardCostPerKm(month="Oct", cost=0.42),
            DashboardCostPerKm(month="Nov", cost=0.45),
            DashboardCostPerKm(month="Dec", cost=0.38),
            DashboardCostPerKm(month="Jan", cost=0.51),
            DashboardCostPerKm(month="Feb", cost=0.39),
            DashboardCostPerKm(month="Mar", cost=0.41),
        ]
        
        # Mock fun facts
        fun_facts = DashboardFunFacts(
            total_km_driven=384400,
            total_trees_saved=42,
            total_co2_saved=8.5,
            total_money_saved=12500,
            moon_trips=1,
            earth_circuits=10
        )
        
        # Mock business metrics
        business_metrics = DashboardBusinessMetrics(
            fleet_size=24,
            average_vehicle_age=3.2,
            total_monthly_cost=23500,
            average_cost_per_km=0.43,
            utilization_rate=78,
            downtime_hours=42
        )
        
        return DashboardResponse(
            monthly_costs=monthly_costs,
            fuel_efficiency_trends=fuel_efficiency_trends,
            cost_per_km_trends=cost_per_km_trends,
            fun_facts=fun_facts,
            business_metrics=business_metrics
        )
        
    except Exception as e:
        logger.exception(f"Unexpected error in dashboard analytics: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Internal server error: {str(e)}"
        )