import json
import logging
import os
from pathlib import Path
from typing import Any, Dict, List

from utils.metrics_tracker import emit as metrics_emit

logger = logging.getLogger("cs_agent")


def load_system_inquiry_rules() -> Dict[str, Any]:
    """加载系统客服询单规则（全局 + 店铺覆盖）。"""
    from config.config import (
        SYSTEM_INQUIRY_ENABLED,
        SYSTEM_INQUIRY_DEFAULT_ACTION,
        SYSTEM_INQUIRY_DEFAULT_REPLY,
        SYSTEM_INQUIRY_RULES_FILE,
    )

    enabled_env = os.getenv("SYSTEM_INQUIRY_ENABLED")
    enabled = (
        enabled_env.lower() in ("1", "true", "yes")
        if isinstance(enabled_env, str)
        else bool(SYSTEM_INQUIRY_ENABLED)
    )
    action = (os.getenv("SYSTEM_INQUIRY_DEFAULT_ACTION") or SYSTEM_INQUIRY_DEFAULT_ACTION or "silent").strip().lower()
    reply = os.getenv("SYSTEM_INQUIRY_DEFAULT_REPLY") or SYSTEM_INQUIRY_DEFAULT_REPLY or ""
    rules_file = os.getenv("SYSTEM_INQUIRY_RULES_FILE") or str(SYSTEM_INQUIRY_RULES_FILE)
    defaults: Dict[str, Any] = {
        "enabled": bool(enabled),
        "default_action": action,
        "default_reply": reply,
        "sender_keywords": ["系统客服", "官方客服", "平台客服", "机器人客服", "商家客服系统"],
        "message_keywords": ["系统询单", "代客咨询", "平台代问", "系统代发", "客服询单"],
        "shops": {},
    }
    try:
        p = Path(rules_file)
        if p.exists():
            with p.open("r", encoding="utf-8") as f:
                loaded = json.load(f)
            if isinstance(loaded, dict):
                defaults.update(loaded)
    except Exception as e:
        logger.warning("系统询单规则加载失败，使用默认规则: %s", e)
    return defaults


def normalize_kw_list(v: Any) -> List[str]:
    if not isinstance(v, list):
        return []
    return [str(x).strip().lower() for x in v if str(x).strip()]


def resolve_system_inquiry_policy(client, acc_id: str) -> Dict[str, Any]:
    """根据店铺合并系统询单策略。"""
    from config.config import SYSTEM_INQUIRY_SHOPS

    rules = client._system_inquiry_rules or {}
    if not bool(rules.get("enabled", True)):
        return {"enabled": False}

    shops_env = os.getenv("SYSTEM_INQUIRY_SHOPS", SYSTEM_INQUIRY_SHOPS or "")
    shop_whitelist = [s.strip() for s in shops_env.split(",") if s.strip()]
    if shop_whitelist and (acc_id or "") not in shop_whitelist:
        return {"enabled": False}

    policy: Dict[str, Any] = {
        "enabled": True,
        "action": str(rules.get("default_action", "silent")).strip().lower(),
        "reply": str(rules.get("default_reply", "")).strip(),
        "sender_keywords": normalize_kw_list(rules.get("sender_keywords")),
        "message_keywords": normalize_kw_list(rules.get("message_keywords")),
    }
    shop_cfg = (rules.get("shops") or {}).get(acc_id or "", {})
    if isinstance(shop_cfg, dict):
        if "enabled" in shop_cfg and not bool(shop_cfg.get("enabled", True)):
            return {"enabled": False}
        if shop_cfg.get("action"):
            policy["action"] = str(shop_cfg.get("action")).strip().lower()
        if shop_cfg.get("reply"):
            policy["reply"] = str(shop_cfg.get("reply")).strip()
        if isinstance(shop_cfg.get("sender_keywords"), list):
            policy["sender_keywords"] = normalize_kw_list(shop_cfg.get("sender_keywords"))
        if isinstance(shop_cfg.get("message_keywords"), list):
            policy["message_keywords"] = normalize_kw_list(shop_cfg.get("message_keywords"))
    if policy["action"] not in ("silent", "reply", "transfer"):
        policy["action"] = "silent"
    return policy


def match_system_inquiry(client, data: dict, policy: Dict[str, Any]) -> bool:
    """识别是否为系统客服询单消息。"""
    if not policy.get("enabled", False):
        return False

    from_name = client.to_chinese(data.get("from_name", "") or "").lower()
    from_id = str(data.get("from_id", "") or "").lower()
    msg = client.to_chinese(data.get("msg", "") or "").lower()

    sender_hits = 0
    for kw in policy.get("sender_keywords", []):
        if kw and (kw in from_name or kw in from_id):
            sender_hits += 1
    message_hits = 0
    for kw in policy.get("message_keywords", []):
        if kw and kw in msg:
            message_hits += 1

    # 优先看发送者特征；纯文本命中时至少要求两个关键词，降低误判风险
    return sender_hits > 0 or message_hits >= 2


async def handle_system_inquiry(client, data: dict) -> bool:
    """命中系统询单后按策略处理。"""
    acc_id = data.get("acc_id", "")
    policy = resolve_system_inquiry_policy(client, acc_id)
    if not match_system_inquiry(client, data, policy):
        return False

    customer_id = data.get("from_id", "")
    metrics_emit("system_inquiry_detected", customer_id=customer_id, acc_id=acc_id)
    action = policy.get("action", "silent")
    logger.info("系统询单命中 | 店铺:%s | 客户:%s | action:%s", acc_id, customer_id, action)

    if action == "reply":
        reply = await client._compose_ai_scene_reply(
            original_msg=data,
            scene="system_inquiry_reply",
            intent_hint="这是系统客服询单消息，简短确认已收到并说明会跟进即可。",
            fallback=(policy.get("reply") or "您好，这边已收到询单消息，稍后由人工客服跟进处理。"),
        )
        await client.send_reply(data, reply)
        metrics_emit("system_inquiry_auto_reply", customer_id=customer_id, acc_id=acc_id)
        return True
    if action == "transfer":
        await client.transfer_to_human(data, "系统询单转人工")
        metrics_emit("system_inquiry_transfer", customer_id=customer_id, acc_id=acc_id)
        return True

    metrics_emit("system_inquiry_ignored", customer_id=customer_id, acc_id=acc_id)
    return True
