# _*_ coding : UTF-8 _*_
# @Time : 2025/01/20 01:30
# @UpdateTime : 2025/01/20 01:30
# @Author : sonder
# @File : department.py
# @Software : PyCharm
# @Comment : 本程序
from typing import Optional

from fastapi import APIRouter, Depends, Query, Path, Request
from fastapi.responses import JSONResponse

from annotation.auth import Auth
from annotation.log import Log
from config.constant import BusinessType, RedisKeyConfig
from controller.login import LoginController
from models import Department, Role
from schemas.common import BaseResponse, DeleteListParams
from schemas.department import AddDepartmentParams, GetDepartmentInfoResponse, \
    GetDepartmentListResponse
from utils.response import Response

departmentAPI = APIRouter(prefix="/department")


@departmentAPI.post("/add", response_model=BaseResponse, response_class=JSONResponse, summary="新增部门")
@Log(title="新增部门", business_type=BusinessType.INSERT)
@Auth(["department:btn:add"])
async def add_department(request: Request, params: AddDepartmentParams,
                         current_user: dict = Depends(LoginController.get_current_user)):
    parent_id = current_user.get("department_id")
    if not params.parent_id:
        params.parent_id = parent_id
    department = await Department.create(
        name=params.name,
        parent_id=params.parent_id,
        principal=params.principal,
        phone=params.phone,
        email=params.email,
        remark=params.remark,
        sort=params.sort,
        status=params.status
    )
    if department:
        if await request.app.state.redis.get(f'{RedisKeyConfig.USER_INFO.key}:*'):
            await request.app.state.redis.delete(f'{RedisKeyConfig.USER_INFO.key}:*')
        return Response.success(msg="添加成功！")
    else:
        return Response.error(msg="添加失败！")


@departmentAPI.delete("/delete/{id}", response_model=BaseResponse, response_class=JSONResponse, summary="删除部门")
@departmentAPI.post("/delete/{id}", response_model=BaseResponse, response_class=JSONResponse, summary="删除部门")
@Log(title="删除部门", business_type=BusinessType.DELETE)
@Auth(["department:btn:delete"])
async def delete_department(request: Request, id: str = Path(description="部门ID"),
                            current_user: dict = Depends(LoginController.get_current_user)):
    if department := await Department.get_or_none(id=id, del_flag=1):
        sub_departments = current_user.get("sub_departments")
        if department.id not in sub_departments:
            return Response.error(msg="删除失败,无权限！")
        if await delete_department_recursive(department_id=department.id):
            if await request.app.state.redis.get(f'{RedisKeyConfig.USER_INFO.key}:*'):
                await request.app.state.redis.delete(f'{RedisKeyConfig.USER_INFO.key}:*')
            return Response.success(msg="删除成功！")
        return Response.error(msg="删除失败!")
    else:
        return Response.error(msg="删除失败,部门不存在！")


@departmentAPI.delete("/deleteList", response_model=BaseResponse, response_class=JSONResponse, summary="批量删除部门")
@departmentAPI.post("/deleteList", response_model=BaseResponse, response_class=JSONResponse, summary="批量删除部门")
@Log(title="批量删除部门", business_type=BusinessType.DELETE)
@Auth(["department:btn:delete"])
async def delete_department_list(request: Request, params: DeleteListParams,
                                 current_user: dict = Depends(LoginController.get_current_user)):
    sub_departments = current_user.get("sub_departments")
    for item in set(params.ids):
        if department := await Department.get_or_none(id=item, del_flag=1):
            if item in sub_departments:
                await delete_department_recursive(department_id=department.id)
    userInfos = await request.app.state.redis.keys(f'{RedisKeyConfig.USER_INFO.key}*')
    if userInfos:
        await request.app.state.redis.delete(*userInfos)
    return Response.success(msg="删除成功！")


async def delete_department_recursive(department_id: str):
    """
    递归删除部门及其附属部门
    :param department_id: 部门ID
    :return:
    """
    await Department.filter(id=department_id, del_flag=1).update(del_flag=0)
    sub_departments = await Department.filter(parent_id=department_id, del_flag=1).all()
    for sub_department in sub_departments:
        await delete_department_recursive(sub_department.id)
    return True


