"""
采购订单保留测试
验证：一旦订单进入待采购列表，即使状态变化也不会被删除，只会更新字段
"""

import pytest
import pytest_asyncio
from datetime import datetime, timedelta
from decimal import Decimal

from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine, async_sessionmaker
from sqlalchemy import select

from app.core.database import Base
from app.models.raw_orders import RawOrder
from app.models.products_master import ProductMaster, ProductSourceMapping
from app.models.procurement_orders import ProcurementOrder, ProcurementStatus
from app.services.procurement_order_service_v2 import ProcurementOrderServiceV2


@pytest_asyncio.fixture
async def test_db():
    """创建测试数据库"""
    engine = create_async_engine("sqlite+aiosqlite:///:memory:", echo=False)

    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)

    async_session = async_sessionmaker(engine, expire_on_commit=False)

    async with async_session() as session:
        yield session

    await engine.dispose()


@pytest.mark.asyncio
async def test_procurement_order_preserved_after_status_change(test_db):
    """
    测试场景：订单初始状态为"已付款"进入待采购列表，
    后来更新为"交易成功"（不满足筛选条件），
    但订单仍应保留在待采购列表中
    """

    # 1. 创建初始原始订单（已付款状态，满足条件）
    raw_order = RawOrder(
        file_name="test_order_001.xlsx",  # 添加必需的file_name
        file_hash="hash001",  # 添加必需的file_hash
        row_idx=1,  # 添加必需的row_idx
        原始订单编号="ORDER-001",
        线上宝贝名称="Tods女款蓝色鳄鱼压纹麻花扣乐福鞋",
        线上销售属性="颜色:蓝色;尺寸:37码",
        数量=1,
        订单单价=Decimal("1200.00"),
        订单金额=Decimal("1200.00"),
        付款时间=datetime.now() - timedelta(days=5),
        交易状态="已付款",  # 满足条件
        退款状态="正常",    # 满足条件
        网店名称="小王国美妆",
        卖家备注="VIP客户",
        图片="http://example.com/image.jpg"
    )
    test_db.add(raw_order)
    await test_db.flush()
    raw_order_id = raw_order.id

    # 2. 创建产品主表记录
    product = ProductMaster(
        sku_key="tods_blue_37",
        品牌="Tods",
        货号="TODS-001",
        颜色="蓝色",
        尺寸="37码",
        线上宝贝名称="Tods女款蓝色鳄鱼压纹麻花扣乐福鞋",
        线上销售属性="颜色:蓝色;尺寸:37码",
        procurement_method="NY",
        avg_price=Decimal("1200.00"),
        is_urgent=False,
        priority_score=50
    )
    test_db.add(product)
    await test_db.flush()

    # 3. 创建产品来源映射
    mapping = ProductSourceMapping(
        product_master_id=product.id,
        raw_order_id=raw_order_id
    )
    test_db.add(mapping)
    await test_db.commit()

    # 4. 第一次生成采购订单（增量模式）
    service = ProcurementOrderServiceV2()
    result1 = await service.generate_procurement_orders(test_db, force_rebuild=False)

    # 验证采购订单被创建
    assert result1['created_orders'] == 1
    assert result1['processed_orders'] == 1

    # 查询采购订单
    procurement_result = await test_db.execute(
        select(ProcurementOrder).where(ProcurementOrder.original_order_id == raw_order_id)
    )
    procurement_order = procurement_result.scalar_one()

    assert procurement_order is not None
    assert procurement_order.original_order_id == raw_order_id
    assert procurement_order.交易状态 == "已付款"
    assert procurement_order.procurement_status == ProcurementStatus.PENDING
    initial_procurement_id = procurement_order.id

    # 5. 更新原始订单状态（变为不满足条件的状态）
    raw_order.交易状态 = "交易成功"  # 不再满足筛选条件
    await test_db.commit()

    # 6. 第二次生成采购订单（增量模式）
    result2 = await service.generate_procurement_orders(test_db, force_rebuild=False)

    # 验证：
    # - 没有新创建的采购订单（因为原始订单不满足条件）
    # - 没有删除现有采购订单
    assert result2['created_orders'] == 0
    assert result2['updated_orders'] == 0
    assert result2['processed_orders'] == 0

    # 7. 验证原始采购订单仍然存在
    count_result = await test_db.execute(
        select(ProcurementOrder).where(ProcurementOrder.original_order_id == raw_order_id)
    )
    procurement_order = count_result.scalar_one()

    assert procurement_order is not None
    assert procurement_order.id == initial_procurement_id
    # 原始订单状态已更新
    assert procurement_order.交易状态 == "交易成功"
    # 采购状态保持PENDING
    assert procurement_order.procurement_status == ProcurementStatus.PENDING


