from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from sqlalchemy import func, and_, desc
from datetime import datetime, timedelta
from typing import List, Optional
from pydantic import BaseModel

from ..database import get_db
from ..models import (
    User, Car, Inquiry, InquiryStatus,
    VehicleRequest, RequestVehicle, PurchasedVehicle,
    DealerApplication, DealerInfo,
    VehicleShare, ShareReward,
    WithdrawalRequest,
    ReferralReward,
    HeroBanner,
    ChargeHistory,
)
from .auth import get_current_admin_user

router = APIRouter(prefix="/dashboard", tags=["Dashboard"])


class DashboardStats(BaseModel):
    total_users: int
    new_users_today: int
    new_users_this_week: int
    total_dealers: int
    pending_dealer_applications: int
    total_cars: int
    total_vehicle_requests: int
    pending_requests: int
    total_purchased_vehicles: int
    total_inquiries: int
    pending_inquiries: int
    total_shares: int
    purchased_shares: int
    total_withdrawals: int
    pending_withdrawals: int
    total_cc_charged: float
    total_withdrawal_amount: float


class RevenueStats(BaseModel):
    total_revenue: float
    revenue_this_month: float
    revenue_last_month: float
    platform_commission: float
    dealer_commission: float


class ChartData(BaseModel):
    labels: List[str]
    values: List[int]


class DailyStats(BaseModel):
    date: str
    users: int
    requests: int
    purchases: int
    revenue: float


class RecentActivity(BaseModel):
    type: str
    title: str
    description: str
    time: str
    icon: str


class TopDealer(BaseModel):
    id: int
    name: str
    dealer_code: str
    total_sales: int
    total_commission: float


