import json
from typing import Any, Optional, Dict

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select
from app.models.pre_test_template import PreTestTemplate
from app.utils.douyinApi import DouyinApi
from app.utils.area import parse_district_data, get_area_by_level, get_cached_area_data, fetch_and_cache_area_data


from app.dependencies import get_current_user, get_db
from app.models.user import User
from app.schemas.pre_test_template import (
    PreTestTemplateCreate,
    PreTestTemplateListResponse,
    PreTestTemplateOut,
    PreTestTemplateUpdate,
)
from app.services.pre_test_template_service import (
    create_pre_test_template,
    delete_pre_test_template,
    get_default_template,
    get_pre_test_template,
    get_pre_test_template_list,
    update_pre_test_template,
)

router = APIRouter(prefix="/pre-test-template", tags=["前测模板"])


def _template_to_dict(template):
    return {
        "id": template.id,
        "name": template.name,
        "note": template.note,
        "platform": template.platform,
        "external_action": template.external_action,
        "cpa_bid": template.cpa_bid,
        "audience_gender": template.audience_gender,
        "audience_age": json.loads(template.audience_age) if template.audience_age else None,
        "audience_region": json.loads(template.audience_region) if template.audience_region else None,
        "audience_network": json.loads(template.audience_network) if template.audience_network else None,
        "cus_name": template.cus_name,
        "pricing_type": template.pricing_type,
        "cost_cap": template.cost_cap,
        "target_cost": template.target_cost,
        "nobid": template.nobid,
        "cpc_bid": template.cpc_bid,
        "budget": template.budget,
        "is_default": template.is_default,
        "user_id": template.user_id,
        "created_at": template.created_at,
        "updated_at": template.updated_at,
    }


@router.post(
    "/create",
    summary="创建前测模板",
    description="创建一个新的前测模板",
)
async def create_template(
    req: PreTestTemplateCreate,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> Any:
    try:
        #新增一个判断,如果模板名称重复,提示用户修改
        result = await db.execute(
            select(PreTestTemplate).where(
                PreTestTemplate.name == req.name,
                PreTestTemplate.user_id == current_user.id,
                PreTestTemplate.deleted_at.is_(None),
            )
        )
        existing_template = result.scalar()
        if existing_template:
            raise ValueError("模板名称已存在")
        
        template = await create_pre_test_template(
            user_id=current_user.id,
            db=db,
            name=req.name,
            note=req.note,
            platform=req.platform,
            external_action=req.external_action,
            cpa_bid=req.cpa_bid,
            audience_gender=req.audience_gender,
            audience_age=req.audience_age,
            audience_region=req.audience_region,
            audience_network=req.audience_network,
            cus_name=req.cus_name,
            pricing_type=req.pricing_type,
            cost_cap=req.cost_cap,
            target_cost=req.target_cost,
            nobid=req.nobid,
            cpc_bid=req.cpc_bid,
            budget=req.budget,
            is_default=req.is_default,
        )

        return {
            "code": 0,
            "message": "创建成功",
        }
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e),
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"创建失败: {str(e)}",
        )


@router.get(
    "/list",
    summary="获取前测模板列表",
    description="获取当前用户的前测模板列表,支持按平台筛选和分页",
    response_model=PreTestTemplateListResponse,
)
async def list_templates(
    platform: Optional[str] = Query(None, description="投放平台筛选（AD/QIANCHUAN/LOCAL）"),
    page: int = Query(1, description="页码,默认1"),
    page_size: int = Query(10, description="每页数量,默认10,最大100"),
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> Any:
    try:
        result = await get_pre_test_template_list(
            user_id=current_user.id,
            db=db,
            platform=platform,
            page=page,
            page_size=page_size,
        )

        return {
            "code": 0,
            "message": "查询成功",
            "data": [_template_to_dict(t) for t in result["data"]],
            "pagination": {
                "page": result["page"],
                "page_size": result["page_size"],
                "total": result["total"],
                "total_pages": (result["total"] + result["page_size"] - 1) // result["page_size"],
            },
        }
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e),
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"查询失败: {str(e)}",
        )


