"""成本分析模块 — 种子数据导入脚本
补充 standard_costs, actual_costs, abc_activities, abc_allocations 数据
运行: python3 scripts/seed_cost_data.py
"""

import sys
import os
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from app.database import get_session_local, get_engine
from app.models import StandardCost, ActualCost, AbcActivity, AbcAllocation
from sqlalchemy import text
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("seed_cost")

PRODUCTS = [
    ("P001", "博海ERP系统", "软件产品"),
    ("P002", "博海OA系统", "软件产品"),
    ("P003", "博海WMS系统", "软件产品"),
    ("S001", "系统实施服务", "技术服务"),
    ("S002", "系统运维服务", "技术服务"),
]


def seed_standard_costs(db):
    """标准成本卡片 — 5个产品的料工费标准"""
    count = db.query(StandardCost).count()
    if count > 0:
        logger.info(f"standard_costs 已有 {count} 条数据，跳过")
        return

    items = [
        # P001 博海ERP系统 - 材料
        StandardCost(product_code="P001", product_name="博海ERP系统", cost_type="material",
                     item_name="服务器资源", standard_quantity=12, unit="台/月", standard_price=5000,
                     standard_cost=60000, version="v1.0", remark="云服务器ECS 8C16G"),
        StandardCost(product_code="P001", product_name="博海ERP系统", cost_type="material",
                     item_name="数据库授权", standard_quantity=2, unit="套", standard_price=30000,
                     standard_cost=60000, version="v1.0", remark="MySQL商业版许可"),
        StandardCost(product_code="P001", product_name="博海ERP系统", cost_type="material",
                     item_name="第三方组件", standard_quantity=1, unit="批", standard_price=15000,
                     standard_cost=15000, version="v1.0"),
        # P001 博海ERP系统 - 人工
        StandardCost(product_code="P001", product_name="博海ERP系统", cost_type="labor",
                     item_name="需求分析", standard_quantity=40, unit="人天", standard_price=1500,
                     standard_cost=60000, version="v1.0"),
        StandardCost(product_code="P001", product_name="博海ERP系统", cost_type="labor",
                     item_name="后端开发", standard_quantity=120, unit="人天", standard_price=1800,
                     standard_cost=216000, version="v1.0"),
        StandardCost(product_code="P001", product_name="博海ERP系统", cost_type="labor",
                     item_name="前端开发", standard_quantity=80, unit="人天", standard_price=1600,
                     standard_cost=128000, version="v1.0"),
        StandardCost(product_code="P001", product_name="博海ERP系统", cost_type="labor",
                     item_name="测试", standard_quantity=40, unit="人天", standard_price=1200,
                     standard_cost=48000, version="v1.0"),
        # P001 博海ERP系统 - 制造费用
        StandardCost(product_code="P001", product_name="博海ERP系统", cost_type="overhead",
                     item_name="项目管理", standard_quantity=1, unit="项", standard_price=35000,
                     standard_cost=35000, version="v1.0"),
        StandardCost(product_code="P001", product_name="博海ERP系统", cost_type="overhead",
                     item_name="质量保证", standard_quantity=1, unit="项", standard_price=20000,
                     standard_cost=20000, version="v1.0"),
        StandardCost(product_code="P001", product_name="博海ERP系统", cost_type="overhead",
                     item_name="办公分摊", standard_quantity=1, unit="项", standard_price=15000,
                     standard_cost=15000, version="v1.0"),

        # P002 博海OA系统
        StandardCost(product_code="P002", product_name="博海OA系统", cost_type="material",
                     item_name="服务器资源", standard_quantity=8, unit="台/月", standard_price=4000,
                     standard_cost=32000, version="v1.0"),
        StandardCost(product_code="P002", product_name="博海OA系统", cost_type="material",
                     item_name="云存储", standard_quantity=500, unit="GB", standard_price=2,
                     standard_cost=1000, version="v1.0"),
        StandardCost(product_code="P002", product_name="博海OA系统", cost_type="labor",
                     item_name="后端开发", standard_quantity=80, unit="人天", standard_price=1800,
                     standard_cost=144000, version="v1.0"),
        StandardCost(product_code="P002", product_name="博海OA系统", cost_type="labor",
                     item_name="前端开发", standard_quantity=60, unit="人天", standard_price=1600,
                     standard_cost=96000, version="v1.0"),
        StandardCost(product_code="P002", product_name="博海OA系统", cost_type="labor",
                     item_name="测试", standard_quantity=30, unit="人天", standard_price=1200,
                     standard_cost=36000, version="v1.0"),
        StandardCost(product_code="P002", product_name="博海OA系统", cost_type="overhead",
                     item_name="项目管理", standard_quantity=1, unit="项", standard_price=25000,
                     standard_cost=25000, version="v1.0"),

        # P003 博海WMS系统
        StandardCost(product_code="P003", product_name="博海WMS系统", cost_type="material",
                     item_name="服务器资源", standard_quantity=6, unit="台/月", standard_price=3500,
                     standard_cost=21000, version="v1.0"),
        StandardCost(product_code="P003", product_name="博海WMS系统", cost_type="material",
                     item_name="硬件设备", standard_quantity=10, unit="台", standard_price=8000,
                     standard_cost=80000, version="v1.0", remark="PDA扫码终端"),
        StandardCost(product_code="P003", product_name="博海WMS系统", cost_type="labor",
                     item_name="后端开发", standard_quantity=100, unit="人天", standard_price=1800,
                     standard_cost=180000, version="v1.0"),
        StandardCost(product_code="P003", product_name="博海WMS系统", cost_type="labor",
                     item_name="前端开发", standard_quantity=50, unit="人天", standard_price=1600,
                     standard_cost=80000, version="v1.0"),
        StandardCost(product_code="P003", product_name="博海WMS系统", cost_type="labor",
                     item_name="实施部署", standard_quantity=30, unit="人天", standard_price=1500,
                     standard_cost=45000, version="v1.0"),
        StandardCost(product_code="P003", product_name="博海WMS系统", cost_type="overhead",
                     item_name="项目管理", standard_quantity=1, unit="项", standard_price=30000,
                     standard_cost=30000, version="v1.0"),

        # S001 系统实施服务
        StandardCost(product_code="S001", product_name="系统实施服务", cost_type="labor",
                     item_name="实施顾问", standard_quantity=60, unit="人天", standard_price=2000,
                     standard_cost=120000, version="v1.0"),
        StandardCost(product_code="S001", product_name="系统实施服务", cost_type="labor",
                     item_name="培训讲师", standard_quantity=10, unit="人天", standard_price=2500,
                     standard_cost=25000, version="v1.0"),
        StandardCost(product_code="S001", product_name="系统实施服务", cost_type="material",
                     item_name="差旅费用", standard_quantity=1, unit="项", standard_price=20000,
                     standard_cost=20000, version="v1.0"),
        StandardCost(product_code="S001", product_name="系统实施服务", cost_type="overhead",
                     item_name="项目管理", standard_quantity=1, unit="项", standard_price=15000,
                     standard_cost=15000, version="v1.0"),

        # S002 系统运维服务
        StandardCost(product_code="S002", product_name="系统运维服务", cost_type="labor",
                     item_name="运维工程师", standard_quantity=22, unit="人天", standard_price=1800,
                     standard_cost=39600, version="v1.0"),
        StandardCost(product_code="S002", product_name="系统运维服务", cost_type="material",
                     item_name="监控工具", standard_quantity=1, unit="套/月", standard_price=5000,
                     standard_cost=5000, version="v1.0"),
        StandardCost(product_code="S002", product_name="系统运维服务", cost_type="overhead",
                     item_name="7x24值班", standard_quantity=1, unit="项", standard_price=8000,
                     standard_cost=8000, version="v1.0"),
    ]
    db.add_all(items)
    db.commit()
    logger.info(f"✅ 标准成本: 插入 {len(items)} 条记录")


