from __future__ import annotations

import asyncio
import smtplib
import time
from datetime import datetime
from email.header import Header
from email.mime.text import MIMEText
from typing import Any

from .config import (
    EMAIL_NOTIFY_ENABLED,
    SMTP_HOST,
    SMTP_PASSWORD,
    SMTP_PORT,
    SMTP_TO,
    SMTP_USER,
)

_last_push: dict[tuple[str, str], tuple[str, str, float]] = {}


def _truncate(text: str, max_len: int = 220) -> str:
    t = str(text or "").strip()
    if len(t) <= max_len:
        return t
    return f"{t[:max_len]}..."


def _send_mail(subject: str, body: str) -> tuple[bool, str]:
    if not EMAIL_NOTIFY_ENABLED:
        return False, "email_disabled"
    if not SMTP_HOST or not SMTP_USER or not SMTP_PASSWORD or not SMTP_TO:
        return False, "email_config_incomplete"

    try:
        msg = MIMEText(body, "plain", "utf-8")
        msg["Subject"] = Header(subject, "utf-8")
        msg["From"] = f"{Header('千牛AI通知', 'utf-8').encode()} <{SMTP_USER}>"
        msg["To"] = SMTP_TO

        if int(SMTP_PORT) == 465:
            with smtplib.SMTP_SSL(SMTP_HOST, SMTP_PORT, timeout=10) as server:
                server.login(SMTP_USER, SMTP_PASSWORD)
                server.sendmail(SMTP_USER, [SMTP_TO], msg.as_string())
        else:
            with smtplib.SMTP(SMTP_HOST, SMTP_PORT, timeout=10) as server:
                server.starttls()
                server.login(SMTP_USER, SMTP_PASSWORD)
                server.sendmail(SMTP_USER, [SMTP_TO], msg.as_string())
        return True, "ok"
    except Exception as e:
        return False, str(e)


async def push_chat_to_email(
    *,
    customer_name: str,
    customer_id: str,
    acc_id: str,
    customer_msg: str,
    reply_msg: str,
    goods_name: str = "",
    recent_dialogue: list[dict[str, Any]] | None = None,
) -> tuple[bool, str]:
    if not EMAIL_NOTIFY_ENABLED:
        return False, "email_disabled"

    key = (str(customer_id or ""), str(acc_id or ""))
    now = time.time()
    last = _last_push.get(key)
    cm = str(customer_msg or "")
    rm = str(reply_msg or "")
    if last:
        lcm, lrm, lts = last
        if lcm == cm and lrm == rm and (now - lts) < 30:
            return False, "dedup_30s"
    _last_push[key] = (cm, rm, now)

    ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    subject = f"[千牛AI]{acc_id or '店铺'}-{customer_name or customer_id or '客户'}"
    lines: list[str] = [f"时间: {ts}"]
    lines.append(f"店铺: {acc_id or '未知店铺'}")
    lines.append(f"客户: {customer_name or '-'} ({customer_id or '-'})")
    if goods_name:
        lines.append(f"商品: {_truncate(goods_name, 120)}")
    lines.append("")
    for item in (recent_dialogue or [])[-8:]:
        role = "客户" if str(item.get("role", "")) == "user" else "客服"
        txt = _truncate(str(item.get("text", "") or ""), 180)
        if txt:
            lines.append(f"{role}: {txt}")
    lines.append(f"客户: {_truncate(cm, 220)}")
    lines.append(f"客服: {_truncate(rm, 220)}")
    body = "\n".join(lines)
    return await asyncio.to_thread(_send_mail, subject, body)

