#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
消息中心 API（异步版本）
"""
from typing import Dict, List, Optional

from fastapi import APIRouter, Depends, HTTPException, Query, Request
from sqlalchemy.ext.asyncio import AsyncSession

from app.database import get_db
from app.base_schema import PaginatedResponse, ResponseModel
from core.message.schema import (
    MessageOut,
    MessageListOut,
    UnreadCountOut,
    MarkReadInput,
    SendMessageInput,
    AnnouncementCreate,
    AnnouncementUpdate,
    AnnouncementOut,
    AnnouncementListOut,
    UserAnnouncementOut,
    ReadStatsOut,
    EmailTestInput,
    EmailSendInput,
    DingTalkWebhookTestInput,
    DingTalkWorkNoticeTestInput,
    DingTalkTodoTestInput,
    DingTalkTodoCompleteInput,
    FeishuWebhookTestInput,
    FeishuAppMessageTestInput,
    WecomWebhookTestInput,
    WecomAppMessageTestInput,
    WechatMPTestInput,
)
from core.message.service import MessageService, AnnouncementService, NotifyService

router = APIRouter(prefix="/message", tags=["消息中心"])


# ============ 消息 API ============

@router.get("/list", response_model=PaginatedResponse[MessageListOut], summary="消息列表")
async def list_messages(
        request: Request,
        msg_type: str = Query(None, description="消息类型"),
        status: str = Query(None, description="状态: unread/read"),
        page: int = Query(default=1, ge=1, description="页码"),
        page_size: int = Query(default=20, ge=1, le=100, alias="pageSize", description="每页数量"),
        db: AsyncSession = Depends(get_db),
):
    """获取当前用户的消息列表"""
    user_id = request.state.user_id
    items, total = await MessageService.get_list(
        db=db,
        user_id=user_id,
        msg_type=msg_type,
        status=status,
        page=page,
        page_size=page_size,
    )

    # 批量获取发送人名称
    sender_ids = list(set(str(item.sender_id) for item in items if item.sender_id))
    sender_names = await _batch_get_user_names(db, sender_ids) if sender_ids else {}

    return PaginatedResponse(
        items=[
            _build_message_list_out(item, sender_names.get(str(item.sender_id), "") if item.sender_id else "")
            for item in items
        ],
        total=total,
    )


@router.get("/unread-count", response_model=UnreadCountOut, summary="未读数量")
async def get_unread_count(
        request: Request,
        db: AsyncSession = Depends(get_db),
):
    """获取未读消息数量"""
    user_id = request.state.user_id
    total = await MessageService.get_unread_count(db, user_id)
    by_type = await MessageService.get_unread_count_by_type(db, user_id)

    return UnreadCountOut(total=total, by_type=by_type)


@router.post("/read-all", response_model=ResponseModel, summary="全部已读")
async def mark_all_as_read(
        request: Request,
        data: MarkReadInput = None,
        db: AsyncSession = Depends(get_db),
):
    """标记所有消息为已读"""
    user_id = request.state.user_id
    msg_type = data.msg_type if data else None
    count = await MessageService.mark_all_as_read(db, user_id, msg_type)

    return ResponseModel(message=f"已标记 {count} 条消息为已读")


@router.delete("/clear-read", response_model=ResponseModel, summary="清空已读")
async def clear_read_messages(
        request: Request,
        db: AsyncSession = Depends(get_db),
):
    """清空所有已读消息"""
    user_id = request.state.user_id
    count = await MessageService.delete_all_read(db, user_id)

    return ResponseModel(message=f"已删除 {count} 条已读消息")


@router.get("/{message_id}", response_model=MessageOut, summary="消息详情")
async def get_message(
        request: Request,
        message_id: str,
        db: AsyncSession = Depends(get_db),
):
    """获取消息详情"""
    user_id = request.state.user_id
    message = await MessageService.get_by_id(db, message_id, user_id)
    if not message:
        raise HTTPException(status_code=404, detail="消息不存在")

    return await _build_message_out(db, message)


@router.post("/{message_id}/read", response_model=ResponseModel, summary="标记已读")
async def mark_as_read(
        request: Request,
        message_id: str,
        db: AsyncSession = Depends(get_db),
):
    """标记单条消息为已读"""
    user_id = request.state.user_id
    success = await MessageService.mark_as_read(db, message_id, user_id)
    if not success:
        raise HTTPException(status_code=404, detail="消息不存在")

    return ResponseModel(message="已标记为已读")


@router.delete("/{message_id}", response_model=ResponseModel, summary="删除消息")
async def delete_message(
        request: Request,
        message_id: str,
        db: AsyncSession = Depends(get_db),
):
    """删除单条消息"""
    user_id = request.state.user_id
    success = await MessageService.delete(db, message_id, user_id)
    if not success:
        raise HTTPException(status_code=404, detail="消息不存在")

    return ResponseModel(message="删除成功")


@router.post("/send", response_model=ResponseModel, summary="发送消息")
async def send_message(
        request: Request,
        data: SendMessageInput,
        db: AsyncSession = Depends(get_db),
):
    """发送站内消息（支持多渠道）"""
    sender_id = request.state.user_id

    if not data.recipient_ids:
        raise HTTPException(status_code=400, detail="接收人不能为空")
    if not data.title.strip():
        raise HTTPException(status_code=400, detail="消息标题不能为空")
    if not data.content.strip():
        raise HTTPException(status_code=400, detail="消息内容不能为空")

    results = await NotifyService.send(
        db=db,
        recipient_ids=data.recipient_ids,
        title=data.title,
        content=data.content,
        channels=data.channels,
        msg_type=data.msg_type,
        sender_id=sender_id,
    )

    return ResponseModel(
        message=f"消息已发送给 {len(data.recipient_ids)} 人",
        data={"results": results, "recipient_count": len(data.recipient_ids)},
    )


# ============ 公告管理端 API ============

announcement_router = APIRouter(prefix="/announcement", tags=["公告管理"])


@announcement_router.get("/admin/list", response_model=PaginatedResponse[AnnouncementListOut], summary="公告列表（管理）")
async def list_announcements(
        status: str = Query(None, description="状态: draft/published/expired"),
        keyword: str = Query(None, description="关键词搜索"),
        page: int = Query(default=1, ge=1, description="页码"),
        page_size: int = Query(default=20, ge=1, le=100, alias="pageSize", description="每页数量"),
        db: AsyncSession = Depends(get_db),
):
    """获取公告列表（管理端）"""
    items, total = await AnnouncementService.get_list(
        db=db,
        page=page,
        page_size=page_size,
        status=status,
        keyword=keyword,
    )

    # 批量查询发布人名称
    publisher_names = await _batch_get_user_names(db, [a.publisher_id for a in items if a.publisher_id])

    return PaginatedResponse(
        items=[_build_announcement_list_out(item, publisher_names) for item in items],
        total=total,
    )


@announcement_router.get("/admin/{announcement_id}", response_model=AnnouncementOut, summary="公告详情（管理）")
async def get_announcement(
        announcement_id: str,
        db: AsyncSession = Depends(get_db),
):
    """获取公告详情"""
    announcement = await AnnouncementService.get_by_id(db, announcement_id)
    if not announcement:
        raise HTTPException(status_code=404, detail="公告不存在")

    return await _build_announcement_out(db, announcement)


@announcement_router.post("/admin", response_model=AnnouncementOut, summary="创建公告")
async def create_announcement(
        request: Request,
        data: AnnouncementCreate,
        db: AsyncSession = Depends(get_db),
):
    """创建公告"""
    user_id = request.state.user_id
    announcement = await AnnouncementService.create(db, data.model_dump(), user_id)
    return await _build_announcement_out(db, announcement)


@announcement_router.put("/admin/{announcement_id}", response_model=AnnouncementOut, summary="更新公告")
async def update_announcement(
        request: Request,
        announcement_id: str,
        data: AnnouncementUpdate,
        db: AsyncSession = Depends(get_db),
):
    """更新公告"""
    user_id = request.state.user_id
    announcement = await AnnouncementService.update(
        db, announcement_id, data.model_dump(exclude_unset=True), user_id
    )
    if not announcement:
        raise HTTPException(status_code=404, detail="公告不存在")

    return await _build_announcement_out(db, announcement)


@announcement_router.delete("/admin/{announcement_id}", response_model=ResponseModel, summary="删除公告")
async def delete_announcement(
        request: Request,
        announcement_id: str,
        db: AsyncSession = Depends(get_db),
):
    """删除公告"""
    user_id = request.state.user_id
    success = await AnnouncementService.delete(db, announcement_id, user_id)
    if not success:
        raise HTTPException(status_code=404, detail="公告不存在")

    return ResponseModel(message="删除成功")


@announcement_router.post("/admin/{announcement_id}/publish", response_model=AnnouncementOut, summary="发布公告")
async def publish_announcement(
        request: Request,
        announcement_id: str,
        db: AsyncSession = Depends(get_db),
):
    """发布公告"""
    user_id = request.state.user_id
    try:
        announcement = await AnnouncementService.publish(db, announcement_id, user_id)
        if not announcement:
            raise HTTPException(status_code=404, detail="公告不存在")
        return await _build_announcement_out(db, announcement)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@announcement_router.get("/admin/{announcement_id}/stats", response_model=ReadStatsOut, summary="阅读统计")
async def get_read_stats(
        announcement_id: str,
        db: AsyncSession = Depends(get_db),
):
    """获取公告阅读统计"""
    stats = await AnnouncementService.get_read_stats(db, announcement_id)
    if not stats:
        raise HTTPException(status_code=404, detail="公告不存在")

    return ReadStatsOut(**stats)


# ============ 公告用户端 API ============

@announcement_router.get("/user/list", response_model=PaginatedResponse[UserAnnouncementOut], summary="我的公告")
async def list_user_announcements(
        request: Request,
        unread_only: bool = Query(False, description="只看未读"),
        page: int = Query(default=1, ge=1, description="页码"),
        page_size: int = Query(default=20, ge=1, le=100, alias="pageSize", description="每页数量"),
        db: AsyncSession = Depends(get_db),
):
    """获取当前用户可见的公告列表"""
    user_id = request.state.user_id
    # 从token中获取用户的部门和角色信息
    user_dept_ids = []
    user_role_ids = []
    if hasattr(request.state, 'token_payload'):
        payload = request.state.token_payload
        if payload.get('dept_id'):
            user_dept_ids = [payload.get('dept_id')]
        if payload.get('role_id'):
            user_role_ids = [payload.get('role_id')]

    items, total = await AnnouncementService.get_user_announcements(
        db=db,
        user_id=user_id,
        user_dept_ids=user_dept_ids,
        user_role_ids=user_role_ids,
        page=page,
        page_size=page_size,
        unread_only=unread_only,
    )

    # 批量查询发布人名称
    publisher_names = await _batch_get_user_names(db, [a.publisher_id for a in items if a.publisher_id])

    return PaginatedResponse(
        items=[_build_user_announcement_out(item, publisher_names) for item in items],
        total=total,
    )


@announcement_router.get("/user/unread-count", response_model=dict, summary="未读公告数量")
async def get_user_unread_count(
        request: Request,
        db: AsyncSession = Depends(get_db),
):
    """获取未读公告数量"""
    user_id = request.state.user_id
    user_dept_ids = []
    user_role_ids = []
    if hasattr(request.state, 'token_payload'):
        payload = request.state.token_payload
        if payload.get('dept_id'):
            user_dept_ids = [payload.get('dept_id')]
        if payload.get('role_id'):
            user_role_ids = [payload.get('role_id')]

    count = await AnnouncementService.get_unread_count(
        db, user_id, user_dept_ids, user_role_ids
    )
    return {"count": count}


@announcement_router.get("/user/{announcement_id}", response_model=UserAnnouncementOut, summary="公告详情")
async def get_user_announcement(
        request: Request,
        announcement_id: str,
        db: AsyncSession = Depends(get_db),
):
    """获取公告详情并标记已读"""
    user_id = request.state.user_id
    announcement = await AnnouncementService.get_by_id(db, announcement_id)
    if not announcement:
        raise HTTPException(status_code=404, detail="公告不存在")

    # 标记已读
    await AnnouncementService.mark_as_read(db, announcement_id, user_id)

    # 重新获取以更新is_read状态
    announcement.is_read = True

    publisher_names = await _batch_get_user_names(db, [announcement.publisher_id] if announcement.publisher_id else [])
    return _build_user_announcement_out(announcement, publisher_names)


@announcement_router.post("/user/{announcement_id}/read", response_model=ResponseModel, summary="标记已读")
async def mark_announcement_as_read(
        request: Request,
        announcement_id: str,
        db: AsyncSession = Depends(get_db),
):
    """标记公告为已读"""
    user_id = request.state.user_id
    success = await AnnouncementService.mark_as_read(db, announcement_id, user_id)
    if not success:
        raise HTTPException(status_code=404, detail="公告不存在")

    return ResponseModel(message="已标记为已读")


# ============ 辅助函数 ============

async def _batch_get_user_names(db: AsyncSession, user_ids: list) -> Dict[str, str]:
    """批量查询用户名称，返回 {user_id: name} 映射"""
    if not user_ids:
        return {}
    from core.user.model import User
    from sqlalchemy import select
    unique_ids = list(set(str(uid) for uid in user_ids))
    stmt = select(User.id, User.name).where(User.id.in_(unique_ids))
    result = await db.execute(stmt)
    return {str(row[0]): row[1] or "" for row in result.all()}


async def _build_message_out(db: AsyncSession, message) -> dict:
    """构建消息详情输出"""
    sender_name = ""
    if message.sender_id:
        sender_names = await _batch_get_user_names(db, [message.sender_id])
        sender_name = sender_names.get(str(message.sender_id), "")

    return {
        "id": str(message.id),
        "title": message.title,
        "content": message.content,
        "msg_type": message.msg_type,
        "status": message.status,
        "link_type": message.link_type or "",
        "link_id": message.link_id or "",
        "sender_name": sender_name,
        "read_at": message.read_at,
        "created_at": message.sys_create_datetime,
    }


def _build_message_list_out(message, sender_name: str = "") -> dict:
    """构建消息列表输出"""
    return {
        "id": str(message.id),
        "title": message.title,
        "content": message.content[:100] if message.content else "",
        "msg_type": message.msg_type,
        "status": message.status,
        "link_type": message.link_type or "",
        "link_id": message.link_id or "",
        "sender_id": str(message.sender_id) if message.sender_id else None,
        "sender_name": sender_name,
        "created_at": message.sys_create_datetime,
    }


async def _build_announcement_out(db: AsyncSession, announcement) -> dict:
    """构建公告输出"""
    publisher_name = ""
    if announcement.publisher_id:
        from core.user.model import User
        from sqlalchemy import select
        stmt = select(User).where(User.id == announcement.publisher_id)
        result = await db.execute(stmt)
        publisher = result.scalar_one_or_none()
        if publisher:
            publisher_name = publisher.name or ""

    return {
        "id": str(announcement.id),
        "title": announcement.title,
        "content": announcement.content,
        "summary": announcement.summary or "",
        "status": announcement.status,
        "priority": announcement.priority,
        "is_top": announcement.is_top,
        "target_type": announcement.target_type,
        "target_ids": announcement.target_ids or [],
        "publish_time": announcement.publish_time,
        "expire_time": announcement.expire_time,
        "publisher_id": str(announcement.publisher_id) if announcement.publisher_id else None,
        "publisher_name": publisher_name,
        "read_count": announcement.read_count or 0,
        "created_at": announcement.sys_create_datetime,
    }


def _build_announcement_list_out(announcement, publisher_names: Dict[str, str] = None) -> dict:
    """构建公告列表输出"""
    publisher_name = ""
    if publisher_names and announcement.publisher_id:
        publisher_name = publisher_names.get(str(announcement.publisher_id), "")
    return {
        "id": str(announcement.id),
        "title": announcement.title,
        "summary": announcement.summary or "",
        "status": announcement.status,
        "priority": announcement.priority,
        "is_top": announcement.is_top,
        "target_type": announcement.target_type,
        "publisher_name": publisher_name,
        "read_count": announcement.read_count or 0,
        "publish_time": announcement.publish_time,
        "created_at": announcement.sys_create_datetime,
    }


def _build_user_announcement_out(announcement, publisher_names: Dict[str, str] = None) -> dict:
    """构建用户公告输出"""
    publisher_name = ""
    if publisher_names and announcement.publisher_id:
        publisher_name = publisher_names.get(str(announcement.publisher_id), "")
    return {
        "id": str(announcement.id),
        "title": announcement.title,
        "summary": announcement.summary or "",
        "content": announcement.content,
        "priority": announcement.priority,
        "is_top": announcement.is_top,
        "is_read": getattr(announcement, "is_read", False),
        "publisher_name": publisher_name,
        "publish_time": announcement.publish_time,
    }


# ============ 邮件 API ============

@router.get("/email/status", response_model=ResponseModel, summary="邮件配置状态")
async def email_status():
    """查看 SMTP 邮件配置状态（通过 config_manager 三级获取）"""
    from app.email import EmailSender

    config = await EmailSender._get_smtp_config()
    configured = bool(config["host"] and config["user"] and config["password"])
    return ResponseModel(
        message="SMTP 已配置" if configured else "SMTP 未配置",
        data={
            "configured": configured,
            "smtp_host": config["host"] or "",
            "smtp_port": config["port"],
            "smtp_user": config["user"][:3] + "***" if config["user"] else "",
            "smtp_use_tls": config["use_tls"],
            "from_name": config["from_name"] or "",
            "from_email": config["from_email"] or "",
        },
    )


@router.post("/email/test", response_model=ResponseModel, summary="测试邮件发送")
async def email_test(data: EmailTestInput):
    """发送测试邮件以验证 SMTP 配置"""
    from app.email import EmailSender

    if not await EmailSender.is_configured_async():
        raise HTTPException(status_code=400, detail="SMTP 未配置，请先在系统配置中配置邮箱相关参数")

    html_content = EmailSender.build_notification_html(
        title="测试邮件",
        content="这是一封测试邮件，用于验证 SMTP 配置是否正确。如果您收到了这封邮件，说明邮件推送功能已正常工作。",
    )
    success = await EmailSender.send(
        to_email=data.to_email,
        subject="[测试] 邮件推送配置验证",
        content=html_content,
        html=True,
    )

    if not success:
        raise HTTPException(status_code=500, detail="邮件发送失败，请检查 SMTP 配置")

    return ResponseModel(message="测试邮件发送成功")


@router.post("/email/send", response_model=ResponseModel, summary="发送邮件通知")
async def email_send(data: EmailSendInput, db: AsyncSession = Depends(get_db)):
    """手动向指定用户发送邮件通知"""
    from core.message.service import NotifyService

    result = await NotifyService._send_email(
        db=db,
        recipient_ids=data.recipient_ids,
        title=data.title,
        content=data.content,
    )

    return ResponseModel(
        message="邮件发送成功" if result else "部分或全部邮件发送失败",
        data={"success": result},
    )


# ============ 钉钉通知 API ============

@router.get("/dingtalk/status", response_model=ResponseModel, summary="钉钉通知配置状态")
async def dingtalk_status():
    """查看钉钉通知配置状态（通过 config_manager 三级获取）"""
    from app.dingtalk import DingTalkWebhook, DingTalkWorkNotice
    from app.config_manager import config_manager

    notify_config = await config_manager.get_group("notify_dingtalk")
    oauth_config = await config_manager.get_group("oauth_dingtalk")

    webhook_url = notify_config.get("webhook_url") or ""
    webhook_secret = notify_config.get("webhook_secret") or ""
    agent_id = notify_config.get("agent_id") or ""
    app_id = oauth_config.get("app_id") or ""
    app_secret = oauth_config.get("app_secret") or ""

    return ResponseModel(
        message="钉钉通知配置状态",
        data={
            "webhook": {
                "configured": bool(webhook_url),
                "url": (webhook_url[:30] + "***") if webhook_url else "",
                "has_secret": bool(webhook_secret),
            },
            "work_notice": {
                "configured": bool(app_id and app_secret and agent_id),
                "agent_id": agent_id,
                "app_id": (app_id[:4] + "***") if app_id else "",
            },
        },
    )


@router.post("/dingtalk/webhook/test", response_model=ResponseModel, summary="测试钉钉 Webhook")
async def dingtalk_webhook_test(data: DingTalkWebhookTestInput):
    """发送测试消息到钉钉群机器人"""
    from app.dingtalk import DingTalkWebhook

    if not await DingTalkWebhook.is_configured_async():
        raise HTTPException(status_code=400, detail="钉钉 Webhook 未配置")

    success = await DingTalkWebhook.send_text(content=f"[测试] {data.content}")
    if not success:
        raise HTTPException(status_code=500, detail="钉钉 Webhook 发送失败")

    return ResponseModel(message="钉钉 Webhook 测试消息发送成功")


@router.post("/dingtalk/work-notice/test", response_model=ResponseModel, summary="测试钉钉工作通知")
async def dingtalk_work_notice_test(data: DingTalkWorkNoticeTestInput, db: AsyncSession = Depends(get_db)):
    """发送测试工作通知到指定用户"""
    from app.dingtalk import DingTalkWorkNotice
    from core.message.service import NotifyService

    if not await DingTalkWorkNotice.is_configured_async():
        raise HTTPException(status_code=400, detail="钉钉工作通知未配置，需要配置钉钉 OAuth 应用及 agent_id")

    # 查询用户的钉钉 unionId
    from core.user.model import User
    from sqlalchemy import select
    stmt = select(User.dingtalk_unionid, User.name).where(User.id == data.user_id)
    result = await db.execute(stmt)
    row = result.first()

    if not row or not row[0]:
        raise HTTPException(status_code=400, detail="该用户未绑定钉钉账号")

    # unionId 转 userId
    user_ids = await NotifyService._convert_dingtalk_unionids([row[0]])
    if not user_ids:
        raise HTTPException(status_code=500, detail="钉钉 unionId 转 userId 失败")

    success = await DingTalkWorkNotice.send_text(
        userid_list=user_ids,
        content=f"[测试] 这是一条发送给 {row[1] or '用户'} 的测试工作通知",
    )
    if not success:
        raise HTTPException(status_code=500, detail="钉钉工作通知发送失败")

    return ResponseModel(message="钉钉工作通知测试发送成功")


# ============ 钉钉待办 API ============

@router.get("/dingtalk-todo/status", response_model=ResponseModel, summary="钉钉待办配置状态")
async def dingtalk_todo_status():
    """查看钉钉待办配置状态"""
    from app.dingtalk import DingTalkTodo
    from app.config_manager import config_manager

    configured = await DingTalkTodo.is_configured_async()
    notify_config = await config_manager.get_group("notify_dingtalk")

    return ResponseModel(
        message="钉钉待办配置状态",
        data={
            "configured": configured,
            "todo_pc_url": notify_config.get("todo_pc_url") or "",
            "todo_app_url": notify_config.get("todo_app_url") or "",
        },
    )


@router.post("/dingtalk-todo/test", response_model=ResponseModel, summary="测试钉钉待办")
async def dingtalk_todo_test(data: DingTalkTodoTestInput, db: AsyncSession = Depends(get_db)):
    """创建一条测试钉钉待办"""
    from app.dingtalk import DingTalkTodo

    if not await DingTalkTodo.is_configured_async():
        raise HTTPException(status_code=400, detail="钉钉待办未配置，需要配置钉钉 OAuth 应用（app_id/app_secret）")

    from core.user.model import User
    from sqlalchemy import select
    stmt = select(User.dingtalk_unionid, User.name).where(User.id == data.user_id)
    result = await db.execute(stmt)
    row = result.first()

    if not row or not row[0]:
        raise HTTPException(status_code=400, detail="该用户未绑定钉钉账号")

    task_id = await DingTalkTodo.create_todo(
        union_id=row[0],
        subject=data.title,
        description=data.content,
        executor_ids=[row[0]],
        priority=20,
    )

    if not task_id:
        raise HTTPException(status_code=500, detail="钉钉待办创建失败")

    return ResponseModel(
        message="钉钉待办测试创建成功",
        data={"task_id": task_id},
    )


@router.post("/dingtalk-todo/complete", response_model=ResponseModel, summary="完成钉钉待办")
async def dingtalk_todo_complete(data: DingTalkTodoCompleteInput, db: AsyncSession = Depends(get_db)):
    """完成指定业务来源的钉钉待办"""
    completed = await NotifyService.complete_dingtalk_todo(
        db=db,
        source_type=data.source_type,
        source_id=data.source_id,
    )

    return ResponseModel(
        message=f"已完成 {completed} 条钉钉待办",
        data={"completed_count": completed},
    )


# ============ 飞书通知 API ============

@router.get("/feishu/status", response_model=ResponseModel, summary="飞书通知配置状态")
async def feishu_status():
    """查看飞书通知配置状态（通过 config_manager 三级获取）"""
    from app.config_manager import config_manager

    notify_config = await config_manager.get_group("notify_feishu")
    oauth_config = await config_manager.get_group("oauth_feishu")

    webhook_url = notify_config.get("webhook_url") or ""
    webhook_secret = notify_config.get("webhook_secret") or ""
    app_id = oauth_config.get("app_id") or ""
    app_secret = oauth_config.get("app_secret") or ""

    return ResponseModel(
        message="飞书通知配置状态",
        data={
            "webhook": {
                "configured": bool(webhook_url),
                "url": (webhook_url[:30] + "***") if webhook_url else "",
                "has_secret": bool(webhook_secret),
            },
            "app_message": {
                "configured": bool(app_id and app_secret),
                "app_id": (app_id[:4] + "***") if app_id else "",
            },
        },
    )


@router.post("/feishu/webhook/test", response_model=ResponseModel, summary="测试飞书 Webhook")
async def feishu_webhook_test(data: FeishuWebhookTestInput):
    """发送测试消息到飞书群机器人"""
    from app.feishu import FeishuWebhook

    if not await FeishuWebhook.is_configured_async():
        raise HTTPException(status_code=400, detail="飞书 Webhook 未配置")

    success = await FeishuWebhook.send_text(text=f"[测试] {data.content}")
    if not success:
        raise HTTPException(status_code=500, detail="飞书 Webhook 发送失败")

    return ResponseModel(message="飞书 Webhook 测试消息发送成功")


@router.post("/feishu/app-message/test", response_model=ResponseModel, summary="测试飞书应用消息")
async def feishu_app_message_test(data: FeishuAppMessageTestInput, db: AsyncSession = Depends(get_db)):
    """发送测试应用消息到指定用户"""
    from app.feishu import FeishuAppMessage

    if not await FeishuAppMessage.is_configured_async():
        raise HTTPException(status_code=400, detail="飞书应用消息未配置，需要配置飞书 OAuth 应用")

    # 查询用户的飞书 union_id
    from core.user.model import User
    from sqlalchemy import select
    stmt = select(User.feishu_union_id, User.name).where(User.id == data.user_id)
    result = await db.execute(stmt)
    row = result.first()

    if not row or not row[0]:
        raise HTTPException(status_code=400, detail="该用户未绑定飞书账号")

    # union_id 转 open_id
    id_map = await FeishuAppMessage.get_open_ids_by_union_ids([row[0]])
    open_id = id_map.get(row[0])
    if not open_id:
        raise HTTPException(status_code=500, detail="飞书 union_id 转 open_id 失败")

    success = await FeishuAppMessage.send_text(
        open_id=open_id,
        text=f"[测试] 这是一条发送给 {row[1] or '用户'} 的测试消息",
    )
    if not success:
        raise HTTPException(status_code=500, detail="飞书应用消息发送失败")

    return ResponseModel(message="飞书应用消息测试发送成功")


# ============ 企业微信通知 API ============

@router.get("/wecom/status", response_model=ResponseModel, summary="企业微信通知配置状态")
async def wecom_status():
    """查看企业微信通知配置状态（通过 config_manager 三级获取）"""
    from app.config_manager import config_manager

    notify_config = await config_manager.get_group("notify_wecom")
    oauth_config = await config_manager.get_group("oauth_wecom")

    webhook_url = notify_config.get("webhook_url") or ""
    corp_id = oauth_config.get("corp_id") or ""
    agent_id = oauth_config.get("agent_id") or ""
    app_secret = oauth_config.get("app_secret") or ""

    return ResponseModel(
        message="企业微信通知配置状态",
        data={
            "webhook": {
                "configured": bool(webhook_url),
                "url": (webhook_url[:30] + "***") if webhook_url else "",
            },
            "app_message": {
                "configured": bool(corp_id and app_secret and agent_id),
                "corp_id": (corp_id[:4] + "***") if corp_id else "",
                "agent_id": agent_id,
            },
        },
    )


@router.post("/wecom/webhook/test", response_model=ResponseModel, summary="测试企业微信 Webhook")
async def wecom_webhook_test(data: WecomWebhookTestInput):
    """发送测试消息到企业微信群机器人"""
    from app.wecom import WecomWebhook

    if not await WecomWebhook.is_configured_async():
        raise HTTPException(status_code=400, detail="企业微信 Webhook 未配置")

    success = await WecomWebhook.send_text(content=f"[测试] {data.content}")
    if not success:
        raise HTTPException(status_code=500, detail="企业微信 Webhook 发送失败")

    return ResponseModel(message="企业微信 Webhook 测试消息发送成功")


@router.post("/wecom/app-message/test", response_model=ResponseModel, summary="测试企业微信应用消息")
async def wecom_app_message_test(data: WecomAppMessageTestInput, db: AsyncSession = Depends(get_db)):
    """发送测试应用消息到指定用户"""
    from app.wecom import WecomAppMessage

    if not await WecomAppMessage.is_configured_async():
        raise HTTPException(status_code=400, detail="企业微信应用消息未配置，需要配置企业微信 OAuth 应用")

    # 查询用户的企业微信 userid
    from core.user.model import User
    from sqlalchemy import select
    stmt = select(User.wecom_userid, User.name).where(User.id == data.user_id)
    result = await db.execute(stmt)
    row = result.first()

    if not row or not row[0]:
        raise HTTPException(status_code=400, detail="该用户未绑定企业微信账号")

    success = await WecomAppMessage.send_text(
        userid_list=[row[0]],
        content=f"[测试] 这是一条发送给 {row[1] or '用户'} 的测试消息",
    )
    if not success:
        raise HTTPException(status_code=500, detail="企业微信应用消息发送失败")

    return ResponseModel(message="企业微信应用消息测试发送成功")


# ============ 微信公众号模板消息 API ============

@router.get("/wechat-mp/status", response_model=ResponseModel, summary="微信公众号通知配置状态")
async def wechat_mp_status():
    """查看微信公众号模板消息配置状态（通过 config_manager 三级获取）"""
    from app.config_manager import config_manager

    oauth_config = await config_manager.get_group("oauth_wechat")
    mp_config = await config_manager.get_group("notify_wechat_mp")

    app_id = oauth_config.get("app_id") or ""
    app_secret = oauth_config.get("app_secret") or ""
    template_id = mp_config.get("template_id") or ""
    mp_url = mp_config.get("url") or ""
    mini_appid = mp_config.get("mini_appid") or ""

    return ResponseModel(
        message="微信公众号通知配置状态",
        data={
            "configured": bool(app_id and app_secret and template_id),
            "app_id": (app_id[:4] + "***") if app_id else "",
            "template_id": (template_id[:8] + "***") if template_id else "",
            "has_url": bool(mp_url),
            "has_miniprogram": bool(mini_appid),
        },
    )


@router.post("/wechat-mp/test", response_model=ResponseModel, summary="测试微信公众号模板消息")
async def wechat_mp_test(data: WechatMPTestInput, db: AsyncSession = Depends(get_db)):
    """发送测试模板消息到指定用户"""
    from app.wechat import WechatMPMessage

    if not await WechatMPMessage.is_configured_async():
        raise HTTPException(status_code=400, detail="微信公众号模板消息未配置，需要配置微信 OAuth 应用及模板 ID")

    # 查询用户的微信 openid
    from core.user.model import User
    from sqlalchemy import select
    stmt = select(User.wechat_openid, User.name).where(User.id == data.user_id)
    result = await db.execute(stmt)
    row = result.first()

    if not row or not row[0]:
        raise HTTPException(status_code=400, detail="该用户未绑定微信账号")

    success = await WechatMPMessage.send_notification(
        openid=row[0],
        title="测试通知",
        content=f"这是一条发送给 {row[1] or '用户'} 的测试模板消息",
        remark="如果您收到此消息，说明微信公众号通知配置正确",
    )
    if not success:
        raise HTTPException(status_code=500, detail="微信模板消息发送失败")

    return ResponseModel(message="微信公众号模板消息测试发送成功")
