import json

from fastapi import APIRouter, Query, HTTPException,Request
from mysql.connector import Error as MySQLError

from ds.db import db
from schema.device_schema import DeviceCreateRequest, DeviceResponse, DeviceListResponse
from schema.response_schema import APIResponse

router = APIRouter(
    prefix="/devices",
    tags=["设备管理"]
)


# ------------------------------
# 内部工具方法 - 通过客户端IP增加设备报警次数
# ------------------------------
def increment_alarm_count_by_ip(client_ip: str) -> bool:
    """
    通过客户端IP增加设备的报警次数（内部服务方法）

    :param client_ip: 客户端IP地址
    :return: 操作是否成功
    """
    if not client_ip:
        raise ValueError("客户端IP不能为空")

    conn = None
    cursor = None
    try:
        conn = db.get_connection()
        cursor = conn.cursor(dictionary=True)

        # 检查设备是否存在
        cursor.execute("SELECT id FROM devices WHERE client_ip = %s", (client_ip,))
        if not cursor.fetchone():
            raise ValueError(f"客户端IP为 {client_ip} 的设备不存在")

        # 报警次数加1，并更新时间戳
        update_query = """
            UPDATE devices 
            SET alarm_count = alarm_count + 1, 
                updated_at = CURRENT_TIMESTAMP 
            WHERE client_ip = %s
        """
        cursor.execute(update_query, (client_ip,))
        conn.commit()

        return True
    except MySQLError as e:
        if conn:
            conn.rollback()
        raise Exception(f"更新报警次数失败：{str(e)}") from e
    finally:
        db.close_connection(conn, cursor)


# ------------------------------
# 内部工具方法 - 通过客户端IP更新设备在线状态
# ------------------------------
def update_online_status_by_ip(client_ip: str, online_status: int) -> bool:
    """
    通过客户端IP更新设备的在线状态（内部服务方法）

    :param client_ip: 客户端IP地址
    :param online_status: 在线状态（1-在线、0-离线）
    :return: 操作是否成功
    """
    if not client_ip:
        raise ValueError("客户端IP不能为空")

    # 验证状态值有效性
    if online_status not in (0, 1):
        raise ValueError("在线状态必须是0（离线）或1（在线）")

    conn = None
    cursor = None
    try:
        conn = db.get_connection()
        cursor = conn.cursor(dictionary=True)

        # 检查设备是否存在
        cursor.execute("SELECT id FROM devices WHERE client_ip = %s", (client_ip,))
        if not cursor.fetchone():
            raise ValueError(f"客户端IP为 {client_ip} 的设备不存在")

        # 更新在线状态和时间戳
        update_query = """
            UPDATE devices 
            SET device_online_status = %s, 
                updated_at = CURRENT_TIMESTAMP 
            WHERE client_ip = %s
        """
        cursor.execute(update_query, (online_status, client_ip))
        conn.commit()

        return True
    except MySQLError as e:
        if conn:
            conn.rollback()
        raise Exception(f"更新设备在线状态失败：{str(e)}") from e
    finally:
        db.close_connection(conn, cursor)


# ------------------------------
# 原有接口保持不变
# ------------------------------
@router.post("/add", response_model=APIResponse, summary="创建设备信息")
async def create_device(device_data: DeviceCreateRequest, request: Request):  # 注入Request对象
    # 原有代码保持不变
    conn = None
    cursor = None
    try:
        conn = db.get_connection()
        cursor = conn.cursor(dictionary=True)

        cursor.execute("SELECT * FROM devices WHERE client_ip = %s", (device_data.ip,))
        existing_device = cursor.fetchone()
        if existing_device:
            # 更新设备状态为在线
            update_online_status_by_ip(client_ip=device_data.ip, online_status=1)
            # 返回信息
            return APIResponse(
                code=200,
                message=f"设备IP {device_data.ip} 已存在，返回已有设备信息",
                data=DeviceResponse(** existing_device)
            )

        # 直接使用注入的request对象获取用户代理
        user_agent = request.headers.get("User-Agent", "").lower()

        if user_agent == "default":
            device_type = device_data.params.get("os") if (
                    device_data.params and isinstance(device_data.params, dict)) else "unknown"
        elif "windows" in user_agent:
            device_type = "windows"
        elif "android" in user_agent:
            device_type = "android"
        elif "linux" in user_agent:
            device_type = "linux"
        else:
            device_type = "unknown"

        device_params_json = json.dumps(device_data.params) if device_data.params else None

        insert_query = """
            INSERT INTO devices 
            (client_ip, hostname, device_online_status, device_type, alarm_count, params)
            VALUES (%s, %s, %s, %s, %s, %s)
        """
        cursor.execute(insert_query, (
            device_data.ip,
            device_data.hostname,
            1,
            device_type,
            0,
            device_params_json
        ))
        conn.commit()

        device_id = cursor.lastrowid
        cursor.execute("SELECT * FROM devices WHERE id = %s", (device_id,))
        new_device = cursor.fetchone()

        return APIResponse(
            code=200,
            message="设备创建成功",
            data=DeviceResponse(**new_device)
        )

    except MySQLError as e:
        if conn:
            conn.rollback()
        raise Exception(f"创建设备失败：{str(e)}") from e
    except json.JSONDecodeError as e:
        raise Exception(f"设备详细信息JSON序列化失败：{str(e)}") from e
    except Exception as e:
        if conn:
            conn.rollback()
        raise e
    finally:
        db.close_connection(conn, cursor)

@router.get("/", response_model=APIResponse, summary="获取设备列表（支持筛选分页）")
async def get_device_list(
        page: int = Query(1, ge=1, description="页码，默认第1页"),
        page_size: int = Query(10, ge=1, le=100, description="每页条数，1-100之间"),
        device_type: str = Query(None, description="按设备类型筛选"),
        online_status: int = Query(None, ge=0, le=1, description="按在线状态筛选")
):
    # 原有代码保持不变
    conn = None
    cursor = None
    try:
        conn = db.get_connection()
        cursor = conn.cursor(dictionary=True)

        where_clause = []
        params = []

        if device_type:
            where_clause.append("device_type = %s")
            params.append(device_type)
        if online_status is not None:
            where_clause.append("device_online_status = %s")
            params.append(online_status)

        count_query = "SELECT COUNT(*) AS total FROM devices"
        if where_clause:
            count_query += " WHERE " + " AND ".join(where_clause)
        cursor.execute(count_query, params)
        total = cursor.fetchone()["total"]

        offset = (page - 1) * page_size
        list_query = "SELECT * FROM devices"
        if where_clause:
            list_query += " WHERE " + " AND ".join(where_clause)
        list_query += " ORDER BY id DESC LIMIT %s OFFSET %s"
        params.extend([page_size, offset])

        cursor.execute(list_query, params)
        device_list = cursor.fetchall()

        return APIResponse(
            code=200,
            message="获取设备列表成功",
            data=DeviceListResponse(
                total=total,
                devices=[DeviceResponse(**device) for device in device_list]
            )
        )

    except MySQLError as e:
        raise Exception(f"获取设备列表失败：{str(e)}") from e
    finally:
        db.close_connection(conn, cursor)
