"""
微信全量操作路由 — 补全统一路由缺失的端点
==========================================

对齐 agent 端 128 个 RPC 方法，通过 WechatSkillV2 统一分发。
所有操作通过 WiFi Frida 无线执行，无需 USB。

新增端点（统一路由已有的不重复）：
- 视频号操作（6个）
- 小程序操作（3个）
- 收藏管理（3个）
- 公众号操作（4个）
- 账号安全（8个）
- 支付操作（6个）
- 浮窗管理（2个）
- 表情管理（2个）
- 搜索（1个）
- 设备信息（3个）
"""
from __future__ import annotations
import logging
from typing import Optional, List

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel, Field

router = APIRouter(prefix="/wechat", tags=["微信全量操作"])
logger = logging.getLogger(__name__)


# ============================================================
# § 1  请求模型
# ============================================================

class WechatBaseRequest(BaseModel):
    device_id: str
    timeout: int = 30

class WxidRequest(WechatBaseRequest):
    wxid: str

class SearchRequest(WechatBaseRequest):
    keyword: str
    limit: int = 50

class ChannelVideoRequest(WechatBaseRequest):
    video_id: str

class ChannelCommentRequest(WechatBaseRequest):
    video_id: str
    comment: str

class ChannelFollowRequest(WechatBaseRequest):
    channel_id: str

class ShareChannelRequest(WechatBaseRequest):
    video_id: str
    to_id: str

class MiniProgramRequest(WechatBaseRequest):
    app_id: str
    path: str = ""

class ShareMiniProgramRequest(WechatBaseRequest):
    app_id: str
    to_id: str
    title: str = ""

class FavoriteRequest(WechatBaseRequest):
    msg_svr_id: str = ""
    local_id: str = ""
    type: str = "message"

class OfficialAccountRequest(WechatBaseRequest):
    account_id: str

class OfficialAccountArticlesRequest(WechatBaseRequest):
    account_id: str
    limit: int = 10

class PasswordRequest(WechatBaseRequest):
    old_password: str
    new_password: str

class PhoneRequest(WechatBaseRequest):
    phone: str

class DeviceRemoveRequest(WechatBaseRequest):
    target_device_id: str

class ToggleRequest(WechatBaseRequest):
    enable: bool = True

class RedPacketRequest(WechatBaseRequest):
    to_id: str
    amount: str
    message: str = "恭喜发财"

class TransferRequest(WechatBaseRequest):
    to_id: str
    amount: str
    description: str = ""

class ReceiveRequest(WechatBaseRequest):
    msg_svr_id: str

class FloatRequest(WechatBaseRequest):
    wxid: str

class EmojiSendRequest(WechatBaseRequest):
    to_id: str
    emoji_md5: str

class EmojiAddRequest(WechatBaseRequest):
    image_path: str

class ProfileSetRequest(WechatBaseRequest):
    value: str

class PrivacyRequest(WechatBaseRequest):
    setting: str
    value: bool = True

class NotificationRequest(WechatBaseRequest):
    type: str = "all"
    enable: bool = True

class ChatBgRequest(WechatBaseRequest):
    wxid: str
    image_path: str = ""

class DndRequest(WechatBaseRequest):
    wxid: str
    enable: bool = True

class PinChatRequest(WechatBaseRequest):
    wxid: str
    pin: bool = True

class QrScanRequest(WechatBaseRequest):
    image_path: str = ""

class LabelContactRequest(WechatBaseRequest):
    wxid: str
    label_ids: List[str]


# ============================================================
# § 2  辅助函数
# ============================================================

async def _get_skill(device_id: str):
    """获取 WechatSkillV2 实例"""
    from skills.wechat.skill_v2 import WechatSkillV2
    return WechatSkillV2(device_id=device_id)


# ============================================================
# § 3  视频号操作（H27）
# ============================================================

