from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session, joinedload
from typing import Optional, List
from ..database import get_db
from ..models import Car, CarMaker, CarModel, CarImage, CarOption
from ..schemas import (
    CarCreate, CarUpdate, CarResponse, CarListResponse,
    CarMakerCreate, CarMakerResponse,
    CarModelCreate, CarModelResponse,
)

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


def car_to_response(car: Car) -> dict:
    """Convert Car model to response dict with computed final prices"""
    return {
        "id": car.id,
        "source": car.source,
        "source_id": car.source_id,
        "car_name": car.car_name,
        "year": car.year,
        "month": car.month,
        "mileage": car.mileage,
        "price_krw": car.price_krw,
        "margin_krw": car.margin_krw or 0,
        "margin_mn": car.margin_mn or 0,
        "final_price_krw": (car.price_krw or 0) + (car.margin_krw or 0),
        "final_price_mn": (car.price_krw or 0) + (car.margin_mn or 0),
        "price_usd": car.price_usd,
        "is_displayed": car.is_displayed or False,
        "fuel": car.fuel,
        "transmission": car.transmission,
        "color": car.color,
        "displacement": car.displacement,
        "car_number": car.car_number,
        "seize_count": car.seize_count or 0,
        "collateral_count": car.collateral_count or 0,
        "check_num": car.check_num,
        "dealer_name": car.dealer_name,
        "dealer_description": car.dealer_description,
        "status": car.status,
        "created_at": car.created_at,
        "updated_at": car.updated_at,
        "maker": car.maker,
        "model": car.model,
        "images": car.images,
        "specification": car.specification,
    }


@router.get("", response_model=CarListResponse)
def get_cars(
    page: int = Query(1, ge=1),
    page_size: int = Query(20, ge=1, le=100),
    maker_id: Optional[int] = None,
    model_id: Optional[int] = None,
    year_min: Optional[int] = None,
    year_max: Optional[int] = None,
    price_min: Optional[int] = None,
    price_max: Optional[int] = None,
    mileage_max: Optional[int] = None,
    fuel: Optional[str] = None,
    status: Optional[str] = None,
    is_displayed: Optional[bool] = None,
    admin: bool = Query(False, description="Admin mode - show all cars"),
    db: Session = Depends(get_db),
):
    """차량 목록 조회"""
    # Base query for filtering (without eager loading for count)
    base_query = db.query(Car)

    # For non-admin (user-facing), only show displayed cars
    if not admin:
        base_query = base_query.filter(Car.is_displayed == True)

    # status 필터 (None이면 전체 조회)
    if status:
        base_query = base_query.filter(Car.status == status)

    # is_displayed 필터 (admin mode에서만 의미있음)
    if is_displayed is not None and admin:
        base_query = base_query.filter(Car.is_displayed == is_displayed)

    if maker_id:
        base_query = base_query.filter(Car.maker_id == maker_id)
    if model_id:
        base_query = base_query.filter(Car.model_id == model_id)
    if year_min:
        base_query = base_query.filter(Car.year >= year_min)
    if year_max:
        base_query = base_query.filter(Car.year <= year_max)
    if price_min:
        base_query = base_query.filter(Car.price_krw >= price_min)
    if price_max:
        base_query = base_query.filter(Car.price_krw <= price_max)
    if mileage_max:
        base_query = base_query.filter(Car.mileage <= mileage_max)
    if fuel:
        base_query = base_query.filter(Car.fuel == fuel)

    total = base_query.count()

    # Add eager loading for actual data fetch
    cars = base_query.options(
        joinedload(Car.maker),
        joinedload(Car.model),
        joinedload(Car.images)
    ).order_by(Car.created_at.desc()).offset((page - 1) * page_size).limit(page_size).all()

    # Convert to response with computed fields
    cars_response = [car_to_response(car) for car in cars]

    return CarListResponse(
        total=total,
        page=page,
        page_size=page_size,
        cars=cars_response
    )


