#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
数据查询API路由
支持景区、产品、风格、受众等基础数据的查询
"""

import logging
from typing import List, Dict, Any, Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel, Field

from api.services.database_service import DatabaseService
from api.dependencies import get_database_service

logger = logging.getLogger(__name__)

router = APIRouter(
    prefix="/data",
    tags=["data"],
    responses={404: {"description": "Not found"}},
)


class ScenicSpotResponse(BaseModel):
    """景区响应模型"""
    id: int = Field(..., description="景区ID")
    name: str = Field(..., description="景区名称")
    address: Optional[str] = Field(None, description="地址")
    description: Optional[str] = Field(None, description="描述")
    advantage: Optional[str] = Field(None, description="优势")
    highlight: Optional[str] = Field(None, description="亮点")
    isPublic: bool = Field(..., description="是否公开")
    userId: int = Field(..., description="用户ID")


class ProductResponse(BaseModel):
    """产品响应模型"""
    id: int = Field(..., description="产品ID")
    name: str = Field(..., description="产品名称")
    originPrice: Optional[float] = Field(None, description="原价")
    realPrice: Optional[float] = Field(None, description="实际价格")
    packageInfo: Optional[str] = Field(None, description="套票信息")
    description: Optional[str] = Field(None, description="描述")
    advantage: Optional[str] = Field(None, description="优势")
    highlight: Optional[str] = Field(None, description="亮点")
    isPublic: bool = Field(..., description="是否公开")
    userId: int = Field(..., description="用户ID")


class StyleResponse(BaseModel):
    """风格响应模型"""
    id: int = Field(..., description="风格ID")
    styleName: str = Field(..., description="风格名称")
    description: Optional[str] = Field(None, description="描述")


class AudienceResponse(BaseModel):
    """受众响应模型"""
    id: int = Field(..., description="受众ID")
    audienceName: str = Field(..., description="受众名称")
    description: Optional[str] = Field(None, description="描述")


@router.get("/scenic-spots", response_model=List[ScenicSpotResponse], summary="获取景区列表")
async def get_scenic_spots(
    user_id: Optional[int] = Query(None, description="用户ID，如果提供则只返回该用户的景区"),
    is_public: Optional[bool] = Query(None, description="是否公开，如果提供则过滤公开/私有景区"),
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    获取景区列表
    
    - **user_id**: 用户ID，如果提供则只返回该用户的景区
    - **is_public**: 是否公开，如果提供则过滤公开/私有景区
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        spots = db_service.list_all_scenic_spots(user_id=user_id, is_public=is_public)
        return [ScenicSpotResponse(**spot) for spot in spots]
    except Exception as e:
        logger.error(f"获取景区列表失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"获取景区列表失败: {str(e)}")


@router.get("/scenic-spots/{spot_id}", response_model=ScenicSpotResponse, summary="根据ID获取景区信息")
async def get_scenic_spot_by_id(
    spot_id: int,
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    根据ID获取景区信息
    
    - **spot_id**: 景区ID
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        spot = db_service.get_scenic_spot_by_id(spot_id)
        if not spot:
            raise HTTPException(status_code=404, detail=f"未找到ID为{spot_id}的景区")
        
        return ScenicSpotResponse(**spot)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取景区信息失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"获取景区信息失败: {str(e)}")


@router.get("/products", response_model=List[ProductResponse], summary="获取产品列表")
async def get_products(
    user_id: Optional[int] = Query(None, description="用户ID，如果提供则只返回该用户的产品"),
    is_public: Optional[bool] = Query(None, description="是否公开，如果提供则过滤公开/私有产品"),
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    获取产品列表
    
    - **user_id**: 用户ID，如果提供则只返回该用户的产品
    - **is_public**: 是否公开，如果提供则过滤公开/私有产品
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        products = db_service.list_all_products(user_id=user_id, is_public=is_public)
        return [ProductResponse(**product) for product in products]
    except Exception as e:
        logger.error(f"获取产品列表失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"获取产品列表失败: {str(e)}")


@router.get("/products/{product_id}", response_model=ProductResponse, summary="根据ID获取产品信息")
async def get_product_by_id(
    product_id: int,
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    根据ID获取产品信息
    
    - **product_id**: 产品ID
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        product = db_service.get_product_by_id(product_id)
        if not product:
            raise HTTPException(status_code=404, detail=f"未找到ID为{product_id}的产品")
        
        return ProductResponse(**product)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取产品信息失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"获取产品信息失败: {str(e)}")


@router.get("/styles", response_model=List[StyleResponse], summary="获取风格列表")
async def get_styles(
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    获取所有风格列表
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        styles = db_service.list_all_styles()
        return [StyleResponse(**style) for style in styles]
    except Exception as e:
        logger.error(f"获取风格列表失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"获取风格列表失败: {str(e)}")


@router.get("/styles/{style_id}", response_model=StyleResponse, summary="根据ID获取风格信息")
async def get_style_by_id(
    style_id: int,
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    根据ID获取风格信息
    
    - **style_id**: 风格ID
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        style = db_service.get_style_by_id(style_id)
        if not style:
            raise HTTPException(status_code=404, detail=f"未找到ID为{style_id}的风格")
        
        return StyleResponse(**style)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取风格信息失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"获取风格信息失败: {str(e)}")


@router.get("/audiences", response_model=List[AudienceResponse], summary="获取受众列表")
async def get_audiences(
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    获取所有受众列表
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        audiences = db_service.list_all_audiences()
        return [AudienceResponse(**audience) for audience in audiences]
    except Exception as e:
        logger.error(f"获取受众列表失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"获取受众列表失败: {str(e)}")


@router.get("/audiences/{audience_id}", response_model=AudienceResponse, summary="根据ID获取受众信息")
async def get_audience_by_id(
    audience_id: int,
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    根据ID获取受众信息
    
    - **audience_id**: 受众ID
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        audience = db_service.get_audience_by_id(audience_id)
        if not audience:
            raise HTTPException(status_code=404, detail=f"未找到ID为{audience_id}的受众")
        
        return AudienceResponse(**audience)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取受众信息失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"获取受众信息失败: {str(e)}")


@router.post("/scenic-spots/batch", response_model=List[ScenicSpotResponse], summary="批量获取景区信息")
async def get_scenic_spots_batch(
    spot_ids: List[int],
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    批量获取景区信息
    
    - **spot_ids**: 景区ID列表
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        spots = db_service.get_scenic_spots_by_ids(spot_ids)
        return [ScenicSpotResponse(**spot) for spot in spots]
    except Exception as e:
        logger.error(f"批量获取景区信息失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"批量获取景区信息失败: {str(e)}")


@router.post("/products/batch", response_model=List[ProductResponse], summary="批量获取产品信息")
async def get_products_batch(
    productIds: List[int],
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    批量获取产品信息
    
    - **productIds**: 产品ID列表
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        products = db_service.get_products_by_ids(productIds)
        return [ProductResponse(**product) for product in products]
    except Exception as e:
        logger.error(f"批量获取产品信息失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"批量获取产品信息失败: {str(e)}")


@router.post("/styles/batch", response_model=List[StyleResponse], summary="批量获取风格信息")
async def get_styles_batch(
    styleIds: List[int],
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    批量获取风格信息
    
    - **styleIds**: 风格ID列表
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        styles = db_service.get_styles_by_ids(styleIds)
        return [StyleResponse(**style) for style in styles]
    except Exception as e:
        logger.error(f"批量获取风格信息失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"批量获取风格信息失败: {str(e)}")


@router.post("/audiences/batch", response_model=List[AudienceResponse], summary="批量获取受众信息")
async def get_audiences_batch(
    audienceIds: List[int],
    db_service: DatabaseService = Depends(get_database_service)
):
    """
    批量获取受众信息
    
    - **audienceIds**: 受众ID列表
    """
    try:
        if not db_service.is_available():
            raise HTTPException(status_code=503, detail="数据库服务不可用")
        
        audiences = db_service.get_audiences_by_ids(audienceIds)
        return [AudienceResponse(**audience) for audience in audiences]
    except Exception as e:
        logger.error(f"批量获取受众信息失败: {e}", exc_info=True)
        raise HTTPException(status_code=500, detail=f"批量获取受众信息失败: {str(e)}") 