@router.get("/channels/browse", response_model=dict)
async def browse_channels(device_id: str, limit: int = 10):
    """浏览视频号"""
    skill = await _get_skill(device_id)
    return await skill.browse_channels(limit)

@router.post("/channels/like", response_model=dict)
async def like_channel_video(req: ChannelVideoRequest):
    """视频号点赞"""
    skill = await _get_skill(req.device_id)
    return await skill.like_channel_video(req.video_id)

@router.post("/channels/comment", response_model=dict)
async def comment_channel_video(req: ChannelCommentRequest):
    """视频号评论"""
    skill = await _get_skill(req.device_id)
    return await skill.comment_channel_video(req.video_id, req.comment)

@router.post("/channels/follow", response_model=dict)
async def follow_channel(req: ChannelFollowRequest):
    """关注视频号"""
    skill = await _get_skill(req.device_id)
    return await skill.follow_channel(req.channel_id)

@router.post("/channels/unfollow", response_model=dict)
async def unfollow_channel(req: ChannelFollowRequest):
    """取消关注视频号"""
    skill = await _get_skill(req.device_id)
    return await skill.unfollow_channel(req.channel_id)

@router.post("/channels/share", response_model=dict)
async def share_channel_video(req: ShareChannelRequest):
    """分享视频号视频"""
    skill = await _get_skill(req.device_id)
    return await skill.share_channel_video(req.video_id, req.to_id)


# ============================================================
# § 4  小程序操作（H32）
# ============================================================

@router.post("/mini-program/open", response_model=dict)
async def open_mini_program(req: MiniProgramRequest):
    """打开小程序"""
    skill = await _get_skill(req.device_id)
    return await skill.open_mini_program(req.app_id, req.path)

@router.get("/mini-program/recent", response_model=dict)
async def get_recent_mini_programs(device_id: str):
    """获取最近使用的小程序"""
    skill = await _get_skill(device_id)
    return await skill.get_recent_mini_programs()

@router.post("/mini-program/share", response_model=dict)
async def share_mini_program(req: ShareMiniProgramRequest):
    """分享小程序"""
    skill = await _get_skill(req.device_id)
    return await skill.share_mini_program(req.app_id, req.to_id, req.title)


# ============================================================
# § 5  收藏管理（H29）
# ============================================================

@router.get("/favorites", response_model=dict)
async def get_favorites(device_id: str, limit: int = 50):
    """获取收藏列表"""
    skill = await _get_skill(device_id)
    return await skill.get_favorites(limit)

@router.post("/favorites/add", response_model=dict)
async def add_favorite(req: FavoriteRequest):
    """添加收藏"""
    skill = await _get_skill(req.device_id)
    return await skill.add_favorite(req.msg_svr_id, req.type)

@router.delete("/favorites/{local_id}", response_model=dict)
async def delete_favorite(local_id: str, device_id: str = ""):
    """删除收藏"""
    skill = await _get_skill(device_id)
    return await skill.delete_favorite(local_id)


# ============================================================
# § 6  公众号操作（H36）
# ============================================================

@router.get("/official-accounts", response_model=dict)
async def get_official_accounts(device_id: str, limit: int = 100):
    """获取关注的公众号列表"""
    skill = await _get_skill(device_id)
    return await skill.get_official_accounts(limit)

@router.post("/official-accounts/follow", response_model=dict)
async def follow_official_account(req: OfficialAccountRequest):
    """关注公众号"""
    skill = await _get_skill(req.device_id)
    return await skill.follow_official_account(req.account_id)

@router.post("/official-accounts/unfollow", response_model=dict)
async def unfollow_official_account(req: OfficialAccountRequest):
    """取消关注公众号"""
    skill = await _get_skill(req.device_id)
    return await skill.unfollow_official_account(req.account_id)

@router.get("/official-accounts/{account_id}/articles", response_model=dict)
async def get_official_account_articles(account_id: str, device_id: str = "", limit: int = 10):
    """获取公众号文章"""
    skill = await _get_skill(device_id)
    return await skill.get_official_account_articles(account_id, limit)