@router.get("/{car_id}", response_model=CarResponse)
def get_car(car_id: int, admin: bool = Query(False), db: Session = Depends(get_db)):
    """차량 상세 조회"""
    car = db.query(Car).options(
        joinedload(Car.maker),
        joinedload(Car.model),
        joinedload(Car.images),
        joinedload(Car.specification)
    ).filter(Car.id == car_id).first()
    if not car:
        raise HTTPException(status_code=404, detail="Car not found")
    # Non-admin can only see displayed cars
    if not admin and not car.is_displayed:
        raise HTTPException(status_code=404, detail="Car not found")
    return car_to_response(car)


@router.post("", response_model=CarResponse)
def create_car(car_data: CarCreate, db: Session = Depends(get_db)):
    """차량 등록 (Agent용)"""
    # Check if car already exists
    existing = db.query(Car).filter(
        Car.source == car_data.source,
        Car.source_id == car_data.source_id
    ).first()

    if existing:
        raise HTTPException(status_code=400, detail="Car already exists")

    # Get maker and model IDs
    maker_id = None
    model_id = None

    if car_data.maker_code:
        maker = db.query(CarMaker).filter(CarMaker.code == car_data.maker_code).first()
        if maker:
            maker_id = maker.id

    if car_data.model_code and maker_id:
        model = db.query(CarModel).filter(
            CarModel.code == car_data.model_code,
            CarModel.maker_id == maker_id
        ).first()
        if model:
            model_id = model.id

    # Create car
    car = Car(
        source=car_data.source,
        source_id=car_data.source_id,
        source_key=car_data.source_key,
        maker_id=maker_id,
        model_id=model_id,
        car_name=car_data.car_name,
        year=car_data.year,
        month=car_data.month,
        mileage=car_data.mileage,
        price_krw=car_data.price_krw,
        price_usd=car_data.price_usd,
        fuel=car_data.fuel,
        transmission=car_data.transmission,
        color=car_data.color,
        displacement=car_data.displacement,
        car_number=car_data.car_number,
        seize_count=car_data.seize_count,
        collateral_count=car_data.collateral_count,
        check_num=car_data.check_num,
        dealer_name=car_data.dealer_name,
        dealer_phone=car_data.dealer_phone,
        shop_name=car_data.shop_name,
        memo=car_data.memo,
    )
    db.add(car)
    db.flush()

    # Add images
    for i, img in enumerate(car_data.images):
        car_image = CarImage(
            car_id=car.id,
            url=img.url,
            local_path=img.local_path,
            is_main=(i == 0),
            sort_order=i
        )
        db.add(car_image)

    # Add options
    for opt in car_data.options:
        car_option = CarOption(car_id=car.id, option_name=opt)
        db.add(car_option)

    db.commit()
    db.refresh(car)
    return car


@router.put("/{car_id}", response_model=CarResponse)
def update_car(car_id: int, car_data: CarUpdate, db: Session = Depends(get_db)):
    """차량 정보 수정"""
    car = db.query(Car).options(
        joinedload(Car.maker),
        joinedload(Car.model),
        joinedload(Car.images),
        joinedload(Car.specification)
    ).filter(Car.id == car_id).first()
    if not car:
        raise HTTPException(status_code=404, detail="Car not found")

    for key, value in car_data.dict(exclude_unset=True).items():
        setattr(car, key, value)

    db.commit()
    db.refresh(car)
    return car_to_response(car)