@router.get(
    "/default",
    summary="获取默认前测模板",
    description="获取当前用户的默认前测模板",
)
async def get_default(
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> Any:
    try:
        template = await get_default_template(current_user.id, db)

        if not template:
            return {
                "code": 0,
                "message": "未设置默认模板",
                "data": None,
            }

        return {
            "code": 0,
            "message": "查询成功",
            "data": _template_to_dict(template),
        }
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"查询失败: {str(e)}",
        )


@router.get(
    "/select/{template_id}",
    summary="获取前测模板详情",
    description="根据模板id获取前测模板详情",
)
async def get_template(
    template_id: str,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> Any:
    try:
        template = await get_pre_test_template(template_id, current_user.id, db)

        if not template:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="模板不存在",
            )

        return {
            "code": 0,
            "message": "查询成功",
            "data": _template_to_dict(template),
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"查询失败: {str(e)}",
        )


@router.post(
    "/update/{template_id}",
    summary="更新前测模板",
    description="更新指定的前测模板",
)
async def update_template(
    template_id: str,
    req: PreTestTemplateUpdate,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> Any:
    try:
        update_data = req.dict(exclude_none=True)
        template = await update_pre_test_template(template_id, current_user.id, db, **update_data)

        if not template:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="模板不存在",
            )

        return {
            "code": 0,
            "message": "更新成功",
            "data": _template_to_dict(template),
        }
    except HTTPException:
        raise
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e),
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"更新失败: {str(e)}",
        )


@router.get(
    "/delete/{template_id}",
    summary="删除前测模板",
    description="软删除指定的前测模板",
)
async def delete_template(
    template_id: str,
    current_user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
) -> Any:
    try:
        success = await delete_pre_test_template(template_id, current_user.id, db)

        if not success:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="模板不存在",
            )

        return {
            "code": 0,
            "message": "删除成功",
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"删除失败: {str(e)}",
        )


@router.get(
    "/getArea",
    summary="获取行政区域信息",
    description="获取指定级别的行政区域信息,支持一级、二级、三级区域,如果需要更新地区,执行：/api/pre-test-template/getArea?oauth_id=0019ecab9b8bc57d964&advertiser_id=1836693172153543",
)
async def get_template_area(
    oauth_id: str = Query(None, description="授权ID选填,更新地区必填"),
    advertiser_id: str = Query(default="1836693172153543", description="授权ID选填,更新地区必填"),
    code: Optional[str] = Query("CN", description="行政区域编码,默认中国CN,选填"),
    level: Optional[str] = Query("ONE_LEVEL", description="行政区域层级,可选值：ONE_LEVEL(获取省份)、TWO_LEVEL（市级）、THREE_LEVEL（区级）"),
    parent_code: Optional[str] = Query(None, description="父级区域编码,获取二级时传一级编码,获取三级时传二级编码"),
) -> Any:
    try:
        # 1. 先检查缓存是否存在
        area_list = get_cached_area_data()
        
        # 2. 如果缓存不存在,调用接口获取数据并保存到缓存
        if not area_list:
            area_list = await fetch_and_cache_area_data(oauth_id, advertiser_id, code)
        
        # 3. 根据 level 参数过滤区域
        if level == "ONE_LEVEL":
            result = get_area_by_level(area_list, "ONE_LEVEL")
        elif level == "TWO_LEVEL":
            result = get_area_by_level(area_list, "TWO_LEVEL", parent_code)
        elif level == "THREE_LEVEL":
            if not parent_code:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="获取三级区域需要提供二级区域编码(parent_code)",
                )
            result = get_area_by_level(area_list, "THREE_LEVEL", parent_code)
        else:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"不支持的级别: {level}",
            )
        
        # 4. 转换为字典格式返回
        result_dict = [area.to_dict() for area in result]
        
        return {
            "code": 0,
            "message": "成功",
            "data": result_dict,
        }
        
    except HTTPException:
        raise
    except ValueError as e:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e),
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取区域信息失败: {str(e)}",
        )
