# -*- coding: utf-8 -*-
"""各业务端口工作台与子页面端点（企业/载体/服务商/政务）。

列表类页面数据全部由服务端（portal_pages 表）提供；企业发布任务写入 tasks 表。
OPC 端工作台在 ``rbac_opc.py`` 中（按用户聚合）。
"""
from __future__ import annotations

from fastapi import APIRouter, Depends, HTTPException, Request
from pydantic import BaseModel

from ..dependencies import get_db
from ..schemas.portals import EnterpriseTaskCreate, TaskReviewRequest, ReferralCreate
from ...rbac import require_roles, write_audit
from ...infrastructure.repositories import Database

router = APIRouter(tags=["portals"])

# 端口 -> 允许的角色
_PORT_ROLE = {
    "enterprise": "enterprise",
    "carrier": "carrier",
    "provider": "provider",
    "government": "government",
}


def _dashboard(port: str):
    role = _PORT_ROLE.get(port)
    if role is None:
        raise HTTPException(status_code=404, detail="Unknown port")

    async def handler(
        db: Database = Depends(get_db),
        _u: dict = Depends(require_roles(role)),
    ):
        payload = await db.portal_dashboards.get(port)
        if payload is None:
            raise HTTPException(status_code=404, detail="Dashboard not found")
        return payload

    return handler


def _page(port: str, page: str):
    role = _PORT_ROLE.get(port)
    if role is None:
        raise HTTPException(status_code=404, detail="Unknown port")

    async def handler(
        db: Database = Depends(get_db),
        _u: dict = Depends(require_roles(role)),
    ):
        payload = await db.portal_pages.get(port, page)
        if payload is None:
            raise HTTPException(status_code=404, detail="Page data not found")
        payload.setdefault("port", port)
        payload.setdefault("page", page)
        return payload

    return handler


router.get("/enterprise/dashboard", summary="企业端工作台")(_dashboard("enterprise"))
router.get("/carrier/dashboard", summary="载体/园区端工作台")(_dashboard("carrier"))
router.get("/provider/dashboard", summary="服务商端工作台")(_dashboard("provider"))
router.get("/government/dashboard", summary="政务端工作台")(_dashboard("government"))

# ── 子页面（列表/数据均由服务端提供）──────────────────────────────────────
router.get("/enterprise/talents", summary="企业·人才搜索")(_page("enterprise", "talents"))
router.get("/carrier/opc", summary="载体·OPC 管理")(_page("carrier", "opc"))
router.get("/carrier/services", summary="载体·服务管理")(_page("carrier", "services"))
router.get("/provider/orders", summary="服务商·订单管理")(_page("provider", "orders"))
router.get("/provider/services", summary="服务商·服务管理")(_page("provider", "services"))
router.get("/government/policies", summary="政务·政策管理")(_page("government", "policies"))


# ── 企业·任务（发布任务/我的任务）─────────────────────────────────────────
@router.get("/enterprise/tasks", summary="企业·我的任务列表")
async def enterprise_tasks(
    db: Database = Depends(get_db),
    _u: dict = Depends(require_roles("enterprise")),
):
    return {"items": await db.tasks.list(status="published")}


@router.post("/enterprise/tasks", summary="企业·发布任务")
async def enterprise_create_task(
    req: EnterpriseTaskCreate,
    request: Request,
    db: Database = Depends(get_db),
    actor: dict = Depends(require_roles("enterprise")),
):
    task = await db.tasks.create({**req.model_dump(exclude_none=True), "status": "pending"})
    await write_audit(db, action="task.publish", resource="task", resource_id=task["id"],
                detail=task["title"], user=actor, request=request)
    return task


@router.post("/enterprise/tasks/{task_id}/submit", summary="企业·提交审核并发布")
async def enterprise_submit_task(
    task_id: str,
    request: Request,
    db: Database = Depends(get_db),
    actor: dict = Depends(require_roles("enterprise")),
):
    task = await db.tasks.set_status(task_id, "published")
    if task is None:
        raise HTTPException(status_code=404, detail="Task not found")
    await write_audit(db, action="task.submit", resource="task", resource_id=task_id,
                user=actor, request=request)
    return task


@router.get("/enterprise/tasks/{task_id}/bids", summary="企业·查看竞标")
async def enterprise_list_bids(
    task_id: str,
    db: Database = Depends(get_db),
    _u: dict = Depends(require_roles("enterprise")),
):
    return {"items": await db.bids.list_for_task(task_id)}


@router.post("/enterprise/tasks/{task_id}/bids/{bid_id}/win", summary="企业·评标中标")
async def enterprise_win_bid(
    task_id: str, bid_id: str,
    request: Request,
    db: Database = Depends(get_db),
    actor: dict = Depends(require_roles("enterprise")),
):
    bid = await db.bids.set_status(bid_id, "win")
    if bid is None:
        raise HTTPException(status_code=404, detail="Bid not found")
    await db.tasks.set_status(task_id, "in_progress")
    await write_audit(db, action="bid.win", resource="bid", resource_id=bid_id,
                detail=f"task={task_id} winner={bid['opc_name']}", user=actor, request=request)
    return bid


@router.post("/enterprise/tasks/{task_id}/review", summary="企业·验收任务")
async def enterprise_review_task(
    task_id: str,
    req: TaskReviewRequest,
    request: Request,
    db: Database = Depends(get_db),
    actor: dict = Depends(require_roles("enterprise")),
):
    task = await db.tasks.get(task_id)
    if task is None:
        raise HTTPException(status_code=404, detail="Task not found")
    new_status = "completed" if req.action == "accept" else "in_progress"
    updated = await db.tasks.set_status(task_id, new_status)
    await write_audit(db, action="task.review", resource="task", resource_id=task_id,
                detail=req.action, user=actor, request=request)
    return updated


# ── 载体·服务商引荐（三方绑定：载体引荐服务商→服务园区内 OPC）─────────────
@router.get("/carrier/referrals", summary="载体·引荐记录")
async def carrier_referrals(
    db: Database = Depends(get_db),
    user: dict = Depends(require_roles("carrier")),
):
    return {"items": await db.referrals.list_for(user.get("org_id"))}


@router.post("/carrier/referrals", summary="载体·引荐服务商给园区内 OPC")
async def carrier_create_referral(
    req: ReferralCreate,
    request: Request,
    db: Database = Depends(get_db),
    actor: dict = Depends(require_roles("carrier")),
):
    referral = await db.referrals.create({
        **req.model_dump(exclude_none=True), "carrier_id": actor.get("org_id") or actor["id"],
    })
    await write_audit(db, action="referral.create", resource="referral", resource_id=referral["id"],
                detail=f"{referral['provider_name']}->{referral['opc_name']}", user=actor, request=request)
    return referral