# ============================================================
# § 7  账号安全（H24）
# ============================================================

@router.post("/security/unblock", response_model=dict)
async def unblock_self(req: WechatBaseRequest):
    """自助解封"""
    skill = await _get_skill(req.device_id)
    return await skill.unblock_self()

@router.post("/security/change-password", response_model=dict)
async def change_password(req: PasswordRequest):
    """修改密码"""
    skill = await _get_skill(req.device_id)
    return await skill.change_password(req.old_password, req.new_password)

@router.post("/security/bind-phone", response_model=dict)
async def bind_phone(req: PhoneRequest):
    """绑定手机号"""
    skill = await _get_skill(req.device_id)
    return await skill.bind_phone(req.phone)

@router.post("/security/unbind-phone", response_model=dict)
async def unbind_phone(req: WechatBaseRequest):
    """解绑手机号"""
    skill = await _get_skill(req.device_id)
    return await skill.unbind_phone()

@router.get("/security/login-devices", response_model=dict)
async def get_login_devices(device_id: str):
    """获取登录设备列表"""
    skill = await _get_skill(device_id)
    return await skill.get_login_devices()

@router.delete("/security/login-device", response_model=dict)
async def remove_login_device(req: DeviceRemoveRequest):
    """移除登录设备"""
    skill = await _get_skill(req.device_id)
    return await skill.remove_login_device(req.target_device_id)

@router.post("/security/fingerprint", response_model=dict)
async def enable_fingerprint(req: ToggleRequest):
    """启用/禁用指纹"""
    skill = await _get_skill(req.device_id)
    return await skill.enable_fingerprint(req.enable)

@router.post("/security/account-protection", response_model=dict)
async def set_account_protection(req: ToggleRequest):
    """设置账号保护"""
    skill = await _get_skill(req.device_id)
    return await skill.set_account_protection(req.enable)


# ============================================================
# § 8  支付操作（H25）
# ============================================================

@router.post("/pay/red-packet", response_model=dict)
async def send_red_packet(req: RedPacketRequest):
    """发红包"""
    skill = await _get_skill(req.device_id)
    return await skill.send_red_packet(req.to_id, req.amount, req.message)

@router.post("/pay/red-packet/receive", response_model=dict)
async def receive_red_packet(req: ReceiveRequest):
    """收红包"""
    skill = await _get_skill(req.device_id)
    return await skill.receive_red_packet(req.msg_svr_id)

@router.post("/pay/transfer", response_model=dict)
async def send_transfer(req: TransferRequest):
    """转账"""
    skill = await _get_skill(req.device_id)
    return await skill.send_transfer(req.to_id, req.amount, req.description)

@router.post("/pay/transfer/receive", response_model=dict)
async def receive_transfer(req: ReceiveRequest):
    """收转账"""
    skill = await _get_skill(req.device_id)
    return await skill.receive_transfer(req.msg_svr_id)

@router.get("/pay/balance", response_model=dict)
async def get_wallet_balance(device_id: str):
    """获取钱包余额"""
    skill = await _get_skill(device_id)
    return await skill.get_wallet_balance()

@router.get("/pay/transactions", response_model=dict)
async def get_transaction_history(device_id: str, limit: int = 20):
    """获取交易记录"""
    skill = await _get_skill(device_id)
    return await skill.get_transaction_history(limit)


# ============================================================
# § 9  浮窗管理（H38）
# ============================================================

@router.post("/float/add", response_model=dict)
async def add_to_float(req: FloatRequest):
    """添加到浮窗"""
    skill = await _get_skill(req.device_id)
    return await skill.add_to_float(req.wxid)

@router.post("/float/remove", response_model=dict)
async def remove_from_float(req: FloatRequest):
    """从浮窗移除"""
    skill = await _get_skill(req.device_id)
    return await skill.remove_from_float(req.wxid)


# ============================================================
# § 10  表情管理（H37）
# ============================================================

