"""交叉评查控制器（第一阶段骨架）。"""

from typing import Any

from fastapi import Depends, File, Form, Query, UploadFile
from fastapi.responses import JSONResponse

from fastapi_common.fastapi_common_security.security import verify_access_token
from fastapi_common.fastapi_common_web.controller import BaseController
from fastapi_common.fastapi_common_web.domain.responses import Result

from fastapi_modules.fastapi_leaudit.domian.Dto.crossReviewDto import (
    CrossReviewProposalCreateDTO,
    CrossReviewProposalVoteDTO,
    CrossReviewTaskCreateDTO,
    CrossReviewTaskDocumentQueryDTO,
    CrossReviewTaskQueryDTO,
)
from fastapi_modules.fastapi_leaudit.domian.vo.crossReviewVo import (
    CrossReviewPendingVotesVO,
    CrossReviewPermissionVO,
    CrossReviewProposalCancelVO,
    CrossReviewProposalCreateVO,
    CrossReviewProposalPageVO,
    CrossReviewProposalVoteVO,
    CrossReviewTaskCompleteVO,
    CrossReviewTaskCreateVO,
    CrossReviewTaskDocumentPageVO,
    CrossReviewTaskDocumentUploadVO,
    CrossReviewTaskPageVO,
    CrossReviewTaskProgressVO,
)
from fastapi_modules.fastapi_leaudit.services.crossReviewService import ICrossReviewService
from fastapi_modules.fastapi_leaudit.services.impl.crossReviewServiceImpl import CrossReviewServiceImpl
from fastapi_modules.fastapi_leaudit.services.impl.permissionServiceImpl import PermissionServiceImpl
from fastapi_modules.fastapi_leaudit.services.permissionService import IPermissionService