def seed_actual_costs(db):
    """实际成本 — 2026年4-5月数据"""
    count = db.query(ActualCost).count()
    if count > 0:
        logger.info(f"actual_costs 已有 {count} 条数据，跳过")
        return

    items = [
        # P001 - 4月
        ActualCost(period="2026-04", product_code="P001", product_name="博海ERP系统",
                   cost_type="material", item_name="服务器资源", actual_quantity=11, actual_price=5200,
                   actual_cost=57200, source="manual"),
        ActualCost(period="2026-04", product_code="P001", product_name="博海ERP系统",
                   cost_type="material", item_name="数据库授权", actual_quantity=2, actual_price=30000,
                   actual_cost=60000, source="manual"),
        ActualCost(period="2026-04", product_code="P001", product_name="博海ERP系统",
                   cost_type="labor", item_name="后端开发", actual_quantity=125, actual_price=1800,
                   actual_cost=225000, source="manual"),
        ActualCost(period="2026-04", product_code="P001", product_name="博海ERP系统",
                   cost_type="labor", item_name="前端开发", actual_quantity=85, actual_price=1600,
                   actual_cost=136000, source="manual"),
        ActualCost(period="2026-04", product_code="P001", product_name="博海ERP系统",
                   cost_type="labor", item_name="测试", actual_quantity=38, actual_price=1200,
                   actual_cost=45600, source="manual"),
        ActualCost(period="2026-04", product_code="P001", product_name="博海ERP系统",
                   cost_type="overhead", item_name="项目管理", actual_quantity=1, actual_price=36000,
                   actual_cost=36000, source="manual"),
        ActualCost(period="2026-04", product_code="P001", product_name="博海ERP系统",
                   cost_type="overhead", item_name="办公分摊", actual_quantity=1, actual_price=18000,
                   actual_cost=18000, source="manual"),

        # P001 - 5月
        ActualCost(period="2026-05", product_code="P001", product_name="博海ERP系统",
                   cost_type="material", item_name="服务器资源", actual_quantity=12, actual_price=5000,
                   actual_cost=60000, source="manual"),
        ActualCost(period="2026-05", product_code="P001", product_name="博海ERP系统",
                   cost_type="material", item_name="第三方组件", actual_quantity=1, actual_price=18000,
                   actual_cost=18000, source="manual"),
        ActualCost(period="2026-05", product_code="P001", product_name="博海ERP系统",
                   cost_type="labor", item_name="需求分析", actual_quantity=35, actual_price=1500,
                   actual_cost=52500, source="manual"),
        ActualCost(period="2026-05", product_code="P001", product_name="博海ERP系统",
                   cost_type="labor", item_name="后端开发", actual_quantity=118, actual_price=1850,
                   actual_cost=218300, source="manual"),
        ActualCost(period="2026-05", product_code="P001", product_name="博海ERP系统",
                   cost_type="labor", item_name="前端开发", actual_quantity=82, actual_price=1650,
                   actual_cost=135300, source="manual"),
        ActualCost(period="2026-05", product_code="P001", product_name="博海ERP系统",
                   cost_type="labor", item_name="测试", actual_quantity=42, actual_price=1200,
                   actual_cost=50400, source="manual"),
        ActualCost(period="2026-05", product_code="P001", product_name="博海ERP系统",
                   cost_type="overhead", item_name="项目管理", actual_quantity=1, actual_price=35000,
                   actual_cost=35000, source="manual"),
        ActualCost(period="2026-05", product_code="P001", product_name="博海ERP系统",
                   cost_type="overhead", item_name="质量保证", actual_quantity=1, actual_price=22000,
                   actual_cost=22000, source="manual"),

        # P002 - 5月 （成本略低于标准）
        ActualCost(period="2026-05", product_code="P002", product_name="博海OA系统",
                   cost_type="material", item_name="服务器资源", actual_quantity=7, actual_price=4200,
                   actual_cost=29400, source="manual"),
        ActualCost(period="2026-05", product_code="P002", product_name="博海OA系统",
                   cost_type="labor", item_name="后端开发", actual_quantity=78, actual_price=1800,
                   actual_cost=140400, source="manual"),
        ActualCost(period="2026-05", product_code="P002", product_name="博海OA系统",
                   cost_type="labor", item_name="前端开发", actual_quantity=58, actual_price=1600,
                   actual_cost=92800, source="manual"),
        ActualCost(period="2026-05", product_code="P002", product_name="博海OA系统",
                   cost_type="labor", item_name="测试", actual_quantity=28, actual_price=1200,
                   actual_cost=33600, source="manual"),
        ActualCost(period="2026-05", product_code="P002", product_name="博海OA系统",
                   cost_type="overhead", item_name="项目管理", actual_quantity=1, actual_price=25000,
                   actual_cost=25000, source="manual"),

        # P003 - 5月 （成本超支）
        ActualCost(period="2026-05", product_code="P003", product_name="博海WMS系统",
                   cost_type="material", item_name="服务器资源", actual_quantity=6, actual_price=3800,
                   actual_cost=22800, source="manual"),
        ActualCost(period="2026-05", product_code="P003", product_name="博海WMS系统",
                   cost_type="material", item_name="硬件设备", actual_quantity=12, actual_price=8500,
                   actual_cost=102000, source="manual"),
        ActualCost(period="2026-05", product_code="P003", product_name="博海WMS系统",
                   cost_type="labor", item_name="后端开发", actual_quantity=105, actual_price=1850,
                   actual_cost=194250, source="manual"),
        ActualCost(period="2026-05", product_code="P003", product_name="博海WMS系统",
                   cost_type="labor", item_name="前端开发", actual_quantity=55, actual_price=1600,
                   actual_cost=88000, source="manual"),
        ActualCost(period="2026-05", product_code="P003", product_name="博海WMS系统",
                   cost_type="labor", item_name="实施部署", actual_quantity=35, actual_price=1500,
                   actual_cost=52500, source="manual"),
        ActualCost(period="2026-05", product_code="P003", product_name="博海WMS系统",
                   cost_type="overhead", item_name="项目管理", actual_quantity=1, actual_price=32000,
                   actual_cost=32000, source="manual"),

        # S001 - 5月
        ActualCost(period="2026-05", product_code="S001", product_name="系统实施服务",
                   cost_type="labor", item_name="实施顾问", actual_quantity=55, actual_price=2000,
                   actual_cost=110000, source="manual"),
        ActualCost(period="2026-05", product_code="S001", product_name="系统实施服务",
                   cost_type="material", item_name="差旅费用", actual_quantity=1, actual_price=18500,
                   actual_cost=18500, source="manual"),

        # S002 - 5月
        ActualCost(period="2026-05", product_code="S002", product_name="系统运维服务",
                   cost_type="labor", item_name="运维工程师", actual_quantity=22, actual_price=1800,
                   actual_cost=39600, source="manual"),
        ActualCost(period="2026-05", product_code="S002", product_name="系统运维服务",
                   cost_type="material", item_name="监控工具", actual_quantity=1, actual_price=5000,
                   actual_cost=5000, source="manual"),
        ActualCost(period="2026-05", product_code="S002", product_name="系统运维服务",
                   cost_type="overhead", item_name="7x24值班", actual_quantity=1, actual_price=9000,
                   actual_cost=9000, source="manual"),
    ]
    db.add_all(items)
    db.commit()
    logger.info(f"✅ 实际成本: 插入 {len(items)} 条记录")