@router.post("/emoji/send-custom", response_model=dict)
async def send_emoji_custom(req: EmojiSendRequest):
    """发送自定义表情"""
    skill = await _get_skill(req.device_id)
    return await skill.send_emoji(req.to_id, req.emoji_md5)

@router.post("/emoji/add-custom", response_model=dict)
async def add_custom_emoji(req: EmojiAddRequest):
    """添加自定义表情"""
    skill = await _get_skill(req.device_id)
    return await skill.add_custom_emoji(req.image_path)


# ============================================================
# § 11  账号管理（H23）
# ============================================================

@router.get("/profile", response_model=dict)
async def get_profile(device_id: str):
    """获取个人资料"""
    skill = await _get_skill(device_id)
    return await skill.get_profile()

@router.get("/account/status", response_model=dict)
async def check_account_status(device_id: str):
    """检查账号状态"""
    skill = await _get_skill(device_id)
    return await skill.check_account_status()

@router.post("/profile/nickname", response_model=dict)
async def set_nickname(req: ProfileSetRequest):
    """设置昵称"""
    skill = await _get_skill(req.device_id)
    return await skill.set_nickname(req.value)

@router.post("/profile/signature", response_model=dict)
async def set_signature(req: ProfileSetRequest):
    """设置签名"""
    skill = await _get_skill(req.device_id)
    return await skill.set_signature(req.value)

@router.post("/profile/avatar", response_model=dict)
async def set_avatar(req: ProfileSetRequest):
    """设置头像"""
    skill = await _get_skill(req.device_id)
    return await skill.set_avatar(req.value)

@router.post("/profile/sex", response_model=dict)
async def set_sex(req: ProfileSetRequest):
    """设置性别"""
    skill = await _get_skill(req.device_id)
    return await skill.set_sex(req.value)

@router.post("/profile/region", response_model=dict)
async def set_region(req: ProfileSetRequest):
    """设置地区"""
    skill = await _get_skill(req.device_id)
    return await skill.set_region(req.value)

@router.post("/profile/status", response_model=dict)
async def set_what_up(req: ProfileSetRequest):
    """设置状态"""
    skill = await _get_skill(req.device_id)
    return await skill.set_what_up(req.value)


# ============================================================
# § 12  搜索（H31）
# ============================================================

@router.get("/search", response_model=dict)
async def global_search(device_id: str, keyword: str, limit: int = 30):
    """全局搜索"""
    skill = await _get_skill(device_id)
    return await skill.global_search(keyword, limit)


# ============================================================
# § 13  设置（H30）
# ============================================================

@router.post("/settings/privacy", response_model=dict)
async def set_privacy(req: PrivacyRequest):
    """设置隐私"""
    skill = await _get_skill(req.device_id)
    return await skill.set_privacy(req.setting, req.value)

@router.post("/settings/notification", response_model=dict)
async def set_notification(req: NotificationRequest):
    """设置通知"""
    skill = await _get_skill(req.device_id)
    return await skill.set_notification(req.type, req.enable)

@router.post("/settings/clear-history", response_model=dict)
async def clear_chat_history(req: WxidRequest):
    """清除聊天记录"""
    skill = await _get_skill(req.device_id)
    return await skill.clear_chat_history(req.wxid)

@router.post("/settings/chat-background", response_model=dict)
async def set_chat_background(req: ChatBgRequest):
    """设置聊天背景"""
    skill = await _get_skill(req.device_id)
    return await skill.set_chat_background(req.wxid, req.image_path)

@router.post("/settings/dnd", response_model=dict)
async def set_do_not_disturb(req: DndRequest):
    """设置免打扰"""
    skill = await _get_skill(req.device_id)
    return await skill.set_do_not_disturb(req.wxid, req.enable)

@router.post("/settings/pin-chat", response_model=dict)
async def pin_chat(req: PinChatRequest):
    """置顶聊天"""
    skill = await _get_skill(req.device_id)
    return await skill.pin_chat(req.wxid, req.pin)


