# app/modules/customers/tests/unit/test_customer_metrics.py
"""Unit tests for CustomerMetricsProvider.get_merchant_metrics."""

import uuid

import pytest

from app.modules.customers.models.customer import Customer
from app.modules.customers.services.customer_metrics import CustomerMetricsProvider
from app.modules.tenancy.models import Merchant, Store, User


@pytest.fixture
def cust_merchant(db):
    """Create a merchant for customer metrics tests."""
    from middleware.auth import AuthManager

    auth = AuthManager()
    user = User(
        email=f"custowner_{uuid.uuid4().hex[:8]}@test.com",
        username=f"custowner_{uuid.uuid4().hex[:8]}",
        hashed_password=auth.hash_password("pass123"),
        role="merchant_owner",
        is_active=True,
    )
    db.add(user)
    db.flush()

    merchant = Merchant(
        name="Customer Metrics Merchant",
        owner_user_id=user.id,
        contact_email=user.email,
        is_active=True,
        is_verified=True,
    )
    db.add(merchant)
    db.commit()
    db.refresh(merchant)
    return merchant


@pytest.fixture
def cust_stores(db, cust_merchant):
    """Create 2 stores for the merchant."""
    stores = []
    for i in range(2):
        uid = uuid.uuid4().hex[:8].upper()
        stores.append(Store(
            merchant_id=cust_merchant.id,
            store_code=f"CSTORE_{uid}",
            subdomain=f"cstore{uid.lower()}",
            name=f"Cust Store {i}",
            is_active=True,
            is_verified=True,
        ))
    db.add_all(stores)
    db.commit()
    for s in stores:
        db.refresh(s)
    return stores


@pytest.fixture
def cust_customers(db, cust_stores):
    """Create customers across the merchant's stores."""
    customers = []
    # 3 customers in store 0
    for i in range(3):
        uid = uuid.uuid4().hex[:8]
        customers.append(Customer(
            store_id=cust_stores[0].id,
            email=f"cust_{uid}@test.com",
            hashed_password="hashed",  # noqa: SEC001
            first_name=f"First{i}",
            last_name=f"Last{i}",
            customer_number=f"C{uid}",
            is_active=True,
        ))
    # 2 customers in store 1
    for i in range(2):
        uid = uuid.uuid4().hex[:8]
        customers.append(Customer(
            store_id=cust_stores[1].id,
            email=f"cust_{uid}@test.com",
            hashed_password="hashed",  # noqa: SEC001
            first_name=f"First{i}",
            last_name=f"Last{i}",
            customer_number=f"C{uid}",
            is_active=True,
        ))
    db.add_all(customers)
    db.commit()
    return customers


@pytest.mark.unit
@pytest.mark.customers
class TestCustomerMetricsProviderMerchant:
    """Tests for CustomerMetricsProvider.get_merchant_metrics."""

    def setup_method(self):
        self.provider = CustomerMetricsProvider()

    def test_total_customers_across_stores(self, db, cust_merchant, cust_stores, cust_customers):
        """Aggregates customers across all merchant stores."""
        metrics = self.provider.get_merchant_metrics(db, cust_merchant.id)
        by_key = {m.key: m.value for m in metrics}
        assert by_key["customers.total"] == 5

    def test_no_customers(self, db, cust_merchant, cust_stores):
        """Returns zero when stores have no customers."""
        metrics = self.provider.get_merchant_metrics(db, cust_merchant.id)
        by_key = {m.key: m.value for m in metrics}
        assert by_key["customers.total"] == 0

    def test_no_stores(self, db, cust_merchant):
        """Returns zero when merchant has no stores."""
        metrics = self.provider.get_merchant_metrics(db, cust_merchant.id)
        by_key = {m.key: m.value for m in metrics}
        assert by_key["customers.total"] == 0

    def test_nonexistent_merchant(self, db):
        """Returns zero for a non-existent merchant ID."""
        metrics = self.provider.get_merchant_metrics(db, 999999)
        by_key = {m.key: m.value for m in metrics}
        assert by_key["customers.total"] == 0
