# app/modules/catalog/services/catalog_metrics.py
"""
Metrics provider for the catalog module.

Provides metrics for:
- Product counts
- Active/inactive products
- Featured products
"""

import logging
from datetime import datetime, timedelta
from typing import TYPE_CHECKING

from sqlalchemy import func
from sqlalchemy.orm import Session

from app.modules.contracts.metrics import (
    MetricsContext,
    MetricValue,
)

if TYPE_CHECKING:
    pass

logger = logging.getLogger(__name__)


class CatalogMetricsProvider:
    """
    Metrics provider for catalog module.

    Provides product-related metrics for store and platform dashboards.
    """

    @property
    def metrics_category(self) -> str:
        return "catalog"

    def get_store_metrics(
        self,
        db: Session,
        store_id: int,
        context: MetricsContext | None = None,
    ) -> list[MetricValue]:
        """
        Get product metrics for a specific store.

        Provides:
        - Total products
        - Active products
        - Featured products
        - New products (in period)
        """
        from app.modules.catalog.models import Product

        try:
            # Total products
            total_products = (
                db.query(Product).filter(Product.store_id == store_id).count()
            )

            # Active products
            active_products = (
                db.query(Product)
                .filter(Product.store_id == store_id, Product.is_active == True)
                .count()
            )

            # Featured products
            featured_products = (
                db.query(Product)
                .filter(
                    Product.store_id == store_id,
                    Product.is_featured == True,
                    Product.is_active == True,
                )
                .count()
            )

            # New products (default to last 30 days)
            date_from = context.date_from if context else None
            if date_from is None:
                date_from = datetime.utcnow() - timedelta(days=30)

            new_products_query = db.query(Product).filter(
                Product.store_id == store_id,
                Product.created_at >= date_from,
            )
            if context and context.date_to:
                new_products_query = new_products_query.filter(
                    Product.created_at <= context.date_to
                )
            new_products = new_products_query.count()

            # Products with translations
            (
                db.query(func.count(func.distinct(Product.id)))
                .filter(Product.store_id == store_id)
                .join(Product.translations)
                .scalar()
                or 0
            )

            return [
                MetricValue(
                    key="catalog.total_products",
                    value=total_products,
                    label="Total Products",
                    category="catalog",
                    icon="box",
                    description="Total products in catalog",
                ),
                MetricValue(
                    key="catalog.active_products",
                    value=active_products,
                    label="Active Products",
                    category="catalog",
                    icon="check-circle",
                    description="Products that are active and visible",
                ),
                MetricValue(
                    key="catalog.featured_products",
                    value=featured_products,
                    label="Featured Products",
                    category="catalog",
                    icon="star",
                    description="Products marked as featured",
                ),
                MetricValue(
                    key="catalog.new_products",
                    value=new_products,
                    label="New Products",
                    category="catalog",
                    icon="plus-circle",
                    description="Products added in the period",
                ),
            ]
        except Exception as e:
            logger.warning(f"Failed to get catalog store metrics: {e}")
            return []

    def get_platform_metrics(
        self,
        db: Session,
        platform_id: int,
        context: MetricsContext | None = None,
    ) -> list[MetricValue]:
        """
        Get product metrics aggregated for a platform.

        Aggregates catalog data across all stores.
        """
        from app.modules.catalog.models import Product
        from app.modules.tenancy.services.platform_service import platform_service

        try:
            # Get all store IDs for this platform via platform service
            store_ids = platform_service.get_store_ids_for_platform(db, platform_id)

            # Total products
            total_products = (
                db.query(Product).filter(Product.store_id.in_(store_ids)).count()
            )

            # Active products
            active_products = (
                db.query(Product)
                .filter(Product.store_id.in_(store_ids), Product.is_active == True)
                .count()
            )

            # Featured products
            featured_products = (
                db.query(Product)
                .filter(
                    Product.store_id.in_(store_ids),
                    Product.is_featured == True,
                    Product.is_active == True,
                )
                .count()
            )

            # Stores with products
            stores_with_products = (
                db.query(func.count(func.distinct(Product.store_id)))
                .filter(Product.store_id.in_(store_ids))
                .scalar()
                or 0
            )

            # Average products per store
            total_stores = (
                db.query(StorePlatform)
                .filter(
                    StorePlatform.platform_id == platform_id,
                    StorePlatform.is_active == True,
                )
                .count()
            )
            avg_products = round(total_products / total_stores, 1) if total_stores > 0 else 0

            return [
                MetricValue(
                    key="catalog.total_products",
                    value=total_products,
                    label="Total Products",
                    category="catalog",
                    icon="box",
                    description="Total products across all stores",
                ),
                MetricValue(
                    key="catalog.active_products",
                    value=active_products,
                    label="Active Products",
                    category="catalog",
                    icon="check-circle",
                    description="Products that are active and visible",
                ),
                MetricValue(
                    key="catalog.featured_products",
                    value=featured_products,
                    label="Featured Products",
                    category="catalog",
                    icon="star",
                    description="Products marked as featured",
                ),
                MetricValue(
                    key="catalog.stores_with_products",
                    value=stores_with_products,
                    label="Stores with Products",
                    category="catalog",
                    icon="store",
                    description="Stores that have created products",
                ),
                MetricValue(
                    key="catalog.avg_products_per_store",
                    value=avg_products,
                    label="Avg Products/Store",
                    category="catalog",
                    icon="calculator",
                    description="Average products per store",
                ),
            ]
        except Exception as e:
            logger.warning(f"Failed to get catalog platform metrics: {e}")
            return []


# Singleton instance
catalog_metrics_provider = CatalogMetricsProvider()

__all__ = ["CatalogMetricsProvider", "catalog_metrics_provider"]
