"""规则引擎 + 每日摘要 + 高级搜索 API"""

import uuid

from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.permissions import get_current_user, require_platform_operator
from app.db import get_db
from app.models.literature import GlobalLiterature
from app.models.user import User
from app.services.daily_digest import send_daily_digest_to_user
from app.services.rule_engine import PRESET_RULES, RuleEngine
from app.services.search_engine import AdvancedSearchEngine

router = APIRouter()


# ─── 预设规则 ───

@router.get("/rules/presets", summary="预设规则")
async def get_preset_rules():
    return {"presets": {k: {"name": v["name"], "rule": v["rule"]} for k, v in PRESET_RULES.items()}}


class TestRuleRequest(BaseModel):
    rule: dict


@router.post("/rules/test", summary="测试规则")
async def test_rule(req: TestRuleRequest, pmid: int = Query(...), db: AsyncSession = Depends(get_db)):
    """测试一条规则是否匹配某篇文献"""
    result = await db.execute(select(GlobalLiterature).where(GlobalLiterature.pmid == pmid))
    lit = result.scalar()
    if not lit:
        raise HTTPException(404)
    matcher = RuleEngine.compile_rule(req.rule)
    matched = matcher({"title": lit.title, "abstract": lit.abstract or "", "journal": lit.journal or ""})
    return {"pmid": pmid, "matched": matched, "title": lit.title[:100]}


# ─── 高级搜索 ───

class AdvancedSearchRequest(BaseModel):
    query: str = ""
    field: str = "all"
    boolean: str = "and"
    exact_phrase: bool = False
    year_from: int | None = None
    year_to: int | None = None
    date_from: str | None = None
    date_to: str | None = None
    journal_tiers: list[str] | None = None
    pub_types: list[str] | None = None
    tag_ids: list[str] | None = None
    retracted: str = ""
    negative_result: str = ""
    page: int = 1
    page_size: int = 20
    sort: str = "date"
    # keyset 游标分页（设了 cursor 后 page 参数被忽略，不做 COUNT）
    cursor_date: str | None = None   # 上一页最后一条的 pub_date（ISO 日期）
    cursor_id: str | None = None     # 上一页最后一条的 id（UUID 字符串）


@router.post("/search/advanced", summary="高级搜索")
async def advanced_search(req: AdvancedSearchRequest, db: AsyncSession = Depends(get_db)):
    try:
        return await AdvancedSearchEngine.search(db, **req.model_dump())
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e)) from e


# ─── 每日摘要 ───

@router.post("/digest/send-now", summary="发送摘要")
async def send_digest_now(db: AsyncSession = Depends(get_db), user: dict = Depends(get_current_user)):
    """立刻给自己发送今日摘要邮件"""
    u = (await db.execute(select(User).where(User.id == uuid.UUID(user["sub"])))).scalar()
    if not u:
        raise HTTPException(404)
    count = await send_daily_digest_to_user(db, str(u.id), u.email, u.display_name)
    return {"status": "sent", "articles": count, "email": u.email}


@router.post("/digest/send-all", summary="批量发送")
async def trigger_all_digests(_op: dict = Depends(require_platform_operator)):
    from app.services.daily_digest import send_all_daily_digests
    stats = await send_all_daily_digests()
    return stats
