from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Query
from sqlalchemy.orm import Session
from typing import List, Optional
import os
import uuid
import aiofiles

from ..database import get_db
from ..models.hero_banner import HeroBanner, HeroBannerSettings
from ..schemas.hero_banner import (
    HeroBannerCreate, HeroBannerUpdate, HeroBannerResponse,
    HeroBannerListResponse, HeroBannerLocalizedResponse,
    HeroBannerSettingsUpdate, HeroBannerSettingsResponse,
)
from .auth import get_current_user
from ..models import User
from ..config import get_settings

router = APIRouter(prefix="/hero-banners", tags=["hero-banners"])

settings = get_settings()
ALLOWED_EXTENSIONS = {".jpg", ".jpeg", ".png", ".gif", ".webp"}


def get_localized_field(obj, field: str, lang: str) -> Optional[str]:
    """Get localized field value with fallback to Korean then English"""
    localized = getattr(obj, f"{field}_{lang}", None)
    if localized:
        return localized
    # Fallback to Korean
    ko_value = getattr(obj, f"{field}_ko", None)
    if ko_value:
        return ko_value
    # Fallback to English
    return getattr(obj, f"{field}_en", None)


# ==================== Public Endpoints ====================

@router.get("/", response_model=List[HeroBannerLocalizedResponse])
def get_hero_banners(
    lang: str = Query("ko", regex="^(ko|en|mn)$"),
    db: Session = Depends(get_db)
):
    """활성 히어로 배너 목록 조회 (Public)"""
    banners = db.query(HeroBanner).filter(
        HeroBanner.is_active == True
    ).order_by(HeroBanner.display_order.asc(), HeroBanner.id.desc()).all()

    result = []
    for b in banners:
        result.append(HeroBannerLocalizedResponse(
            id=b.id,
            title=get_localized_field(b, "title", lang),
            subtitle=get_localized_field(b, "subtitle", lang),
            image_url=b.image_url,
            link_url=b.link_url,
            car_id=b.car_id,
        ))

    return result


@router.get("/check-car/{car_id}")
def check_banner_car(car_id: int, db: Session = Depends(get_db)):
    """차량이 Hero Banner에 연결되어 있는지 확인 (Public)

    Banner에 연결된 차량은 샘플로 모든 정보를 무료로 공개합니다.
    """
    banner = db.query(HeroBanner).filter(
        HeroBanner.car_id == car_id,
        HeroBanner.is_active == True
    ).first()

    return {
        "car_id": car_id,
        "is_banner_car": banner is not None,
        "banner_id": banner.id if banner else None
    }


@router.get("/settings", response_model=HeroBannerSettingsResponse)
def get_banner_settings(db: Session = Depends(get_db)):
    """배너 슬라이더 설정 조회 (Public)"""
    settings_obj = db.query(HeroBannerSettings).first()
    if not settings_obj:
        # 기본 설정 생성
        settings_obj = HeroBannerSettings(
            slide_interval=3000,
            animation_type="film-strip",
            image_width=500,
            image_height=300,
            auto_play=True,
        )
        db.add(settings_obj)
        db.commit()
        db.refresh(settings_obj)
    return settings_obj


# ==================== Admin Endpoints ====================

def get_admin_user(current_user: User = Depends(get_current_user)) -> User:
    """관리자 권한 확인 (임시: 모든 로그인 사용자 허용)"""
    # TODO: 실제 관리자 역할 체크 추가
    # if current_user.role != "admin":
    #     raise HTTPException(status_code=403, detail="Admin access required")
    return current_user


@router.get("/admin/list", response_model=List[HeroBannerListResponse])
def admin_get_banners(
    db: Session = Depends(get_db),
    current_user: User = Depends(get_admin_user)
):
    """모든 히어로 배너 조회 (Admin)"""
    banners = db.query(HeroBanner).order_by(
        HeroBanner.display_order.asc(),
        HeroBanner.id.desc()
    ).all()
    return banners


