# -*- coding: utf-8 -*-
"""业务层 · 结算/合同/争议/撮合服务。

资金相关规则（佣金、结算、争议联动）在业务层集中，接口层瘦身。
"""
from __future__ import annotations

from fastapi import HTTPException

from ..infrastructure.repositories import Database

# 平台佣金比例
COMMISSION_RATE = 0.05


class SettlementService:
    """结算托管、电子合同、争议、投资撮合。"""

    def __init__(self, db: Database):
        self.db = db

    async def release_escrow(self, task_id: str) -> dict:
        """验收通过后结算：任务须 completed；无托管则兜底创建（佣金 5%）。"""
        task = await self.db.tasks.get(task_id)
        if task is None or task["status"] != "completed":
            raise HTTPException(status_code=400, detail="任务未完成，不能结算")
        escrows = await self.db.escrows.list()
        esc = next((e for e in escrows if e["task_id"] == task_id), None)
        if esc is None:
            amount = max(task.get("budget_min", 0), task.get("budget_max", 0))
            commission = int(amount * COMMISSION_RATE)
            esc = await self.db.escrows.create(task_id, task["title"], amount, commission)
        return await self.db.escrows.set_status(esc["id"], "released")

    async def sign_contract(self, task_id: str, actor: dict, opc_id: str | None = None) -> dict:
        """签订电子合同（幂等：已签返回现有合同）。"""
        task = await self.db.tasks.get(task_id)
        if task is None:
            raise HTTPException(status_code=404, detail="Task not found")
        existing = await self.db.contracts.get_for_task(task_id)
        if existing is not None:
            return existing
        resolved_opc = opc_id or (actor["id"] if actor.get("role") == "opc_member" else "")
        return await self.db.contracts.create(task_id, task["title"], actor["id"], resolved_opc)

    async def create_dispute(self, task_id: str, actor: dict, reason: str) -> dict:
        """发起争议并联动任务置为 disputed。"""
        task = await self.db.tasks.get(task_id)
        if task is None:
            raise HTTPException(status_code=404, detail="Task not found")
        dispute = await self.db.disputes.create(task_id, task["title"], actor["id"], reason)
        await self.db.tasks.set_status(task_id, "disputed")
        return dispute

    async def resolve_dispute(self, dispute_id: str) -> dict:
        dispute = await self.db.disputes.set_status(dispute_id, "resolved", resolution="平台调解结案")
        if dispute is None:
            raise HTTPException(status_code=404, detail="Dispute not found")
        return dispute

    async def investor_matches(self, user_id: str) -> dict:
        """投资撮合：按投资人偏好（行业/阶段关键词）打分排序。"""
        pref = await self.db.investor_prefs.get(user_id) or {}
        industries = set(pref.get("industries") or [])
        data = await self.db.portal_pages.get("investor", "projects") or {"items": []}
        scored = []
        for it in data.get("items", []):
            text = f"{it.get('title', '')} {it.get('meta', '')}"
            score = sum(10 for ind in industries if ind and ind in text)
            if pref.get("stage") and pref["stage"] in text:
                score += 5
            scored.append((score, it))
        scored.sort(key=lambda x: x[0], reverse=True)
        return {"items": [{"title": it["title"], "meta": it["meta"], "tag": it.get("tag"),
                           "match": min(100, s + 50)} for s, it in scored]}
