# -*- coding: utf-8 -*-
"""
成交/未成交记录 - 用于日报与数据分析
"""
import sqlite3
import os
from datetime import datetime
from typing import List, Dict, Optional

_DB_PATH = os.path.join(os.path.dirname(__file__), "deal_outcome_db", "outcomes.db")
_DB_TYPE = os.getenv("DB_TYPE", "sqlite").lower()
_MYSQL_HOST = os.getenv("MYSQL_HOST", "127.0.0.1")
_MYSQL_PORT = int(os.getenv("MYSQL_PORT", "3306"))
_MYSQL_USER = os.getenv("MYSQL_USER", "root")
_MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD", "")
_MYSQL_DATABASE = os.getenv("MYSQL_DATABASE", "ai_cs")


class _CompatResult:
    def __init__(self, rows=None, rowcount: int = 0, lastrowid: int = 0):
        self._rows = rows or []
        self.rowcount = rowcount
        self.lastrowid = lastrowid

    def fetchall(self):
        return self._rows

    def fetchone(self):
        return self._rows[0] if self._rows else None


class _PyMySQLCompatConn:
    def __init__(self, conn):
        self._conn = conn

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc, tb):
        if exc_type:
            try:
                self._conn.rollback()
            except Exception:
                pass
        self._conn.close()

    def execute(self, query: str, args=None):
        cur = self._conn.cursor()
        cur.execute(query, args or ())
        rows = cur.fetchall() if cur.description else []
        res = _CompatResult(rows=rows, rowcount=cur.rowcount, lastrowid=getattr(cur, "lastrowid", 0))
        cur.close()
        return res

    def commit(self):
        self._conn.commit()

def _is_mysql() -> bool:
    return _DB_TYPE in ("mysql", "mariadb")

def _sql(query: str) -> str:
    return query.replace("?", "%s") if _is_mysql() else query


def _get_conn() -> sqlite3.Connection:
    if _is_mysql():
        import pymysql
        conn = pymysql.connect(
            host=_MYSQL_HOST,
            port=_MYSQL_PORT,
            user=_MYSQL_USER,
            password=_MYSQL_PASSWORD,
            database=_MYSQL_DATABASE,
            charset="utf8mb4",
            cursorclass=pymysql.cursors.DictCursor,
            autocommit=False,
        )
        return _PyMySQLCompatConn(conn)
    os.makedirs(os.path.dirname(_DB_PATH), exist_ok=True)
    conn = sqlite3.connect(_DB_PATH)
    conn.row_factory = sqlite3.Row
    return conn


def _init_db():
    with _get_conn() as conn:
        if _is_mysql():
            conn.execute("""
                CREATE TABLE IF NOT EXISTS deal_outcomes (
                    id          INTEGER PRIMARY KEY AUTO_INCREMENT,
                    customer_id VARCHAR(128) NOT NULL,
                    customer_name VARCHAR(255) DEFAULT '',
                    acc_id      VARCHAR(128) DEFAULT '',
                    platform    VARCHAR(64) DEFAULT '',
                    date        DATE NOT NULL,
                    outcome     VARCHAR(16) NOT NULL,
                    reason      TEXT,
                    order_id    VARCHAR(128) DEFAULT '',
                    amount      REAL DEFAULT 0,
                    discount_given INTEGER DEFAULT 0,
                    timestamp   DATETIME NOT NULL
                ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
            """)
            idx_rows = conn.execute("SHOW INDEX FROM deal_outcomes").fetchall()
            exists = {str(r.get("Key_name", "")) for r in idx_rows}
            if "idx_deal_date" not in exists:
                conn.execute("CREATE INDEX idx_deal_date ON deal_outcomes(date)")
            if "idx_deal_customer" not in exists:
                conn.execute("CREATE INDEX idx_deal_customer ON deal_outcomes(customer_id)")
            if "idx_deal_acc" not in exists:
                conn.execute("CREATE INDEX idx_deal_acc ON deal_outcomes(acc_id)")
            if "idx_deal_outcome" not in exists:
                conn.execute("CREATE INDEX idx_deal_outcome ON deal_outcomes(outcome)")
        else:
            conn.execute("""
                CREATE TABLE IF NOT EXISTS deal_outcomes (
                    id          INTEGER PRIMARY KEY AUTOINCREMENT,
                    customer_id TEXT    NOT NULL,
                    customer_name TEXT   DEFAULT '',
                    acc_id      TEXT    DEFAULT '',
                    platform    TEXT    DEFAULT '',
                    date        TEXT    NOT NULL,
                    outcome     TEXT    NOT NULL CHECK(outcome IN ('成交','未成交')),
                    reason      TEXT    DEFAULT '',
                    order_id    TEXT    DEFAULT '',
                    amount      REAL    DEFAULT 0,
                    discount_given INTEGER DEFAULT 0,
                    timestamp   TEXT    NOT NULL
                )
            """)
            conn.execute("CREATE INDEX IF NOT EXISTS idx_deal_date ON deal_outcomes(date)")
            conn.execute("CREATE INDEX IF NOT EXISTS idx_deal_customer ON deal_outcomes(customer_id)")
            conn.execute("CREATE INDEX IF NOT EXISTS idx_deal_acc ON deal_outcomes(acc_id)")
            conn.execute("CREATE INDEX IF NOT EXISTS idx_deal_outcome ON deal_outcomes(outcome)")
        conn.commit()