@router.get("/admin/{banner_id}", response_model=HeroBannerResponse)
def admin_get_banner(
    banner_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_admin_user)
):
    """히어로 배너 상세 조회 (Admin)"""
    banner = db.query(HeroBanner).filter(HeroBanner.id == banner_id).first()
    if not banner:
        raise HTTPException(status_code=404, detail="Banner not found")
    return banner


@router.post("/admin", response_model=HeroBannerResponse)
def create_banner(
    banner_data: HeroBannerCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_admin_user)
):
    """히어로 배너 생성 (Admin)"""
    banner = HeroBanner(**banner_data.model_dump())
    db.add(banner)
    db.commit()
    db.refresh(banner)
    return banner


@router.put("/admin/{banner_id}", response_model=HeroBannerResponse)
def update_banner(
    banner_id: int,
    banner_data: HeroBannerUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_admin_user)
):
    """히어로 배너 수정 (Admin)"""
    banner = db.query(HeroBanner).filter(HeroBanner.id == banner_id).first()
    if not banner:
        raise HTTPException(status_code=404, detail="Banner not found")

    update_data = banner_data.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(banner, field, value)

    db.commit()
    db.refresh(banner)
    return banner


@router.delete("/admin/{banner_id}")
def delete_banner(
    banner_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_admin_user)
):
    """히어로 배너 삭제 (Admin)"""
    banner = db.query(HeroBanner).filter(HeroBanner.id == banner_id).first()
    if not banner:
        raise HTTPException(status_code=404, detail="Banner not found")

    # 로컬 이미지 파일 삭제
    if banner.image_url and banner.image_url.startswith("/uploads/"):
        try:
            filepath = os.path.join(settings.UPLOAD_DIR if hasattr(settings, 'UPLOAD_DIR') else "./uploads",
                                   os.path.basename(banner.image_url))
            if os.path.exists(filepath):
                os.remove(filepath)
        except Exception:
            pass

    db.delete(banner)
    db.commit()

    return {"message": "Banner deleted successfully"}


@router.put("/admin/settings", response_model=HeroBannerSettingsResponse)
def update_banner_settings(
    settings_data: HeroBannerSettingsUpdate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_admin_user)
):
    """배너 슬라이더 설정 수정 (Admin)"""
    settings_obj = db.query(HeroBannerSettings).first()
    if not settings_obj:
        settings_obj = HeroBannerSettings()
        db.add(settings_obj)

    update_data = settings_data.model_dump(exclude_unset=True)
    for field, value in update_data.items():
        setattr(settings_obj, field, value)

    db.commit()
    db.refresh(settings_obj)
    return settings_obj


# ==================== Image Upload ====================

@router.post("/admin/upload-image")
async def upload_banner_image(
    file: UploadFile = File(...),
    db: Session = Depends(get_db),
    current_user: User = Depends(get_admin_user)
):
    """배너 이미지 업로드 (Admin)"""
    # 파일 확장자 검증
    ext = os.path.splitext(file.filename)[1].lower()
    if ext not in ALLOWED_EXTENSIONS:
        raise HTTPException(
            status_code=400,
            detail=f"File type not allowed. Allowed: {ALLOWED_EXTENSIONS}"
        )

    # 파일 읽기 및 크기 검증
    contents = await file.read()
    max_size = 10 * 1024 * 1024  # 10MB
    if len(contents) > max_size:
        raise HTTPException(
            status_code=400,
            detail=f"File too large. Max size: {max_size / 1024 / 1024}MB"
        )

    # 업로드 디렉토리 생성
    upload_dir = "./uploads/hero-banners"
    os.makedirs(upload_dir, exist_ok=True)

    # 고유 파일명 생성
    filename = f"hero_{uuid.uuid4()}{ext}"
    filepath = os.path.join(upload_dir, filename)

    # 파일 저장
    async with aiofiles.open(filepath, 'wb') as f:
        await f.write(contents)

    # 상대 URL 반환
    image_url = f"/uploads/hero-banners/{filename}"

    return {
        "message": "Image uploaded successfully",
        "image_url": image_url,
        "filename": filename,
    }
