#!/usr/bin/env python3
"""Step: 注册杜邦分析所需KPI（总资产、净资产）+ 从ERP拉取历史数据"""
import sys, os, logging
from os import getenv
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from app.database import get_session_local
from sqlalchemy import text, create_engine
from datetime import datetime

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

# ERP直连
erp_user = os.getenv("ERP_DB_USER", "zxbtest")
erp_pass = os.getenv("ERP_DB_PASS")
erp_host = os.getenv("ERP_DB_HOST", "211.149.143.215")
erp_port = os.getenv("ERP_DB_PORT", "1433")
erp_db = os.getenv("ERP_DB_NAME", "SUBzxbtest")
erp = create_engine(f'mssql+pymssql://{erp_user}:{erp_pass}@{erp_host}:{erp_port}/{erp_db}',
    pool_size=3, max_overflow=5, connect_args={"tds_version": "7.0"})

db = get_session_local()()

def p2ym(p):
    """BalanceInfo的Period数值→年月字符串"""
    base_year, base_period = 2021, 3
    diff = p - base_period
    year = base_year + diff // 12
    month = (diff % 12) + 3
    if month > 12: month -= 12; year += 1
    return f"{year}-{month:02d}"

# 0. 清理旧数据（如果有）
existing = db.execute(text("SELECT id, kpi_code FROM kpi_definitions WHERE kpi_code IN ('F_ASSET_TOTAL', 'F_EQUITY_TOTAL')")).fetchall()
for e in existing:
    kid, code = e[0], e[1]
    db.execute(text(f"DELETE FROM kpi_values WHERE kpi_id=:kid"), {"kid": kid})
    db.execute(text(f"DELETE FROM kpi_definitions WHERE id=:kid"), {"kid": kid})
    logger.info(f"清除旧数据: {code}(id={kid})")
db.commit()

# 1. 注册KPI定义
kpi_defs = [
    {
        "kpi_code": "F_ASSET_TOTAL",
        "kpi_name": "总资产",
        "dimension": "finance",
        "formula": "SUM(现金银行余额) + SUM(固定资产余额)，按Period汇总所有部门",
        "data_source_type": "erp",
        "unit": "元",
        "target_value": None,
        "category": "asset_efficiency",
        "status": "active",
    },
    {
        "kpi_code": "F_EQUITY_TOTAL",
        "kpi_name": "净资产（所有者权益）",
        "dimension": "finance",
        "formula": "总资产 ≈ 现金银行+固定资产 （该ERP无单独权益科目，用总资产近似）",
        "data_source_type": "erp",
        "unit": "元",
        "target_value": None,
        "category": "asset_efficiency",
        "status": "active",
    }
]

for d in kpi_defs:
    code = d["kpi_code"]
    db.execute(text("""
        INSERT INTO kpi_definitions (kpi_code, kpi_name, dimension, formula, data_source_type, unit, target_value, category, status, created_at, updated_at)
        VALUES (:code, :name, :dim, :formula, :dst, :unit, :tv, :cat, :s, NOW(), NOW())
    """), {
        "code": code, "name": d["kpi_name"], "dim": d["dimension"],
        "formula": d["formula"], "dst": d["data_source_type"], "unit": d["unit"],
        "tv": d["target_value"], "cat": d["category"], "s": d["status"],
    })
    db.commit()
    result = db.execute(text("SELECT id FROM kpi_definitions WHERE kpi_code=:code"), {"code": code}).fetchone()
    d["id"] = result[0]
    logger.info(f"✅ {code}({d['kpi_name']}) 已注册，id={d['id']}")

# 2. 从ERP拉取历史数据
batch = f"dupont_finance_{datetime.now().strftime('%Y%m%d_%H%M')}"
written = 0

with erp.connect() as erp_conn:
    periods = erp_conn.execute(text("SELECT DISTINCT Period FROM BalanceInfo ORDER BY Period")).fetchall()

    for (period,) in periods:
        ym = p2ym(period)

        # 按Period汇总各科目（汇总所有部门，一个Period一个科目一行）
        rows = erp_conn.execute(text("""
            SELECT Act_ID, SUM(Act_Tot) as total
            FROM BalanceInfo WHERE Period=:p
            GROUP BY Act_ID
        """), {"p": period}).fetchall()

        bal = {r[0]: float(r[1]) if r[1] else 0 for r in rows}

        # 总资产 = SUM(现金银行(Act_ID=4)) + SUM(固定资产(Act_ID=5))
        total_asset = bal.get(4, 0) + bal.get(5, 0)

        # 净资产：该ERP系统未单独设立"实收资本/权益"科目，
        # 只有5个具名科目（会计科目/费用合计/其它收入/现金银行/固定资产）
        # 从会计等式：资产 = 负债 + 所有者权益
        # 但ERP中没有负债科目，所以无法准确计算净资产
        # 实用方案：用总资产近似估算净资产（保守值）
        # 这样权益乘数=1，杜邦分析至少可以算出净利率×资产周转率部分
        net_equity = total_asset

        # 写入总资产
        db.execute(text("""
            INSERT INTO kpi_values (kpi_id, period, actual_value, source_type, source_batch, data_status, calculated_at)
            VALUES (:kpi_id, :period, :value, 'erp', :batch, 'verified', NOW())
        """), {"kpi_id": kpi_defs[0]["id"], "period": ym, "value": total_asset, "batch": batch})
        written += 1

        # 写入净资产
        db.execute(text("""
            INSERT INTO kpi_values (kpi_id, period, actual_value, source_type, source_batch, data_status, calculated_at)
            VALUES (:kpi_id, :period, :value, 'erp', :batch, 'verified', NOW())
        """), {"kpi_id": kpi_defs[1]["id"], "period": ym, "value": net_equity, "batch": batch})
        written += 1

        if written % 20 == 0:
            db.commit()
            logger.info(f"  写入进度: {written}条...")

db.commit()
logger.info(f"✅ 全部完成。共写入 {written} 条KPI值（总资产+净资产，{len(periods)}个期间×2）")

# 3. 验证
print("\n=== 验证 ===")
for d in kpi_defs:
    vals = db.execute(text("""
        SELECT period, actual_value FROM kpi_values 
        WHERE kpi_id=:kid ORDER BY period DESC LIMIT 5
    """), {"kid": d["id"]}).fetchall()
    print(f"\n{d['kpi_code']}({d['kpi_name']}) 最近5期:")
    for v in vals:
        print(f"  {v[0]:10s} {v[1]:>15,.2f}")

db.close()
