# analytics/forecasting.py
"""
Smart Stock Forecasting — predicts stock exhaustion and recommends restock.
Company-scoped. Called as part of generate_insights management command.
"""
import logging
from datetime import timedelta
from decimal import Decimal

from django.utils import timezone
from django.db.models import Sum, Count, Q

logger = logging.getLogger(__name__)

FORECAST_DAYS = 30          # Look-back window for avg daily sales
RESTOCK_BUFFER_DAYS = 14   # Recommend enough stock for 2 weeks
DEAD_STOCK_DAYS = 45        # No sales for this many days = dead stock
OVERSTOCK_DAYS = 60         # > 60 days of stock at current velocity = overstock


class StockForecaster:
    """Updates StockForecast for every active product in the company."""

    def __init__(self, company):
        self.company = company
        self.now = timezone.now()
        self.since = self.now - timedelta(days=FORECAST_DAYS)

    def update_all(self):
        from inventory.models import Product
        from analytics.models import StockForecast

        products = Product.objects.filter(company=self.company, status='active')
        updated = 0

        for product in products:
            try:
                forecast = self._forecast_product(product)
                StockForecast.objects.update_or_create(
                    company=self.company,
                    product=product,
                    defaults=forecast,
                )
                updated += 1
            except Exception as e:
                logger.error(f"[Forecast] Error for {product.name}: {e}")

        logger.info(f"[Forecast] Updated {updated} products for {self.company.name}")
        return updated

    def _forecast_product(self, product):
        from sales.models import POSOrderItem

        # Total quantity sold in last FORECAST_DAYS
        sold_data = POSOrderItem.objects.filter(
            order__company=self.company,
            order__status='completed',
            order__created_at__gte=self.since,
            product=product,
        ).aggregate(total_qty=Sum('quantity'), order_count=Count('order_id', distinct=True))

        total_qty = sold_data['total_qty'] or 0
        avg_daily = Decimal(str(total_qty)) / Decimal(str(FORECAST_DAYS)) if total_qty > 0 else Decimal('0')

        current_stock = product.stock_quantity

        # Days until stockout
        if avg_daily > 0:
            days_until_stockout = int(current_stock / avg_daily)
        else:
            days_until_stockout = None  # No sales data = can't predict

        # Recommended restock qty (2-week buffer)
        recommended_restock = int(avg_daily * RESTOCK_BUFFER_DAYS) if avg_daily > 0 else 0

        # Stock health classification
        if total_qty == 0 and current_stock > 0:
            health = 'dead'  # Has stock but zero sales in 45 days
        elif avg_daily == 0 and current_stock == 0:
            health = 'healthy'  # Out of stock intentionally (no demand)
        elif days_until_stockout is not None:
            if days_until_stockout <= 3:
                health = 'critical'
            elif days_until_stockout <= RESTOCK_BUFFER_DAYS:
                health = 'low_risk'
            elif days_until_stockout > OVERSTOCK_DAYS:
                health = 'overstock'
            else:
                health = 'healthy'
        else:
            health = 'healthy'

        return {
            'avg_daily_sales': avg_daily,
            'days_until_stockout': days_until_stockout,
            'recommended_restock_qty': recommended_restock,
            'stock_health': health,
        }
