"""Step 2: AI分析ERP表语义 — 通过后端进程执行（避开了Key遮蔽）
运行: python3 scripts/analyze_erp_tables.py
输出: erp_schema 增加 classification/domain/description 字段
"""

import sys, os, json, logging, requests
from datetime import datetime

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from app.database import get_engine, get_session_local
from sqlalchemy import text

logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger("erp_analyze")

# 从环境变量获取Key（后端进程.env已加载）
API_KEY = os.getenv("DEEPSEEK_API_KEY")
if not API_KEY:
    logger.error("DEEPSEEK_API_KEY 环境变量未设置")
    sys.exit(1)

DEEPSEEK_API = "https://api.deepseek.com/v1/chat/completions"


def get_tables_batch(offset: int, limit: int) -> list:
    """获取一批未分类的表"""
    engine = get_engine()
    with engine.connect() as conn:
        rows = conn.execute(text("""
            SELECT table_name, total_rows, field_count, fields_json
            FROM erp_schema
            WHERE field_count > 0
            ORDER BY total_rows DESC
            LIMIT :limit OFFSET :offset
        """), {"limit": limit, "offset": offset}).fetchall()
    
    tables = []
    for r in rows:
        try:
            fields = json.loads(r.fields_json) if r.fields_json else []
        except:
            fields = []
        tables.append({
            "name": r.table_name,
            "rows": r.total_rows or 0,
            "field_count": r.field_count or 0,
            "fields": [f["name"] for f in fields if isinstance(f, dict)][:30]
        })
    return tables


def call_deepseek(prompt: str) -> list:
    """调用DeepSeek分析"""
    resp = requests.post(
        DEEPSEEK_API,
        headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
        json={
            "model": "deepseek-chat",
            "messages": [
                {"role": "system", "content": "你是一个ERP系统分析师，精通制造业/贸易企业进销存+财务系统。严格基于表名和字段名推断，不要编造。"},
                {"role": "user", "content": prompt}
            ],
            "temperature": 0.1,
            "max_tokens": 4000,
        },
        timeout=120
    )
    data = resp.json()
    content = data["choices"][0]["message"]["content"]
    
    # 提取JSON
    content = content.strip()
    if content.startswith("```"):
        content = content.split("\n", 1)[1]
        content = content.rsplit("```", 1)[0]
    return json.loads(content)


def save_analysis(results: list):
    """将分析结果写入erp_schema"""
    db = get_session_local()()
    try:
        for r in results:
            db.execute(text("""
                UPDATE erp_schema 
                SET classification=:type, domain=:domain, description=:desc, updated_at=NOW()
                WHERE table_name=:tn
            """), {
                "tn": r["table"],
                "type": r.get("type", "system"),
                "domain": r.get("domain", "other"),
                "desc": r.get("desc", ""),
            })
        db.commit()
        logger.info(f"  已更新 {len(results)} 条")
    except Exception as e:
        db.rollback()
        logger.error(f"保存失败: {e}")
    finally:
        db.close()


def main():
    # 先检查erp_schema是否有分类字段
    engine = get_engine()
    insp = __import__("sqlalchemy", fromlist=["inspect"]).inspect(engine)
    columns = [c["name"] for c in insp.get_columns("erp_schema")]
    
    db = get_session_local()()
    try:
        if "classification" not in columns:
            logger.info("添加 classification/domain/description 字段...")
            db.execute(text("ALTER TABLE erp_schema ADD COLUMN classification VARCHAR(20) DEFAULT NULL COMMENT 'core/config/log/temp/system'"))
            db.execute(text("ALTER TABLE erp_schema ADD COLUMN domain VARCHAR(20) DEFAULT NULL COMMENT 'sale/purchase/inventory/finance/...'"))
            db.execute(text("ALTER TABLE erp_schema ADD COLUMN description VARCHAR(500) DEFAULT NULL COMMENT '中文描述'"))
            db.commit()
            logger.info("字段添加完成")
    finally:
        db.close()
    
    # 分批分析（每批120张表）
    total = 984  # field_count>0的表
    batch_size = 120
    
    for offset in range(0, total, batch_size):
        tables = get_tables_batch(offset, batch_size)
        if not tables:
            break
        
        logger.info(f"分析批次 {offset//batch_size + 1}: 表 {offset+1}-{min(offset+batch_size, total)} / {total}")
        
        # 构建prompt
        table_lines = []
        for t in tables:
            fields_str = ", ".join(t["fields"])
            table_lines.append(f"【{t['name']}】({t['rows']}行, {t['field_count']}字段): {fields_str}")
        
        prompt = f"""分析以下ERP数据库表。对于每张表，判断：
1. type: core(核心业务表，存业务数据)/config(配置表)/log(日志表)/temp(临时表，前缀tmp/Temp/oldhis)/system(系统表，如权限/用户/菜单)
2. domain: sale(销售)/purchase(采购)/inventory(库存)/finance(财务)/customer(客户)/product(商品)/hr(人事)/sys(系统)/other
3. desc: 一段中文描述该表在业务中对应什么

输出JSON数组：
[{{"table":"表名","type":"core","domain":"sale","desc":"销售主表"}}]

{chr(10).join(table_lines)}"""
        
        try:
            results = call_deepseek(prompt)
            save_analysis(results)
        except Exception as e:
            logger.error(f"批次失败: {e}")
            continue
    
    # 统计
    db = get_session_local()()
    try:
        r = db.execute(text("""
            SELECT classification, domain, COUNT(*) 
            FROM erp_schema WHERE classification IS NOT NULL
            GROUP BY classification, domain ORDER BY classification, domain
        """)).fetchall()
        logger.info("\n=== 分析统计 ===")
        counts = {}
        for row in r:
            key = f"{row[0]}/{row[1]}"
            counts[key] = row[2]
        for k, v in sorted(counts.items()):
            logger.info(f"  {k:25s} {v} 张")
        
        core = db.execute(text("SELECT COUNT(*) FROM erp_schema WHERE classification='core'")).scalar()
        logger.info(f"\n核心业务表: {core} 张")
    finally:
        db.close()


if __name__ == "__main__":
    main()
