# -*- coding:utf-8 -*-
"""
@Author  : xuxingchen
@Contact : xuxingchen@sinochem.com
@Desc    : 通行空间映射界面控制逻辑
"""
import os.path
from io import BytesIO

from fastapi import APIRouter, Request, Header, BackgroundTasks, UploadFile, File
from fastapi.responses import FileResponse

from models.brands import BrandsTable, UpdateBrand
from models.spaces import SpacesTable
from routers.login import authenticate_token
from utils import logger
from utils.logger import TOKEN_ERROR
from utils.database import get_table_handler
from utils.misc import InvalidException, valid_xls

router = APIRouter()


@router.post("/updateSubSystemPlatformName", summary="更新当前使用的可视对讲厂家")
async def update_sub_system_platform_name(request: Request, item: UpdateBrand, token: str = Header(...)):
    """更新当前使用的可视对讲厂家"""
    if not authenticate_token(token):
        raise InvalidException(TOKEN_ERROR)
    th = get_table_handler()
    resp = BrandsTable.update_checked_factory(th, item.name)
    logger.Logger.debug(f"{request.url.path} {resp}")
    return resp


@router.get("/getSubSystemPlatformName", summary="查询当前使用的可视对讲厂家")
async def get_sub_system_platform_name(request: Request, token: str = Header(...)):
    """获取当前启用的可视对讲厂家"""
    if not authenticate_token(token):
        raise InvalidException(TOKEN_ERROR)
    th = get_table_handler()
    resp = BrandsTable.get_checked_factory(th)
    logger.Logger.debug(f"{request.url.path} {resp}")
    return resp


@router.get("/exportAiotPlatformData", summary="导出AIOT平台空间数据")
async def export_aiot_platform_data(request: Request, background_tasks: BackgroundTasks, token: str = Header(...)):
    """导出AIOT平台空间数据"""
    if not authenticate_token(token):
        raise InvalidException(TOKEN_ERROR)
    th = get_table_handler()
    file_path = SpacesTable.get_aiot_platform_data(th)
    background_tasks.add_task(os.remove, file_path)
    logger.Logger.debug(f"{request.url.path} 完成AIOT平台空间数据导出")
    return FileResponse(path=file_path,
                        filename=os.path.basename(file_path),
                        media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")


@router.get("/exportSubSystemData", summary="导出子系统空间结构数据表")
async def export_aiot_platform_data(request: Request, background_tasks: BackgroundTasks, token: str = Header(...)):
    """导出子系统空间结构数据表"""
    if not authenticate_token(token):
        raise InvalidException(TOKEN_ERROR)
    th = get_table_handler()
    file_path = SpacesTable.get_sub_system_data(th)
    background_tasks.add_task(os.remove, file_path)
    logger.Logger.debug(f"{request.url.path} 完成子系统空间数据导出")
    return FileResponse(path=file_path,
                        filename=os.path.basename(file_path),
                        media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")


@router.post("/importIdMapData", summary="导入空间映射表")
async def import_id_map_data(request: Request,
                             xls_file: UploadFile = File(...),
                             token: str = Header(...)):
    """接收空间映射表xls表格上传、校验并更新对应映射信息"""
    if not authenticate_token(token):
        raise InvalidException(TOKEN_ERROR)
    # 检查文件类型是否为xls
    if xls_file.content_type not in ["application/vnd.ms-excel",
                                     "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]:
        resp = {"status": False, "message": "仅支持上传xls文件"}
    else:
        file_content = await xls_file.read()
        max_size_mb = 10  # 设置最大允许的文件大小为 10MB
        if xls_file.file.seek(0, os.SEEK_END) > max_size_mb * 1024 * 1024:
            resp = {"status": False, "message": f"文件大小不得超过 {max_size_mb}MB"}
        else:
            # 解析xls，校验数据格式是否符合标准
            required_columns = ["房屋id", "子系统id", "子系统空间名称"]
            _callback, message, data = valid_xls(BytesIO(file_content), required_columns)
            if _callback:
                th = get_table_handler()
                SpacesTable.update(th, data)
                resp = {"status": True}
            else:
                raise InvalidException(message)
    logger.Logger.debug(f"{request.url.path} {resp}")
    return resp