@pytest.mark.asyncio
async def test_procurement_order_update_on_generation(test_db):
    """
    测试场景：使用 force_rebuild=True 时，
    现有的采购订单应该被更新而不是删除
    """

    # 1. 创建初始原始订单
    raw_order = RawOrder(
        file_name="test_order_002.xlsx",
        file_hash="hash002",
        row_idx=1,
        原始订单编号="ORDER-002",
        线上宝贝名称="MaxMara女款黑色羊毛大衣",
        线上销售属性="颜色:黑色;尺寸:40码",
        数量=1,
        订单单价=Decimal("3500.00"),
        订单金额=Decimal("3500.00"),
        付款时间=datetime.now() - timedelta(days=3),
        交易状态="已付款",
        退款状态="正常",
        网店名称="小王国美妆",
        卖家备注="",
        图片="http://example.com/image2.jpg"
    )
    test_db.add(raw_order)
    await test_db.flush()
    raw_order_id = raw_order.id

    # 2. 创建产品主表记录
    product = ProductMaster(
        sku_key="maxmara_black_40",
        品牌="MaxMara",
        货号="MM-001",
        颜色="黑色",
        尺寸="40码",
        线上宝贝名称="MaxMara女款黑色羊毛大衣",
        线上销售属性="颜色:黑色;尺寸:40码",
        procurement_method="LA",
        avg_price=Decimal("3500.00"),
        is_urgent=False,
        priority_score=60
    )
    test_db.add(product)
    await test_db.flush()

    # 3. 创建产品来源映射
    mapping = ProductSourceMapping(
        product_master_id=product.id,
        raw_order_id=raw_order_id
    )
    test_db.add(mapping)
    await test_db.commit()

    # 4. 第一次生成采购订单
    service = ProcurementOrderServiceV2()
    result1 = await service.generate_procurement_orders(test_db, force_rebuild=False)
    assert result1['created_orders'] == 1

    # 查询采购订单
    procurement_result = await test_db.execute(
        select(ProcurementOrder).where(ProcurementOrder.original_order_id == raw_order_id)
    )
    procurement_order = procurement_result.scalar_one()
    initial_id = procurement_order.id
    initial_amount = procurement_order.订单金额

    # 5. 更新原始订单数据
    raw_order.订单单价 = Decimal("3200.00")
    raw_order.订单金额 = Decimal("3200.00")
    raw_order.卖家备注 = "已更新备注"
    await test_db.commit()

    # 6. 使用 force_rebuild=True 重新生成
    result2 = await service.generate_procurement_orders(test_db, force_rebuild=True)

    # 验证结果
    # 原始订单满足条件，应该被处理
    assert result2['processed_orders'] == 1
    # 由于订单已存在，应该被更新而不是创建
    assert result2['updated_orders'] == 1

    # 7. 验证采购订单被更新而不是删除/重建
    procurement_result = await test_db.execute(
        select(ProcurementOrder).where(ProcurementOrder.original_order_id == raw_order_id)
    )
    procurement_order = procurement_result.scalar_one()

    assert procurement_order is not None
    assert procurement_order.id == initial_id  # ID应该相同（不是新建）
    assert procurement_order.订单金额 == Decimal("3200.00")  # 金额已更新
    assert procurement_order.卖家备注 == "已更新备注"  # 备注已更新
    assert procurement_order.procurement_status == ProcurementStatus.PENDING  # 采购状态保持