def seed_abc_activities(db):
    """ABC作业活动定义"""
    count = db.query(AbcActivity).count()
    if count > 0:
        logger.info(f"abc_activities 已有 {count} 条数据，跳过")
        return

    items = [
        AbcActivity(activity_code="A001", activity_name="需求调研与分析",
                    activity_desc="与客户沟通，收集和分析业务需求，编写需求规格说明书",
                    cost_driver="需求调研人天", driver_unit="人天", total_cost=120000, driver_volume=80, driver_rate=1500.0),
        AbcActivity(activity_code="A002", activity_name="系统架构设计",
                    activity_desc="系统架构规划、数据库设计、接口协议定义",
                    cost_driver="架构设计人天", driver_unit="人天", total_cost=90000, driver_volume=45, driver_rate=2000.0),
        AbcActivity(activity_code="A003", activity_name="核心功能开发",
                    activity_desc="后端业务逻辑实现、API接口开发",
                    cost_driver="开发人天", driver_unit="人天", total_cost=480000, driver_volume=300, driver_rate=1600.0),
        AbcActivity(activity_code="A004", activity_name="前端界面开发",
                    activity_desc="用户界面实现、交互逻辑开发",
                    cost_driver="前端开发人天", driver_unit="人天", total_cost=320000, driver_volume=200, driver_rate=1600.0),
        AbcActivity(activity_code="A005", activity_name="测试与质量保障",
                    activity_desc="单元测试、集成测试、性能测试、Bug追踪",
                    cost_driver="测试人天", driver_unit="人天", total_cost=120000, driver_volume=100, driver_rate=1200.0),
        AbcActivity(activity_code="A006", activity_name="项目实施与部署",
                    activity_desc="客户现场实施、系统部署、数据迁移",
                    cost_driver="实施人天", driver_unit="人天", total_cost=180000, driver_volume=90, driver_rate=2000.0),
        AbcActivity(activity_code="A007", activity_name="客户培训与验收",
                    activity_desc="客户培训、验收测试、上线支持",
                    cost_driver="培训人天", driver_unit="人天", total_cost=75000, driver_volume=30, driver_rate=2500.0),
        AbcActivity(activity_code="A008", activity_name="运维与技术支持",
                    activity_desc="系统监控、故障处理、版本更新、客户咨询",
                    cost_driver="运维人天", driver_unit="人天", total_cost=200000, driver_volume=100, driver_rate=2000.0),
        AbcActivity(activity_code="A009", activity_name="项目管理与协调",
                    activity_desc="项目计划制定、进度跟踪、风险管理、资源协调",
                    cost_driver="管理人天", driver_unit="人天", total_cost=150000, driver_volume=60, driver_rate=2500.0),
        AbcActivity(activity_code="A010", activity_name="质量体系维护",
                    activity_desc="过程改进、代码审查、规范化建设",
                    cost_driver="QA人天", driver_unit="人天", total_cost=60000, driver_volume=30, driver_rate=2000.0),
    ]
    db.add_all(items)
    db.commit()
    logger.info(f"✅ ABC作业: 插入 {len(items)} 条记录")


