# tests/fixtures/customer_fixtures.py
"""
Customer-related test fixtures.

Note: Fixtures should NOT use db.expunge() as it breaks lazy loading.
See tests/conftest.py for details on fixture best practices.
"""

from datetime import UTC

import pytest

from app.modules.customers.models.customer import Customer, CustomerAddress
from app.modules.orders.models import Order


@pytest.fixture
def test_customer(db, test_store):
    """Create a test customer."""
    customer = Customer(
        store_id=test_store.id,
        email="testcustomer@example.com",
        hashed_password="hashed_password",  # noqa: SEC001
        first_name="John",
        last_name="Doe",
        customer_number="TEST001",
        is_active=True,
    )
    db.add(customer)
    db.commit()
    db.refresh(customer)
    return customer


@pytest.fixture
def test_customer_address(db, test_store, test_customer):
    """Create a test customer shipping address."""
    address = CustomerAddress(
        store_id=test_store.id,
        customer_id=test_customer.id,
        address_type="shipping",
        first_name="John",
        last_name="Doe",
        address_line_1="123 Main St",
        city="Luxembourg",
        postal_code="L-1234",
        country_name="Luxembourg",
        country_iso="LU",
        is_default=True,
    )
    db.add(address)
    db.commit()
    db.refresh(address)
    return address


@pytest.fixture
def test_customer_billing_address(db, test_store, test_customer):
    """Create a test customer billing address."""
    address = CustomerAddress(
        store_id=test_store.id,
        customer_id=test_customer.id,
        address_type="billing",
        first_name="John",
        last_name="Doe",
        merchant="Test Merchant S.A.",
        address_line_1="456 Business Ave",
        city="Luxembourg",
        postal_code="L-5678",
        country_name="Luxembourg",
        country_iso="LU",
        is_default=True,
    )
    db.add(address)
    db.commit()
    db.refresh(address)
    return address


@pytest.fixture
def test_customer_multiple_addresses(db, test_store, test_customer):
    """Create multiple addresses for testing limits and listing."""
    addresses = []
    for i in range(3):
        address = CustomerAddress(
            store_id=test_store.id,
            customer_id=test_customer.id,
            address_type="shipping" if i % 2 == 0 else "billing",
            first_name=f"Name{i}",
            last_name="Test",
            address_line_1=f"{i}00 Test Street",
            city="Luxembourg",
            postal_code=f"L-{1000+i}",
            country_name="Luxembourg",
            country_iso="LU",
            is_default=(i == 0),
        )
        db.add(address)  # noqa: PERF006
        addresses.append(address)
    db.commit()
    for addr in addresses:
        db.refresh(addr)
    return addresses


@pytest.fixture
def test_order(db, test_store, test_customer, test_customer_address):
    """Create a test order with customer/address snapshots."""
    from datetime import datetime

    order = Order(
        store_id=test_store.id,
        customer_id=test_customer.id,
        order_number="TEST-ORD-001",
        status="pending",
        channel="direct",
        subtotal=99.99,
        total_amount=99.99,
        currency="EUR",
        order_date=datetime.now(UTC),
        # Customer snapshot
        customer_first_name=test_customer.first_name,
        customer_last_name=test_customer.last_name,
        customer_email=test_customer.email,
        customer_phone=None,
        # Shipping address snapshot
        ship_first_name=test_customer_address.first_name,
        ship_last_name=test_customer_address.last_name,
        ship_address_line_1=test_customer_address.address_line_1,
        ship_city=test_customer_address.city,
        ship_postal_code=test_customer_address.postal_code,
        ship_country_iso="LU",
        # Billing address snapshot
        bill_first_name=test_customer_address.first_name,
        bill_last_name=test_customer_address.last_name,
        bill_address_line_1=test_customer_address.address_line_1,
        bill_city=test_customer_address.city,
        bill_postal_code=test_customer_address.postal_code,
        bill_country_iso="LU",
    )
    db.add(order)
    db.commit()
    db.refresh(order)
    return order


@pytest.fixture
def test_order_item(db, test_order, test_product):
    """Create a test order item."""
    from app.modules.orders.models import OrderItem

    order_item = OrderItem(
        order_id=test_order.id,
        product_id=test_product.id,
        product_name="Test Product",
        product_sku="TEST-SKU-001",
        quantity=1,
        unit_price=49.99,
        total_price=49.99,
    )
    db.add(order_item)
    db.commit()
    db.refresh(order_item)
    return order_item