@departmentAPI.put("/update/{id}", response_model=BaseResponse, response_class=JSONResponse, summary="修改部门")
@departmentAPI.post("/update/{id}", response_model=BaseResponse, response_class=JSONResponse, summary="修改部门")
@Log(title="修改部门", business_type=BusinessType.UPDATE)
@Auth(["department:btn:update"])
async def update_department(request: Request, params: AddDepartmentParams, id: str = Path(description="部门ID"),
                            current_user: dict = Depends(LoginController.get_current_user)):
    if department := await Department.get_or_none(id=id, del_flag=1):
        sub_departments = current_user.get("sub_departments")
        if id not in sub_departments:
            return Response.error(msg="修改失败,无权限！")
        department.name = params.name
        department.parent_id = params.parent_id
        department.principal = params.principal
        department.phone = params.phone
        department.email = params.email
        department.remark = params.remark
        department.sort = params.sort
        department.status = params.status
        await department.save()
        userInfos = await request.app.state.redis.keys(f'{RedisKeyConfig.USER_INFO.key}*')
        if userInfos:
            await request.app.state.redis.delete(*userInfos)
        return Response.success(msg="修改成功！")
    else:
        return Response.error(msg="修改失败,部门不存在！")


@departmentAPI.get("/info/{id}", response_model=GetDepartmentInfoResponse, response_class=JSONResponse,
                   summary="查询部门详情")
@Log(title="查询部门详情", business_type=BusinessType.SELECT)
@Auth(["department:btn:info"])
async def get_department(request: Request, id: str = Path(description="部门ID"),
                         current_user: dict = Depends(LoginController.get_current_user)):
    if department := await Department.get_or_none(id=id, del_flag=1).values(
            id="id",
            name="name",
            parent_id="parent_id",
            principal="principal",
            phone="phone",
            email="email",
            remark="remark",
            sort="sort",
            status="status",
            create_time="create_time",
            update_time="update_time",
            create_by="create_by",
            update_by="update_by"
    ):
        sub_departments = current_user.get("sub_departments")
        if id not in sub_departments:
            return Response.error(msg="查询失败,无权限！")
        return Response.success(data=department)
    else:
        return Response.error(msg="部门不存在！")


@departmentAPI.get("/list", response_model=GetDepartmentListResponse, response_class=JSONResponse,
                   summary="查询部门列表")
@Log(title="查询部门列表", business_type=BusinessType.SELECT)
@Auth(["department:btn:list"])
async def get_department_list(
        request: Request,
        page: int = Query(default=1, description="当前页码"),
        pageSize: int = Query(default=10, description="每页条数"),
        name: Optional[str] = Query(default=None, description="部门名称"),
        principal: Optional[str] = Query(default=None, description="负责人"),
        phone: Optional[str] = Query(default=None, description="电话"),
        email: Optional[str] = Query(default=None, description="邮箱"),
        remark: Optional[str] = Query(default=None, description="备注"),
        sort: Optional[int] = Query(default=None, description="排序权重"),
        current_user: dict = Depends(LoginController.get_current_user)
):
    filterArgs = {
        f'{k}__contains': v for k, v in {
            'name': name,
            'principal': principal,
            'phone': phone,
            'email': email,
            'remark': remark,
            'sort': sort
        }.items() if v
    }
    sub_departments = current_user.get("sub_departments")
    total = await Department.filter(**filterArgs, del_flag=1, id__in=sub_departments).count()
    data = await Department.filter(**filterArgs, del_flag=1, id__in=sub_departments).offset(
        (page - 1) * pageSize).limit(
        pageSize).values(
        id="id",
        name="name",
        parent_id="parent_id",
        principal="principal",
        phone="phone",
        email="email",
        remark="remark",
        sort="sort",
        status="status",
        create_time="create_time",
        update_time="update_time",
        create_by="create_by",
        update_by="update_by"
    )
    return Response.success(data={
        "result": data,
        "total": total,
        "page": page,
        "pageSize": pageSize
    })


@departmentAPI.get("/roleList/{id}", response_model=GetDepartmentListResponse, response_class=JSONResponse,
                   summary="用户获取部门角色列表")
@Log(title="获取部门角色列表", business_type=BusinessType.SELECT)
@Auth(["department:btn:list"])
async def get_department_role_list(
        request: Request,
        id: str = Path(..., description="部门ID"),
        current_user: dict = Depends(LoginController.get_current_user)
):
    sub_departments = current_user.get("sub_departments")
    if id not in sub_departments:
        return Response.error(msg="查询失败,无权限！")
    data = await Role.filter(department__id=id).values(
        id="id",
        department_id="department__id",
        department_name="department__name",
        department_phone="department__phone",
        department_principal="department__principal",
        department_email="department__email",
        role_name="name",
        role_code="code",
        role_id="id",
        create_time="create_time",
        update_time="update_time"
    )
    return Response.success(data={
        "result": data,
        "total": len(data),
        "page": 1,
        "pageSize": 9999
    })