@router.get("/stats", response_model=DashboardStats)
def get_dashboard_stats(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    """Get comprehensive dashboard statistics"""
    today = datetime.utcnow().date()
    week_ago = today - timedelta(days=7)

    # User stats
    total_users = db.query(func.count(User.id)).filter(User.is_admin == False).scalar() or 0
    new_users_today = db.query(func.count(User.id)).filter(
        and_(
            User.is_admin == False,
            func.date(User.created_at) == today
        )
    ).scalar() or 0
    new_users_this_week = db.query(func.count(User.id)).filter(
        and_(
            User.is_admin == False,
            func.date(User.created_at) >= week_ago
        )
    ).scalar() or 0

    # Dealer stats
    total_dealers = db.query(func.count(DealerInfo.id)).filter(DealerInfo.is_active == True).scalar() or 0
    pending_dealer_applications = db.query(func.count(DealerApplication.id)).filter(
        DealerApplication.status == "pending"
    ).scalar() or 0

    # Car stats
    total_cars = db.query(func.count(Car.id)).scalar() or 0

    # Vehicle request stats
    total_vehicle_requests = db.query(func.count(VehicleRequest.id)).scalar() or 0
    pending_requests = db.query(func.count(VehicleRequest.id)).filter(
        VehicleRequest.status == "pending"
    ).scalar() or 0

    # Purchased vehicles
    total_purchased_vehicles = db.query(func.count(PurchasedVehicle.id)).scalar() or 0

    # Inquiry stats
    total_inquiries = db.query(func.count(Inquiry.id)).scalar() or 0
    pending_inquiries = db.query(func.count(Inquiry.id)).filter(
        Inquiry.status == InquiryStatus.PENDING
    ).scalar() or 0

    # Share stats
    total_shares = db.query(func.count(VehicleShare.id)).scalar() or 0
    purchased_shares = db.query(func.count(VehicleShare.id)).filter(
        VehicleShare.is_purchased == True
    ).scalar() or 0

    # Withdrawal stats
    total_withdrawals = db.query(func.count(WithdrawalRequest.id)).scalar() or 0
    pending_withdrawals = db.query(func.count(WithdrawalRequest.id)).filter(
        WithdrawalRequest.status == "pending"
    ).scalar() or 0

    # CC stats
    total_cc_charged = db.query(func.coalesce(func.sum(ChargeHistory.amount), 0)).filter(
        ChargeHistory.status == "completed"
    ).scalar() or 0

    total_withdrawal_amount = db.query(func.coalesce(func.sum(WithdrawalRequest.amount), 0)).filter(
        WithdrawalRequest.status == "completed"
    ).scalar() or 0

    return DashboardStats(
        total_users=total_users,
        new_users_today=new_users_today,
        new_users_this_week=new_users_this_week,
        total_dealers=total_dealers,
        pending_dealer_applications=pending_dealer_applications,
        total_cars=total_cars,
        total_vehicle_requests=total_vehicle_requests,
        pending_requests=pending_requests,
        total_purchased_vehicles=total_purchased_vehicles,
        total_inquiries=total_inquiries,
        pending_inquiries=pending_inquiries,
        total_shares=total_shares,
        purchased_shares=purchased_shares,
        total_withdrawals=total_withdrawals,
        pending_withdrawals=pending_withdrawals,
        total_cc_charged=float(total_cc_charged),
        total_withdrawal_amount=float(total_withdrawal_amount),
    )


@router.get("/revenue", response_model=RevenueStats)
def get_revenue_stats(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    """Get revenue statistics"""
    today = datetime.utcnow().date()
    this_month_start = today.replace(day=1)
    last_month_end = this_month_start - timedelta(days=1)
    last_month_start = last_month_end.replace(day=1)

    # Total CC charged as revenue
    total_revenue = db.query(func.coalesce(func.sum(ChargeHistory.amount), 0)).filter(
        ChargeHistory.status == "completed"
    ).scalar() or 0

    revenue_this_month = db.query(func.coalesce(func.sum(ChargeHistory.amount), 0)).filter(
        and_(
            ChargeHistory.status == "completed",
            func.date(ChargeHistory.created_at) >= this_month_start
        )
    ).scalar() or 0

    revenue_last_month = db.query(func.coalesce(func.sum(ChargeHistory.amount), 0)).filter(
        and_(
            ChargeHistory.status == "completed",
            func.date(ChargeHistory.created_at) >= last_month_start,
            func.date(ChargeHistory.created_at) <= last_month_end
        )
    ).scalar() or 0

    # Commission stats from purchased vehicles
    platform_commission = db.query(func.coalesce(func.sum(PurchasedVehicle.platform_commission), 0)).scalar() or 0
    dealer_commission = db.query(func.coalesce(func.sum(PurchasedVehicle.dealer_commission), 0)).scalar() or 0

    return RevenueStats(
        total_revenue=float(total_revenue),
        revenue_this_month=float(revenue_this_month),
        revenue_last_month=float(revenue_last_month),
        platform_commission=float(platform_commission),
        dealer_commission=float(dealer_commission),
    )


@router.get("/chart/users", response_model=ChartData)
def get_user_chart_data(
    days: int = 30,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    """Get user registration chart data for last N days"""
    today = datetime.utcnow().date()

    labels = []
    values = []

    for i in range(days - 1, -1, -1):
        date = today - timedelta(days=i)
        count = db.query(func.count(User.id)).filter(
            and_(
                User.is_admin == False,
                func.date(User.created_at) == date
            )
        ).scalar() or 0

        labels.append(date.strftime("%m/%d"))
        values.append(count)

    return ChartData(labels=labels, values=values)


@router.get("/chart/requests", response_model=ChartData)
def get_request_chart_data(
    days: int = 30,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    """Get vehicle request chart data for last N days"""
    today = datetime.utcnow().date()

    labels = []
    values = []

    for i in range(days - 1, -1, -1):
        date = today - timedelta(days=i)
        count = db.query(func.count(VehicleRequest.id)).filter(
            func.date(VehicleRequest.created_at) == date
        ).scalar() or 0

        labels.append(date.strftime("%m/%d"))
        values.append(count)

    return ChartData(labels=labels, values=values)


@router.get("/chart/revenue", response_model=ChartData)
def get_revenue_chart_data(
    days: int = 30,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    """Get daily revenue chart data for last N days"""
    today = datetime.utcnow().date()

    labels = []
    values = []

    for i in range(days - 1, -1, -1):
        date = today - timedelta(days=i)
        amount = db.query(func.coalesce(func.sum(ChargeHistory.amount), 0)).filter(
            and_(
                ChargeHistory.status == "completed",
                func.date(ChargeHistory.created_at) == date
            )
        ).scalar() or 0

        labels.append(date.strftime("%m/%d"))
        values.append(int(amount))

    return ChartData(labels=labels, values=values)


@router.get("/recent-activities", response_model=List[RecentActivity])
def get_recent_activities(
    limit: int = 10,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    """Get recent activities across the platform"""
    activities = []

    # Recent user registrations
    recent_users = db.query(User).filter(User.is_admin == False).order_by(
        desc(User.created_at)
    ).limit(3).all()

    for user in recent_users:
        activities.append({
            "type": "user",
            "title": "New User Registration",
            "description": f"{user.name or user.email} joined the platform",
            "time": user.created_at.isoformat() if user.created_at else "",
            "icon": "user"
        })

    # Recent vehicle requests
    recent_requests = db.query(VehicleRequest).order_by(
        desc(VehicleRequest.created_at)
    ).limit(3).all()

    for req in recent_requests:
        activities.append({
            "type": "request",
            "title": "Vehicle Request",
            "description": f"Request #{req.id} - {req.status}",
            "time": req.created_at.isoformat() if req.created_at else "",
            "icon": "car"
        })

    # Recent inquiries
    recent_inquiries = db.query(Inquiry).order_by(
        desc(Inquiry.created_at)
    ).limit(3).all()

    for inq in recent_inquiries:
        activities.append({
            "type": "inquiry",
            "title": "New Inquiry",
            "description": f"{inq.subject or 'General inquiry'} - {inq.status}",
            "time": inq.created_at.isoformat() if inq.created_at else "",
            "icon": "message"
        })

    # Recent dealer applications
    recent_applications = db.query(DealerApplication).filter(
        DealerApplication.status == "pending"
    ).order_by(desc(DealerApplication.applied_at)).limit(2).all()

    for app in recent_applications:
        activities.append({
            "type": "dealer",
            "title": "Dealer Application",
            "description": f"{app.real_name} ({app.business_name}) applied",
            "time": app.applied_at.isoformat() if app.applied_at else "",
            "icon": "badge"
        })

    # Recent withdrawals
    recent_withdrawals = db.query(WithdrawalRequest).filter(
        WithdrawalRequest.status == "pending"
    ).order_by(desc(WithdrawalRequest.requested_at)).limit(2).all()

    for wd in recent_withdrawals:
        activities.append({
            "type": "withdrawal",
            "title": "Withdrawal Request",
            "description": f"₩{wd.amount:,.0f} withdrawal requested",
            "time": wd.requested_at.isoformat() if wd.requested_at else "",
            "icon": "wallet"
        })

    # Sort by time
    activities.sort(key=lambda x: x["time"], reverse=True)

    return [RecentActivity(**a) for a in activities[:limit]]


@router.get("/top-dealers", response_model=List[TopDealer])
def get_top_dealers(
    limit: int = 5,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    """Get top performing dealers"""
    # Get dealers with their stats
    dealers = db.query(
        DealerInfo,
        User.name,
        func.count(PurchasedVehicle.id).label("sales_count"),
        func.coalesce(func.sum(PurchasedVehicle.dealer_commission), 0).label("total_commission")
    ).join(
        User, DealerInfo.user_id == User.id
    ).outerjoin(
        PurchasedVehicle, DealerInfo.user_id == PurchasedVehicle.selected_dealer_id
    ).filter(
        DealerInfo.is_active == True
    ).group_by(
        DealerInfo.id, User.name
    ).order_by(
        desc("sales_count")
    ).limit(limit).all()

    return [
        TopDealer(
            id=dealer.DealerInfo.id,
            name=dealer.name or "Unknown",
            dealer_code=dealer.DealerInfo.dealer_code,
            total_sales=dealer.sales_count,
            total_commission=float(dealer.total_commission)
        )
        for dealer in dealers
    ]


@router.get("/pending-actions")
def get_pending_actions(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_admin_user)
):
    """Get counts of pending items requiring admin action"""
    pending_requests = db.query(func.count(VehicleRequest.id)).filter(
        VehicleRequest.status == "pending"
    ).scalar() or 0

    pending_inquiries = db.query(func.count(Inquiry.id)).filter(
        Inquiry.status == InquiryStatus.PENDING
    ).scalar() or 0

    pending_dealer_apps = db.query(func.count(DealerApplication.id)).filter(
        DealerApplication.status == "pending"
    ).scalar() or 0

    pending_withdrawals = db.query(func.count(WithdrawalRequest.id)).filter(
        WithdrawalRequest.status == "pending"
    ).scalar() or 0

    return {
        "pending_requests": pending_requests,
        "pending_inquiries": pending_inquiries,
        "pending_dealer_applications": pending_dealer_apps,
        "pending_withdrawals": pending_withdrawals,
        "total_pending": pending_requests + pending_inquiries + pending_dealer_apps + pending_withdrawals
    }