_init_db()


def record_deal(
    customer_id: str,
    outcome: str,
    reason: str = "",
    customer_name: str = "",
    acc_id: str = "",
    platform: str = "",
    order_id: str = "",
    amount: float = 0,
    discount_given: bool = False,
):
    """记录一笔成交或未成交"""
    ts = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    date = datetime.now().strftime("%Y-%m-%d")
    with _get_conn() as conn:
        conn.execute(
            _sql("""INSERT INTO deal_outcomes
               (customer_id, customer_name, acc_id, platform, date, outcome, reason,
                order_id, amount, discount_given, timestamp)
               VALUES (?,?,?,?,?,?,?,?,?,?,?)"""),
            (
                customer_id,
                customer_name or "",
                acc_id or "",
                platform or "",
                date,
                outcome,
                reason or "",
                order_id or "",
                amount,
                1 if discount_given else 0,
                ts,
            ),
        )
        conn.commit()


def get_daily_outcomes(date: str = "") -> List[Dict]:
    """获取指定日期的成交/未成交记录，用于日报"""
    if not date:
        date = datetime.now().strftime("%Y-%m-%d")
    with _get_conn() as conn:
        rows = conn.execute(
            _sql("""
            SELECT customer_id, customer_name, acc_id, outcome, reason,
                   order_id, amount, discount_given, timestamp
            FROM deal_outcomes
            WHERE date = ?
            ORDER BY timestamp ASC
            """),
            (date,),
        ).fetchall()
    return [dict(r) for r in rows]


def get_daily_summary(date: str = "") -> Dict:
    """获取指定日期的成交/未成交汇总统计"""
    outcomes = get_daily_outcomes(date)
    success = [o for o in outcomes if o["outcome"] == "成交"]
    fail = [o for o in outcomes if o["outcome"] == "未成交"]

    # 按原因分组
    fail_by_reason: Dict[str, int] = {}
    for o in fail:
        r = o.get("reason") or "其他"
        fail_by_reason[r] = fail_by_reason.get(r, 0) + 1

    return {
        "date": date or datetime.now().strftime("%Y-%m-%d"),
        "成交数": len(success),
        "未成交数": len(fail),
        "成交金额": sum(o.get("amount") or 0 for o in success),
        "成交明细": success,
        "未成交明细": fail,
        "未成交原因分布": fail_by_reason,
    }


def export_for_analysis(start_date: str = "", end_date: str = "") -> List[Dict]:
    """
    导出成交/未成交记录，供数据库分析。
    日期格式 YYYY-MM-DD，留空则查全部。
    """
    with _get_conn() as conn:
        if start_date and end_date:
            rows = conn.execute(
                _sql("""SELECT * FROM deal_outcomes
                   WHERE date BETWEEN ? AND ?
                   ORDER BY date, timestamp"""),
                (start_date, end_date),
            ).fetchall()
        elif start_date:
            rows = conn.execute(
                _sql("""SELECT * FROM deal_outcomes WHERE date >= ? ORDER BY date, timestamp"""),
                (start_date,),
            ).fetchall()
        elif end_date:
            rows = conn.execute(
                _sql("""SELECT * FROM deal_outcomes WHERE date <= ? ORDER BY date, timestamp"""),
                (end_date,),
            ).fetchall()
        else:
            rows = conn.execute(
                """SELECT * FROM deal_outcomes ORDER BY date, timestamp"""
            ).fetchall()
    return [dict(r) for r in rows]