# ============================================================
# § 14  二维码（H26）
# ============================================================

@router.post("/qr/scan", response_model=dict)
async def scan_qr_code(req: QrScanRequest):
    """扫描二维码"""
    skill = await _get_skill(req.device_id)
    return await skill.scan_qr_code(req.image_path)

@router.get("/qr/my", response_model=dict)
async def generate_my_qr_code(device_id: str):
    """生成我的二维码"""
    skill = await _get_skill(device_id)
    return await skill.generate_my_qr_code()

@router.get("/qr/group/{group_id}", response_model=dict)
async def generate_group_qr_code(group_id: str, device_id: str = ""):
    """生成群二维码"""
    skill = await _get_skill(device_id)
    return await skill.generate_group_qr_code(group_id)


# ============================================================
# § 15  设备信息（H39）
# ============================================================

@router.get("/device-info", response_model=dict)
async def get_device_info(device_id: str):
    """获取设备信息"""
    skill = await _get_skill(device_id)
    return await skill.get_device_info()

@router.get("/storage-info", response_model=dict)
async def get_storage_info(device_id: str):
    """获取存储信息"""
    skill = await _get_skill(device_id)
    return await skill.get_storage_info()

@router.get("/network-info", response_model=dict)
async def get_network_info(device_id: str):
    """获取网络信息"""
    skill = await _get_skill(device_id)
    return await skill.get_network_info()


# ============================================================
# § 16  标签补全（H28）
# ============================================================

@router.post("/tag/set-contact", response_model=dict)
async def set_contact_label(req: LabelContactRequest):
    """设置联系人标签"""
    skill = await _get_skill(req.device_id)
    return await skill.set_contact_label(req.wxid, req.label_ids)

@router.get("/tag/contacts/{label_id}", response_model=dict)
async def get_contacts_by_label(label_id: str, device_id: str = ""):
    """按标签获取联系人"""
    skill = await _get_skill(device_id)
    return await skill.get_contacts_by_label(label_id)


# ============================================================
# § 17  Hook 状态
# ============================================================

@router.get("/hook/status", response_model=dict)
async def get_hook_status(device_id: str):
    """获取 Hook 状态"""
    skill = await _get_skill(device_id)
    return await skill.get_hook_status()

@router.get("/hook/process-info", response_model=dict)
async def get_process_info(device_id: str):
    """获取微信进程信息"""
    skill = await _get_skill(device_id)
    return await skill.get_process_info()

@router.get("/hook/wechat-version", response_model=dict)
async def get_wechat_version(device_id: str):
    """获取微信版本"""
    skill = await _get_skill(device_id)
    return await skill.get_wechat_version()


# ============================================================
# § 17  矩阵 H40 补全（128 canonical 扩展）
# ============================================================

@router.get("/ping", response_model=dict)
async def ping(device_id: str):
    skill = await _get_skill(device_id)
    return await skill.ping()

@router.get("/safety-center", response_model=dict)
async def get_safety_center(device_id: str):
    skill = await _get_skill(device_id)
    return await skill.get_safety_center()

@router.get("/restrictions", response_model=dict)
async def check_restrictions(device_id: str):
    skill = await _get_skill(device_id)
    return await skill.check_restrictions()

@router.get("/top-stories", response_model=dict)
async def get_top_stories(device_id: str):
    skill = await _get_skill(device_id)
    return await skill.get_top_stories()

@router.get("/steps", response_model=dict)
async def get_wechat_steps(device_id: str):
    skill = await _get_skill(device_id)
    return await skill.get_wechat_steps()

@router.get("/stickers", response_model=dict)
async def get_sticker_list(device_id: str):
    skill = await _get_skill(device_id)
    return await skill.get_sticker_list()

@router.post("/pay/show-code", response_model=dict)
async def show_payment_code(device_id: str):
    skill = await _get_skill(device_id)
    return await skill.show_payment_code()

