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

"""
地图数据推送API路由
实现地图数据推送时的动作点和库区数据存储功能
"""

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from typing import Any, Dict

from data.session import get_db
from services.map_data_service import MapDataService
from routes.model.base import ApiResponse
from routes.model.map_model import (
    MapDataPushRequest, MapDataPushResponse, 
    MapDataQueryRequest, MapDataQueryResponse
)
from routes.common_api import format_response, error_response
from utils.logger import get_logger

# 创建路由
router = APIRouter(prefix="/api/vwed-map-data", tags=["地图数据推送"])

# 设置日志
logger = get_logger("app.map_data_api")


# 标准API响应格式
def api_response(code: int = 200, message: str = "操作成功", data: Any = None) -> Dict[str, Any]:
    """
    标准API响应格式
    
    Args:
        code: 状态码
        message: 响应消息
        data: 响应数据
    
    Returns:
        Dict[str, Any]: 格式化的响应数据
    """
    return {
        "code": code,
        "message": message,
        "data": data
    }


@router.post("/push", response_model=ApiResponse[MapDataPushResponse])
async def push_map_data(
    request: MapDataPushRequest,
    db: Session = Depends(get_db)
):
    """
    推送地图数据
    
    当用户推送新的地图时，将地图相关的动作点和库区数据存入数据库
    支持库区分类（密集库区、一般库区）和动作点分层存储
    
    重要功能：
    - 自动为新创建的库位层同步所有已启用的扩展属性
    - 新库位层会自动包含系统中定义的扩展属性配置
    - 扩展属性使用默认值进行初始化
    
    Args:
        request: 地图数据推送请求
        db: 数据库会话
    
    Returns:
        ApiResponse[MapDataPushResponse]: 推送结果响应
    """
    try:
        # 调用服务层方法推送地图数据
        result = MapDataService.push_map_data(db=db, request=request)
        
        return api_response(message="地图数据推送成功", data=result)
    
    except ValueError as e:
        # 数据验证错误
        return error_response(str(e), 400)
    
    except Exception as e:
        logger.error(f"地图数据推送失败: {str(e)}")
        return error_response(f"地图数据推送失败: {str(e)}", 500)


@router.post("/query", response_model=ApiResponse[MapDataQueryResponse])
async def query_map_data(
    request: MapDataQueryRequest,
    db: Session = Depends(get_db)
):
    """
    查询地图数据
    
    根据场景ID查询地图中的库区和动作点数据
    支持按库区类型筛选和是否包含分层数据的选项
    
    Args:
        request: 地图数据查询请求
        db: 数据库会话
    
    Returns:
        ApiResponse[MapDataQueryResponse]: 查询结果响应
    """
    try:
        # 调用服务层方法查询地图数据
        result = MapDataService.query_map_data(db=db, request=request)
        
        return api_response(message="查询成功", data=result)
    
    except ValueError as e:
        # 数据验证错误
        return error_response(str(e), 400)
    
    except Exception as e:
        logger.error(f"查询地图数据失败: {str(e)}")
        return error_response(f"查询地图数据失败: {str(e)}", 500)


@router.delete("/scene/{scene_id}")
async def delete_scene_data(
    scene_id: str,
    db: Session = Depends(get_db)
):
    """
    删除场景数据
    
    删除指定场景的所有地图数据，包括库区、动作点和分层数据
    
    Args:
        scene_id: 场景ID
        db: 数据库会话
    
    Returns:
        ApiResponse: 删除结果响应
    """
    try:
        # 调用服务层的删除方法
        MapDataService._delete_existing_data(db=db, scene_id=scene_id)
        db.commit()
        
        logger.info(f"场景数据删除成功: 场景ID={scene_id}")
        return api_response(message="场景数据删除成功")
    
    except Exception as e:
        db.rollback()
        logger.error(f"删除场景数据失败: {str(e)}")
        return error_response(f"删除场景数据失败: {str(e)}", 500)


@router.get("/scene/{scene_id}/summary")
async def get_scene_summary(
    scene_id: str,
    db: Session = Depends(get_db)
):
    """
    获取场景数据摘要
    
    获取指定场景的数据统计信息，包括库区和动作点的数量统计
    
    Args:
        scene_id: 场景ID
        db: 数据库会话
    
    Returns:
        ApiResponse: 场景摘要信息
    """
    try:
        # 构造查询请求
        query_request = MapDataQueryRequest(
            scene_id=scene_id,
            include_layers=True
        )
        
        # 调用服务层方法获取数据
        result = MapDataService.query_map_data(db=db, request=query_request)
        
        # 提取摘要信息
        summary = {
            "scene_id": result.scene_id,
            "total_storage_areas": len(result.storage_areas),
            "total_operate_points": len(result.operate_points),
            "total_capacity": result.total_capacity,
            "used_capacity": result.used_capacity,
            "capacity_usage_rate": round(
                (result.used_capacity / result.total_capacity * 100) if result.total_capacity > 0 else 0, 2
            ),
            "dense_areas_count": result.dense_areas_count,
            "general_areas_count": result.general_areas_count,
            "total_layers": result.total_layers,
            "occupied_layers": result.occupied_layers,
            "layer_usage_rate": round(
                (result.occupied_layers / result.total_layers * 100) if result.total_layers > 0 else 0, 2
            )
        }
        
        return api_response(message="获取场景摘要成功", data=summary)
    
    except Exception as e:
        logger.error(f"获取场景摘要失败: {str(e)}")
        return error_response(f"获取场景摘要失败: {str(e)}", 500) 