@router.delete("/{car_id}")
def delete_car(car_id: int, db: Session = Depends(get_db)):
    """차량 삭제 (관련 데이터 포함)"""
    print(f"[DELETE] Deleting car {car_id}")
    car = db.query(Car).filter(Car.id == car_id).first()
    if not car:
        print(f"[DELETE] Car {car_id} not found")
        raise HTTPException(status_code=404, detail="Car not found")

    try:
        # 관련 테이블 데이터 삭제
        from ..models.car import CarImage, CarOption
        from ..models.performance_check import CarPerformanceCheck
        from ..models.car_specification import CarSpecification
        from ..models.hero_banner import HeroBanner
        from ..models.user import CarView, PerformanceCheckView
        from sqlalchemy import text

        # 이미지 삭제
        img_count = db.query(CarImage).filter(CarImage.car_id == car_id).delete(synchronize_session=False)
        print(f"[DELETE] Deleted {img_count} images")
        # 옵션 삭제
        opt_count = db.query(CarOption).filter(CarOption.car_id == car_id).delete(synchronize_session=False)
        print(f"[DELETE] Deleted {opt_count} options")
        # 성능점검 삭제
        pc_count = db.query(CarPerformanceCheck).filter(CarPerformanceCheck.car_id == car_id).delete(synchronize_session=False)
        print(f"[DELETE] Deleted {pc_count} performance checks")
        # 사양 삭제
        spec_count = db.query(CarSpecification).filter(CarSpecification.car_id == car_id).delete(synchronize_session=False)
        print(f"[DELETE] Deleted {spec_count} specifications")
        # 차량 조회 기록 삭제
        cv_count = db.query(CarView).filter(CarView.car_id == car_id).delete(synchronize_session=False)
        print(f"[DELETE] Deleted {cv_count} car views")
        # 성능점검 조회 기록 삭제
        pcv_count = db.query(PerformanceCheckView).filter(PerformanceCheckView.car_id == car_id).delete(synchronize_session=False)
        print(f"[DELETE] Deleted {pcv_count} performance check views")
        # 문의 기록에서 car_id 제거 (raw SQL로 실행하여 모델 스키마 검증 방지)
        result = db.execute(text("UPDATE inquiries SET car_id = NULL WHERE car_id = :car_id"), {"car_id": car_id})
        inq_count = result.rowcount
        print(f"[DELETE] Unlinked {inq_count} inquiries")
        # 배너에서 car_id 제거 (배너는 삭제하지 않고 연결만 해제)
        banner_count = db.query(HeroBanner).filter(HeroBanner.car_id == car_id).update({"car_id": None}, synchronize_session=False)
        print(f"[DELETE] Unlinked {banner_count} banners")

        # 차량 삭제
        db.delete(car)
        db.commit()
        print(f"[DELETE] Car {car_id} deleted successfully")
        return {"message": "Car deleted"}
    except Exception as e:
        db.rollback()
        import traceback
        error_trace = traceback.format_exc()
        print(f"[DELETE] Error deleting car {car_id}: {e}\n{error_trace}")
        raise HTTPException(status_code=500, detail=f"Delete failed: {str(e)}")


# Makers
@router.get("/makers/", response_model=List[CarMakerResponse])
def get_makers(db: Session = Depends(get_db)):
    """제조사 목록 조회"""
    return db.query(CarMaker).all()


@router.post("/makers/", response_model=CarMakerResponse)
def create_maker(maker_data: CarMakerCreate, db: Session = Depends(get_db)):
    """제조사 등록"""
    existing = db.query(CarMaker).filter(CarMaker.code == maker_data.code).first()
    if existing:
        return existing

    maker = CarMaker(**maker_data.dict())
    db.add(maker)
    db.commit()
    db.refresh(maker)
    return maker


# Models
@router.get("/models/", response_model=List[CarModelResponse])
def get_models(maker_id: Optional[int] = None, db: Session = Depends(get_db)):
    """모델 목록 조회"""
    query = db.query(CarModel)
    if maker_id:
        query = query.filter(CarModel.maker_id == maker_id)
    return query.all()


@router.post("/models/", response_model=CarModelResponse)
def create_model(model_data: CarModelCreate, db: Session = Depends(get_db)):
    """모델 등록"""
    existing = db.query(CarModel).filter(
        CarModel.code == model_data.code,
        CarModel.maker_id == model_data.maker_id
    ).first()
    if existing:
        return existing

    model = CarModel(**model_data.dict())
    db.add(model)
    db.commit()
    db.refresh(model)
    return model
