from typing import Any, Optional, List

from fastapi import APIRouter, Body, Depends, HTTPException, Query, status
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession

from app.dependencies import get_admin_user, get_db
from app.models.user import User
from app.models.open_type import OpenType
from app.schemas.open_type import (
    OpenTypeCreate,
    OpenTypeUpdate,
    OpenTypeListResponse,
    OpenTypeResponse,
)
from app.utils.id_gen import generate_id

router = APIRouter(prefix="/open-type", tags=["open-type"])


# 公共接口 - 无需登录
@router.get(
    "/open_type_all",
    summary="查询所有开户方式",
    description="查询所有开户方式，前端使用select框选择，无需登录",
    dependencies=[],
)
async def get_open_type_public(
    db: AsyncSession = Depends(get_db),
) -> Any | dict:
    
    result = await db.execute(
        select(OpenType).where(OpenType.deleted_at.is_(None))
    )
    open_types = result.scalars().all()
    return {
        "code": 0,
        "message": "查询成功",
        "data": [
            {
                "id": ot.id,
                "type_name": ot.type_name,
                "open_type": ot.open_type,
                "description": ot.description,
                "thumb": ot.thumb,
            }
            for ot in open_types
        ],
    }


@router.get(
    "/list",
    summary="获取开户方式列表",
    description="获取开户方式列表，支持分页和筛选",
    response_model=OpenTypeListResponse,
)
async def get_open_type_list(
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(20, ge=1, le=100, description="每页数量"),
    type_name: Optional[str] = Query(None, description="标题名称筛选"),
    open_type: Optional[int] = Query(None, description="开户方式id筛选"),
    admin: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db),
) -> Any | dict:
    offset = (page - 1) * page_size

    query = select(OpenType).where(OpenType.deleted_at.is_(None))

    if type_name:
        query = query.where(OpenType.type_name.like(f"%{type_name}%"))

    if open_type:
        query = query.where(OpenType.open_type == open_type)

    result = await db.execute(
        query.order_by(OpenType.open_type.asc())
        .offset(offset)
        .limit(page_size)
    )
    open_types = result.scalars().all()

    count_query = select(func.count(OpenType.id)).where(OpenType.deleted_at.is_(None))
    if type_name:
        count_query = count_query.where(OpenType.type_name.like(f"%{type_name}%"))
    if open_type:
        count_query = count_query.where(OpenType.open_type == open_type)

    total_result = await db.execute(count_query)
    total = total_result.scalar_one()

    return {
        "code": 0,
        "message": "查询成功",
        "data": [
            {
                "id": item.id,
                "type_name": item.type_name,
                "open_type": item.open_type,
                "description": item.description,
                "thumb": item.thumb,
                "created_at": item.created_at,
                "updated_at": item.updated_at,
            }
            for item in open_types
        ],
        "pagination": {
            "page": page,
            "page_size": page_size,
            "total": total,
            "total_pages": (total + page_size - 1) // page_size,
        },
    }


@router.get(
    "/select/{id}",
    summary="获取开户方式详情",
    description="根据ID获取开户方式详情",
    response_model=OpenTypeResponse,
)
async def get_open_type_detail(
    id: str,
    admin: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db),
) -> Any | dict:
    result = await db.execute(
        select(OpenType).where(OpenType.id == id, OpenType.deleted_at.is_(None))
    )
    open_type = result.scalar_one_or_none()

    if not open_type:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="开户方式不存在",
        )

    return {
        "code": 0,
        "message": "查询成功",
        "data": {
            "id": open_type.id,
            "type_name": open_type.type_name,
            "open_type": open_type.open_type,
            "description": open_type.description,
            "thumb": open_type.thumb,
            "created_at": open_type.created_at,
            "updated_at": open_type.updated_at,
        },
    }


@router.post(
    "/create",
    summary="创建开户方式",
    description="创建新的开户方式",
    response_model=OpenTypeResponse,
)
async def create_open_type(
    req: OpenTypeCreate = Body(...),
    admin: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db),
) -> Any | dict:
    existing = await db.execute(
        select(OpenType).where(OpenType.open_type == req.open_type, OpenType.deleted_at.is_(None))
    )
    if existing.scalar_one_or_none():
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=f"开户方式ID {req.open_type} 已存在",
        )

    open_type = OpenType(
        id=generate_id(),
        type_name=req.type_name,
        open_type=req.open_type,
        description=req.description,
        thumb=req.thumb,
    )

    db.add(open_type)
    await db.commit()
    await db.refresh(open_type)

    return {
        "code": 0,
        "message": "创建成功",
        "data": {
            "id": open_type.id,
            "type_name": open_type.type_name,
            "open_type": open_type.open_type,
            "description": open_type.description,
            "thumb": open_type.thumb,
            "created_at": open_type.created_at,
            "updated_at": open_type.updated_at,
        },
    }


@router.put(
    "/update/{id}",
    summary="更新开户方式",
    description="更新指定的开户方式",
    response_model=OpenTypeResponse,
)
async def update_open_type(
    id: str,
    req: OpenTypeUpdate = Body(...),
    admin: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db),
) -> Any | dict:
    result = await db.execute(
        select(OpenType).where(OpenType.id == id, OpenType.deleted_at.is_(None))
    )
    open_type = result.scalar_one_or_none()

    if not open_type:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="开户方式不存在",
        )

    if req.open_type is not None and req.open_type != open_type.open_type:
        existing = await db.execute(
            select(OpenType).where(
                OpenType.open_type == req.open_type,
                OpenType.id != id,
                OpenType.deleted_at.is_(None),
            )
        )
        if existing.scalar_one_or_none():
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"开户方式ID {req.open_type} 已存在",
            )

    if req.type_name is not None:
        open_type.type_name = req.type_name
    if req.open_type is not None:
        open_type.open_type = req.open_type
    if req.description is not None:
        open_type.description = req.description
    if req.thumb is not None:
        open_type.thumb = req.thumb

    await db.commit()
    await db.refresh(open_type)

    return {
        "code": 0,
        "message": "更新成功",
        "data": {
            "id": open_type.id,
            "type_name": open_type.type_name,
            "open_type": open_type.open_type,
            "description": open_type.description,
            "thumb": open_type.thumb,
            "created_at": open_type.created_at,
            "updated_at": open_type.updated_at,
        },
    }


@router.delete(
    "/delete/{id}",
    summary="删除开户方式",
    description="软删除指定的开户方式",
    response_model=OpenTypeResponse,
)
async def delete_open_type(
    id: str,
    admin: User = Depends(get_admin_user),
    db: AsyncSession = Depends(get_db),
) -> Any | dict:
    result = await db.execute(
        select(OpenType).where(OpenType.id == id, OpenType.deleted_at.is_(None))
    )
    open_type = result.scalar_one_or_none()

    if not open_type:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="开户方式不存在",
        )

    open_type.deleted_at = func.now()
    await db.commit()

    return {
        "code": 0,
        "message": "删除成功",
        "data": None,
    }
