#!/usr/bin/env python3
"""
导出 bi_vala_app_account 手机号 MD5 映射表

用途：
  1. 全量导出：python3 export_phone_md5.py → output/phone_md5_export.csv
  2. 按 account_id 导出：python3 export_phone_md5.py --ids 123,456,789
  3. 被其他 skill 调用：from scripts.export_phone_md5 import query_phone_md5

输出 CSV 字段：account_id, tel_encrypt, phone_plain, phone_md5
"""
import csv
import os
import sys
import argparse
from datetime import datetime

import psycopg2
import psycopg2.extras

SCRIPTS_DIR = os.path.dirname(os.path.abspath(__file__))
WORKSPACE_DIR = os.path.dirname(SCRIPTS_DIR)
sys.path.insert(0, SCRIPTS_DIR)
from phone_encrypt import decrypt_phone, phone_md5, tel_encrypt_to_md5

# ── 数据库配置 ──
PG_HOST = "bj-postgres-16pob4sg.sql.tencentcdb.com"
PG_PORT = 28591
PG_USER = "ai_member"
PG_DB = "vala_bi"

# 从 secrets.env 读取密码
SECRETS_FILE = os.path.join(WORKSPACE_DIR, "secrets.env")


def _get_pg_password() -> str:
    """从 secrets.env 读取 PostgreSQL 密码"""
    with open(SECRETS_FILE) as f:
        for line in f:
            line = line.strip()
            if line.startswith("PG_ONLINE_PASSWORD="):
                return line.split("=", 1)[1].strip().strip('"').strip("'")
    raise RuntimeError("未找到 PG_ONLINE_PASSWORD 在 secrets.env 中")


def _get_conn():
    return psycopg2.connect(
        host=PG_HOST, port=PG_PORT, user=PG_USER,
        password=_get_pg_password(), dbname=PG_DB
    )


def query_phone_md5(account_ids: list[int] = None) -> list[dict]:
    """
    查询手机号 MD5 映射

    Args:
        account_ids: 指定 account_id 列表，None 表示全量

    Returns:
        [{account_id, tel_encrypt, phone_plain, phone_md5}, ...]
    """
    conn = _get_conn()
    try:
        cur = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
        if account_ids:
            sql = """
                SELECT id AS account_id, tel_encrypt
                FROM bi_vala_app_account
                WHERE id = ANY(%s) AND tel_encrypt IS NOT NULL AND tel_encrypt != ''
            """
            cur.execute(sql, (account_ids,))
        else:
            sql = """
                SELECT id AS account_id, tel_encrypt
                FROM bi_vala_app_account
                WHERE tel_encrypt IS NOT NULL AND tel_encrypt != ''
            """
            cur.execute(sql)

        rows = cur.fetchall()
        results = []
        for row in rows:
            tel_enc = row["tel_encrypt"]
            try:
                phone = decrypt_phone(tel_enc)
                md5 = phone_md5(phone)
            except Exception:
                phone = ""
                md5 = ""
            results.append({
                "account_id": row["account_id"],
                "tel_encrypt": tel_enc,
                "phone_plain": phone,
                "phone_md5": md5,
            })
        return results
    finally:
        conn.close()


def export_csv(account_ids: list[int] = None, output_path: str = None) -> str:
    """
    导出为 CSV 文件

    Returns:
        输出文件路径
    """
    if output_path is None:
        ts = datetime.now().strftime("%Y%m%d_%H%M%S")
        output_path = os.path.join(WORKSPACE_DIR, "output", f"phone_md5_export_{ts}.csv")

    os.makedirs(os.path.dirname(output_path), exist_ok=True)
    results = query_phone_md5(account_ids)

    with open(output_path, "w", newline="", encoding="utf-8") as f:
        writer = csv.DictWriter(f, fieldnames=["account_id", "tel_encrypt", "phone_plain", "phone_md5"])
        writer.writeheader()
        writer.writerows(results)

    print(f"导出完成: {len(results)} 条记录 → {output_path}")
    return output_path


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="导出手机号 MD5 映射表")
    parser.add_argument("--ids", help="指定 account_id，逗号分隔，不传则全量导出")
    parser.add_argument("--output", help="输出文件路径，默认 output/phone_md5_export_<时间戳>.csv")
    args = parser.parse_args()

    ids = None
    if args.ids:
        ids = [int(x.strip()) for x in args.ids.split(",") if x.strip()]

    export_csv(ids, args.output)