@pytest.mark.asyncio
async def test_multiple_status_changes_with_field_updates(test_db):
    """
    测试场景：多次更新订单状态和字段，
    验证采购订单始终保留且字段正确更新
    """

    # 1. 创建初始原始订单
    raw_order = RawOrder(
        file_name="test_order_003.xlsx",
        file_hash="hash003",
        row_idx=1,
        原始订单编号="ORDER-003",
        线上宝贝名称="Stuart Weitzman女款高跟鞋",
        线上销售属性="颜色:红色;尺寸:35.5码",
        数量=2,
        订单单价=Decimal("2800.00"),
        订单金额=Decimal("5600.00"),
        付款时间=datetime.now() - timedelta(days=10),
        交易状态="已付款",
        退款状态="正常",
        网店名称="小王国美妆",
        卖家备注="第一次备注",
        图片="http://example.com/image3.jpg"
    )
    test_db.add(raw_order)
    await test_db.flush()
    raw_order_id = raw_order.id

    # 2. 创建产品主表
    product = ProductMaster(
        sku_key="sw_red_35_5",
        品牌="Stuart Weitzman",
        货号="SW-001",
        颜色="红色",
        尺寸="35.5码",
        线上宝贝名称="Stuart Weitzman女款高跟鞋",
        线上销售属性="颜色:红色;尺寸:35.5码",
        procurement_method="AP",
        avg_price=Decimal("2800.00"),
        is_urgent=False,
        priority_score=50
    )
    test_db.add(product)
    await test_db.flush()

    mapping = ProductSourceMapping(
        product_master_id=product.id,
        raw_order_id=raw_order_id
    )
    test_db.add(mapping)
    await test_db.commit()

    service = ProcurementOrderServiceV2()

    # 3. 初始生成
    result1 = await service.generate_procurement_orders(test_db, force_rebuild=False)
    assert result1['created_orders'] == 1
    initial_count = 1

    # 4. 更新为部分发货（仍满足条件）
    raw_order.交易状态 = "部分发货"
    raw_order.数量 = 1  # 发货了1件
    raw_order.订单金额 = Decimal("2800.00")
    raw_order.卖家备注 = "已发货1件"
    await test_db.commit()

    result2 = await service.generate_procurement_orders(test_db, force_rebuild=False)
    # 订单已存在，不会再创建
    assert result2['created_orders'] == 0

    # 5. 查询验证
    procurement_result = await test_db.execute(
        select(ProcurementOrder).where(ProcurementOrder.original_order_id == raw_order_id)
    )
    procurement_orders = procurement_result.scalars().all()
    assert len(procurement_orders) == initial_count  # 数量没变

    procurement_order = procurement_orders[0]
    assert procurement_order.数量 == 1
    assert procurement_order.交易状态 == "部分发货"
    assert procurement_order.卖家备注 == "已发货1件"

    # 6. 再次更新为交易成功（不满足条件）
    raw_order.交易状态 = "交易成功"
    raw_order.卖家备注 = "交易完成"
    await test_db.commit()

    result3 = await service.generate_procurement_orders(test_db, force_rebuild=False)
    # 订单现在不满足条件，但不会被删除
    assert result3['created_orders'] == 0

    # 7. 最终验证
    procurement_result = await test_db.execute(
        select(ProcurementOrder).where(ProcurementOrder.original_order_id == raw_order_id)
    )
    procurement_orders = procurement_result.scalars().all()
    assert len(procurement_orders) == initial_count  # 仍然是1条记录

    procurement_order = procurement_orders[0]
    assert procurement_order.procurement_status == ProcurementStatus.PENDING  # 采购状态保持


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