def seed_abc_allocations(db):
    """ABC成本分配到产品"""
    count = db.query(AbcAllocation).count()
    if count > 0:
        logger.info(f"abc_allocations 已有 {count} 条数据，跳过")
        return

    # 按产品按作业分配比例 (driver_consumed)
    # product_code -> [(activity_id, driver_consumed, product_name)]
    allocs = [
        # P001 博海ERP系统
        AbcAllocation(period="2026-05", activity_id=1, product_code="P001", product_name="博海ERP系统", driver_consumed=35, allocated_cost=52500),
        AbcAllocation(period="2026-05", activity_id=2, product_code="P001", product_name="博海ERP系统", driver_consumed=20, allocated_cost=40000),
        AbcAllocation(period="2026-05", activity_id=3, product_code="P001", product_name="博海ERP系统", driver_consumed=120, allocated_cost=192000),
        AbcAllocation(period="2026-05", activity_id=4, product_code="P001", product_name="博海ERP系统", driver_consumed=80, allocated_cost=128000),
        AbcAllocation(period="2026-05", activity_id=5, product_code="P001", product_name="博海ERP系统", driver_consumed=40, allocated_cost=48000),
        AbcAllocation(period="2026-05", activity_id=6, product_code="P001", product_name="博海ERP系统", driver_consumed=30, allocated_cost=60000),
        AbcAllocation(period="2026-05", activity_id=7, product_code="P001", product_name="博海ERP系统", driver_consumed=10, allocated_cost=25000),
        AbcAllocation(period="2026-05", activity_id=9, product_code="P001", product_name="博海ERP系统", driver_consumed=25, allocated_cost=62500),

        # P002 博海OA系统
        AbcAllocation(period="2026-05", activity_id=1, product_code="P002", product_name="博海OA系统", driver_consumed=15, allocated_cost=22500),
        AbcAllocation(period="2026-05", activity_id=2, product_code="P002", product_name="博海OA系统", driver_consumed=10, allocated_cost=20000),
        AbcAllocation(period="2026-05", activity_id=3, product_code="P002", product_name="博海OA系统", driver_consumed=70, allocated_cost=112000),
        AbcAllocation(period="2026-05", activity_id=4, product_code="P002", product_name="博海OA系统", driver_consumed=55, allocated_cost=88000),
        AbcAllocation(period="2026-05", activity_id=5, product_code="P002", product_name="博海OA系统", driver_consumed=25, allocated_cost=30000),
        AbcAllocation(period="2026-05", activity_id=9, product_code="P002", product_name="博海OA系统", driver_consumed=15, allocated_cost=37500),

        # P003 博海WMS系统
        AbcAllocation(period="2026-05", activity_id=1, product_code="P003", product_name="博海WMS系统", driver_consumed=20, allocated_cost=30000),
        AbcAllocation(period="2026-05", activity_id=2, product_code="P003", product_name="博海WMS系统", driver_consumed=10, allocated_cost=20000),
        AbcAllocation(period="2026-05", activity_id=3, product_code="P003", product_name="博海WMS系统", driver_consumed=90, allocated_cost=144000),
        AbcAllocation(period="2026-05", activity_id=4, product_code="P003", product_name="博海WMS系统", driver_consumed=45, allocated_cost=72000),
        AbcAllocation(period="2026-05", activity_id=5, product_code="P003", product_name="博海WMS系统", driver_consumed=25, allocated_cost=30000),
        AbcAllocation(period="2026-05", activity_id=6, product_code="P003", product_name="博海WMS系统", driver_consumed=25, allocated_cost=50000),
        AbcAllocation(period="2026-05", activity_id=9, product_code="P003", product_name="博海WMS系统", driver_consumed=15, allocated_cost=37500),

        # S001 系统实施服务
        AbcAllocation(period="2026-05", activity_id=6, product_code="S001", product_name="系统实施服务", driver_consumed=35, allocated_cost=70000),
        AbcAllocation(period="2026-05", activity_id=7, product_code="S001", product_name="系统实施服务", driver_consumed=20, allocated_cost=50000),

        # S002 系统运维服务
        AbcAllocation(period="2026-05", activity_id=8, product_code="S002", product_name="系统运维服务", driver_consumed=100, allocated_cost=200000),
        AbcAllocation(period="2026-05", activity_id=10, product_code="S002", product_name="系统运维服务", driver_consumed=30, allocated_cost=60000),
    ]
    db.add_all(allocs)
    db.commit()
    logger.info(f"✅ ABC分配: 插入 {len(allocs)} 条记录")


def main():
    db = get_session_local()()
    try:
        logger.info("开始导入成本分析种子数据...")
        seed_standard_costs(db)
        seed_actual_costs(db)
        seed_abc_activities(db)
        seed_abc_allocations(db)
        logger.info("🎉 全部成本种子数据导入完成!")
    except Exception as e:
        logger.error(f"导入失败: {e}", exc_info=True)
        db.rollback()
        raise
    finally:
        db.close()


if __name__ == "__main__":
    main()