class CrossReviewController(BaseController):
    """交叉评查控制器。"""

    _PERMISSIONS = {
        "task_create": "cross_review:task:create",
        "task_read": "cross_review:task:read",
        "progress_view": "cross_review:progress:view",
        "document_read": "cross_review:document:read",
        "document_complete": "cross_review:document:complete",
        "proposal_create": "cross_review:proposal:create",
        "proposal_read": "cross_review:proposal:read",
        "proposal_delete": "cross_review:proposal:delete",
        "proposal_vote": "cross_review:proposal:vote",
    }

    def __init__(self):
        super().__init__(prefix="/v3/cross-review", tags=["交叉评查"])
        self.CrossReviewService: ICrossReviewService = CrossReviewServiceImpl()
        self.PermissionService: IPermissionService = PermissionServiceImpl()

        @self.router.post("/tasks", response_model=Result[CrossReviewTaskCreateVO])
        async def CreateTask(
            Body: CrossReviewTaskCreateDTO,
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """创建交叉评查任务。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["task_create"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有创建交叉评查任务权限", "data": None})
            Data = await self.CrossReviewService.CreateTask(CurrentUserId=int(payload["user_id"]), Body=Body)
            return Result.success(data=Data, message="交叉评查任务创建成功")

        @self.router.post("/tasks/query", response_model=Result[CrossReviewTaskPageVO])
        async def GetUserTasks(
            Body: CrossReviewTaskQueryDTO,
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """查询当前用户参与的交叉评查任务。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["task_read"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看交叉评查任务权限", "data": None})
            Data = await self.CrossReviewService.GetUserTasks(CurrentUserId=int(payload["user_id"]), Body=Body)
            return Result.success(data=Data)

        @self.router.get("/tasks/{TaskId}/progress", response_model=Result[CrossReviewTaskProgressVO])
        async def GetTaskProgress(
            TaskId: int,
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """查询任务进度。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["progress_view"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看交叉评查任务进度权限", "data": None})
            Data = await self.CrossReviewService.GetTaskProgress(CurrentUserId=int(payload["user_id"]), TaskId=TaskId)
            return Result.success(data=Data)

        @self.router.get("/tasks/{TaskId}/documents", response_model=Result[CrossReviewTaskDocumentPageVO])
        async def GetTaskDocuments(
            TaskId: int,
            page: int = Query(1, ge=1, description="页码"),
            pageSize: int = Query(20, ge=1, le=100, description="每页大小"),
            keyword: str | None = Query(None, description="关键字"),
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """查询任务文档列表。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["task_read"], self._PERMISSIONS["document_read"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看交叉评查任务文档权限", "data": None})
            Body = CrossReviewTaskDocumentQueryDTO(page=page, pageSize=pageSize, keyword=keyword)
            Data = await self.CrossReviewService.GetTaskDocuments(
                CurrentUserId=int(payload["user_id"]),
                TaskId=TaskId,
                Body=Body,
            )
            return Result.success(data=Data)

        @self.router.get("/tasks/{TaskId}/can-confirm", response_model=Result[CrossReviewPermissionVO])
        async def CanConfirmTaskDocument(
            TaskId: int,
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """查询当前用户是否可确认完成。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["document_complete"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有确认交叉评查文档完成权限", "data": None})
            Data = await self.CrossReviewService.CanConfirmTaskDocument(CurrentUserId=int(payload["user_id"]), TaskId=TaskId)
            return Result.success(data=Data)

        @self.router.post("/tasks/{TaskId}/documents/{DocumentId}/complete", response_model=Result[CrossReviewTaskCompleteVO])
        async def CompleteTaskDocument(
            TaskId: int,
            DocumentId: int,
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """确认任务文档完成。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["document_complete"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有确认交叉评查文档完成权限", "data": None})
            Data = await self.CrossReviewService.CompleteTaskDocument(
                CurrentUserId=int(payload["user_id"]),
                TaskId=TaskId,
                DocumentId=DocumentId,
            )
            return Result.success(data=Data, message="交叉评查文档已确认完成")

        @self.router.post("/tasks/{TaskId}/documents/upload", response_model=Result[CrossReviewTaskDocumentUploadVO])
        async def UploadTaskDocument(
            TaskId: int,
            file: UploadFile = File(..., description="上传文档"),
            typeId: int | None = Form(None, description="文档类型ID"),
            groupId: int | None = Form(None, description="文档子类型ID"),
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """向交叉评查任务补传文档。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["document_complete"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有交叉评查任务补传文档权限", "data": None})
            content = await file.read()
            Data = await self.CrossReviewService.UploadTaskDocument(
                CurrentUserId=int(payload["user_id"]),
                TaskId=TaskId,
                FileName=file.filename or "upload.bin",
                FileContent=content,
                ContentType=file.content_type,
                TypeId=typeId,
                GroupId=groupId,
            )
            return Result.success(data=Data, message="交叉评查任务文档上传成功")

        @self.router.post("/proposals", response_model=Result[CrossReviewProposalCreateVO])
        async def CreateProposal(
            Body: CrossReviewProposalCreateDTO,
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """创建交叉评查提案。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["proposal_create"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有创建交叉评查提案权限", "data": None})
            Data = await self.CrossReviewService.CreateProposal(CurrentUserId=int(payload["user_id"]), Body=Body)
            return Result.success(data=Data, message="交叉评查提案创建成功")

        @self.router.post("/proposals/{ProposalId}/votes", response_model=Result[CrossReviewProposalVoteVO])
        async def VoteProposal(
            ProposalId: int,
            Body: CrossReviewProposalVoteDTO,
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """对交叉评查提案投票。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["proposal_vote"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有交叉评查提案投票权限", "data": None})
            Data = await self.CrossReviewService.VoteProposal(CurrentUserId=int(payload["user_id"]), ProposalId=ProposalId, Body=Body)
            return Result.success(data=Data, message="交叉评查提案投票成功")

        @self.router.delete("/proposals/{ProposalId}", response_model=Result[CrossReviewProposalCancelVO])
        async def CancelProposal(
            ProposalId: int,
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """撤销交叉评查提案。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["proposal_delete"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有撤销交叉评查提案权限", "data": None})
            Data = await self.CrossReviewService.CancelProposal(CurrentUserId=int(payload["user_id"]), ProposalId=ProposalId)
            return Result.success(data=Data, message="交叉评查提案已撤销")

        @self.router.get("/documents/{DocumentId}/proposals", response_model=Result[CrossReviewProposalPageVO])
        async def GetDocumentProposals(
            DocumentId: int,
            page: int = Query(1, ge=1, description="页码"),
            pageSize: int = Query(20, ge=1, le=100, description="每页大小"),
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """获取文档提案列表。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["proposal_read"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看交叉评查提案权限", "data": None})
            Data = await self.CrossReviewService.GetDocumentProposals(
                CurrentUserId=int(payload["user_id"]),
                DocumentId=DocumentId,
                Page=page,
                PageSize=pageSize,
            )
            return Result.success(data=Data)

        @self.router.get("/documents/{DocumentId}/pending-votes", response_model=Result[CrossReviewPendingVotesVO])
        async def GetDocumentPendingVotes(
            DocumentId: int,
            payload: dict[str, Any] = Depends(verify_access_token),
        ):
            """获取文档待投票摘要。"""
            if not await self._check_permission(int(payload["user_id"]), [self._PERMISSIONS["proposal_read"], self._PERMISSIONS["document_complete"]]):
                return JSONResponse(status_code=403, content={"code": 403, "msg": "当前用户没有查看待投票信息权限", "data": None})
            Data = await self.CrossReviewService.GetDocumentPendingVotes(CurrentUserId=int(payload["user_id"]), DocumentId=DocumentId)
            return Result.success(data=Data)

    async def _check_permission(self, user_id: int, permission_keys: list[str]) -> bool:
        """OR 逻辑权限校验。"""
        for permission_key in permission_keys:
            if await self.PermissionService.CheckPermission(user_id, permission_key):
                return True
        return False