@router.post("/steps/like", response_model=dict)
async def like_wechat_steps(device_id: str, user_id: str = "filehelper"):
    skill = await _get_skill(device_id)
    return await skill.like_wechat_steps(user_id)

@router.post("/cache/clear", response_model=dict)
async def clear_cache(device_id: str):
    skill = await _get_skill(device_id)
    return await skill.clear_cache()

@router.get("/update/check", response_model=dict)
async def check_for_update(device_id: str):
    skill = await _get_skill(device_id)
    return await skill.check_for_update()

class CallRequest(WechatBaseRequest):
    to_id: str

@router.post("/call/voice", response_model=dict)
async def voice_call(req: CallRequest):
    skill = await _get_skill(req.device_id)
    return await skill.voice_call(req.to_id)

@router.post("/call/video", response_model=dict)
async def video_call(req: CallRequest):
    skill = await _get_skill(req.device_id)
    return await skill.video_call(req.to_id)

@router.post("/location/share-realtime", response_model=dict)
async def share_real_time_location(req: CallRequest):
    skill = await _get_skill(req.device_id)
    return await skill.share_real_time_location(req.to_id)

class DownloadFileRequest(WechatBaseRequest):
    url: str
    save_path: str = "/sdcard/Download/wp_download.bin"

@router.post("/file/download", response_model=dict)
async def download_file(req: DownloadFileRequest):
    skill = await _get_skill(req.device_id)
    return await skill.download_file(req.url, req.save_path)

class MassSendRequest(WechatBaseRequest):
    user_ids: List[str]
    content: str

@router.post("/message/mass-send", response_model=dict)
async def mass_send(req: MassSendRequest):
    skill = await _get_skill(req.device_id)
    return await skill.mass_send(req.user_ids, req.content)

@router.post("/message/batch-send", response_model=dict)
async def batch_send(req: MassSendRequest):
    skill = await _get_skill(req.device_id)
    return await skill.batch_send(req.user_ids, req.content)

class ReplyCommentRequest(WechatBaseRequest):
    sns_id: str
    comment: str

@router.post("/moments/reply-comment", response_model=dict)
async def reply_comment(req: ReplyCommentRequest):
    skill = await _get_skill(req.device_id)
    return await skill.reply_comment(req.sns_id, req.comment)

class ReceivePaymentRequest(WechatBaseRequest):
    msg_svr_id: str

@router.post("/pay/receive", response_model=dict)
async def receive_payment(req: ReceivePaymentRequest):
    skill = await _get_skill(req.device_id)
    return await skill.receive_payment(req.msg_svr_id)


# ============================================================
# § 18  统一执行入口
# ============================================================

class UnifiedExecuteRequest(BaseModel):
    device_id: str
    action: str
    params: dict = Field(default_factory=dict)
    timeout: int = 30

@router.post("/execute", response_model=dict)
async def unified_execute(req: UnifiedExecuteRequest):
    """
    统一执行入口 — 支持所有 128 个微信 canonical action（174 catalog 含 alias）
    
    通过 action 名直接调用对应的 Frida RPC 方法。
    通道自动选择：Hook > WebSocket Agent > UI 自动化
    """
    skill = await _get_skill(req.device_id)
    return await skill.execute(req.action, req.params)

@router.get("/actions", response_model=dict)
async def list_all_actions():
    """列出所有支持的微信操作（128 canonical + 174 catalog）"""
    from skills.wechat.skill_v2 import WECHAT_ACTIONS, MODULES, WechatSkillV2
    catalog = WechatSkillV2.get_catalog_action_list()
    return {
        "success": True,
        "total_actions": len(WECHAT_ACTIONS),
        "catalog_actions": len(catalog),
        "total_modules": len(MODULES),
        "modules": {k: v["name"] for k, v in MODULES.items()},
        "actions": sorted(WECHAT_ACTIONS.keys()),
        "catalog": catalog,
    }
