# services/suppliers/app/api/analytics.py
"""
Supplier Analytics API endpoints (ANALYTICS)
Consolidates performance metrics, delivery stats, and all analytics operations
"""

from datetime import datetime, timedelta
from typing import List, Optional, Dict, Any
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Query, Path, status
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import Session
import structlog

from shared.auth.decorators import get_current_user_dep
from shared.auth.access_control import require_user_role, analytics_tier_required
from shared.routing import RouteBuilder
from app.core.database import get_db
from app.services.performance_service import PerformanceTrackingService, AlertService
from app.services.dashboard_service import DashboardService
from app.schemas.performance import (
    PerformanceMetric, Alert, PerformanceDashboardSummary,
    SupplierPerformanceInsights, PerformanceAnalytics, BusinessModelInsights,
    AlertSummary, PerformanceReportRequest, ExportDataResponse
)
from app.models.performance import PerformancePeriod, PerformanceMetricType, AlertType, AlertSeverity

logger = structlog.get_logger()

# Create route builder for consistent URL structure
route_builder = RouteBuilder('suppliers')

router = APIRouter(tags=["analytics"])


# ===== Dependency Injection =====

async def get_performance_service() -> PerformanceTrackingService:
    """Get performance tracking service"""
    return PerformanceTrackingService()

async def get_alert_service() -> AlertService:
    """Get alert service"""
    return AlertService()

async def get_dashboard_service() -> DashboardService:
    """Get dashboard service"""
    return DashboardService()


# ===== Performance Metrics =====

@router.post(
    route_builder.build_analytics_route("performance/{supplier_id}/calculate"),
    response_model=PerformanceMetric
)
async def calculate_supplier_performance(
    tenant_id: UUID = Path(...),
    supplier_id: UUID = Path(...),
    period: PerformancePeriod = Query(...),
    period_start: datetime = Query(...),
    period_end: datetime = Query(...),
    current_user: dict = Depends(get_current_user_dep),
    performance_service: PerformanceTrackingService = Depends(get_performance_service),
    db: AsyncSession = Depends(get_db)
):
    """Calculate performance metrics for a supplier"""
    try:
        metric = await performance_service.calculate_supplier_performance(
            db, supplier_id, tenant_id, period, period_start, period_end
        )

        if not metric:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Unable to calculate performance metrics"
            )

        logger.info("Performance metrics calculated",
                   tenant_id=str(tenant_id),
                   supplier_id=str(supplier_id),
                   period=period.value)

        return metric

    except Exception as e:
        logger.error("Error calculating performance metrics",
                    tenant_id=str(tenant_id),
                    supplier_id=str(supplier_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to calculate performance metrics"
        )


@router.get(
    route_builder.build_analytics_route("performance/{supplier_id}/metrics"),
    response_model=List[PerformanceMetric]
)
async def get_supplier_performance_metrics(
    tenant_id: UUID = Path(...),
    supplier_id: UUID = Path(...),
    metric_type: Optional[PerformanceMetricType] = Query(None),
    period: Optional[PerformancePeriod] = Query(None),
    date_from: Optional[datetime] = Query(None),
    date_to: Optional[datetime] = Query(None),
    limit: int = Query(50, ge=1, le=500),
    current_user: dict = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """Get performance metrics for a supplier"""
    try:
        from app.models.performance import SupplierPerformanceMetric
        from sqlalchemy import select, and_, desc

        # Build query for performance metrics
        query = select(SupplierPerformanceMetric).where(
            and_(
                SupplierPerformanceMetric.supplier_id == supplier_id,
                SupplierPerformanceMetric.tenant_id == tenant_id
            )
        )

        # Apply filters
        if metric_type:
            query = query.where(SupplierPerformanceMetric.metric_type == metric_type)

        if date_from:
            query = query.where(SupplierPerformanceMetric.calculated_at >= date_from)

        if date_to:
            query = query.where(SupplierPerformanceMetric.calculated_at <= date_to)

        # Order by most recent and apply limit
        query = query.order_by(desc(SupplierPerformanceMetric.calculated_at)).limit(limit)

        result = await db.execute(query)
        metrics = result.scalars().all()

        logger.info("Retrieved performance metrics",
                   tenant_id=str(tenant_id),
                   supplier_id=str(supplier_id),
                   count=len(metrics))

        return metrics

    except Exception as e:
        logger.error("Error getting performance metrics",
                    tenant_id=str(tenant_id),
                    supplier_id=str(supplier_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to retrieve performance metrics"
        )


# ===== Alert Management =====

@router.post(
    route_builder.build_analytics_route("performance/alerts/evaluate"),
    response_model=List[Alert]
)
@require_user_role(['admin', 'owner'])
async def evaluate_performance_alerts(
    tenant_id: UUID = Path(...),
    supplier_id: Optional[UUID] = Query(None, description="Specific supplier to evaluate"),
    current_user: dict = Depends(get_current_user_dep),
    alert_service: AlertService = Depends(get_alert_service),
    db: AsyncSession = Depends(get_db)
):
    """Evaluate and create performance-based alerts"""
    try:
        alerts = await alert_service.evaluate_performance_alerts(db, tenant_id, supplier_id)

        logger.info("Performance alerts evaluated",
                   tenant_id=str(tenant_id),
                   alerts_created=len(alerts))

        return alerts

    except Exception as e:
        logger.error("Error evaluating performance alerts",
                    tenant_id=str(tenant_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to evaluate performance alerts"
        )


@router.get(
    route_builder.build_analytics_route("performance/alerts"),
    response_model=List[Alert]
)
async def get_supplier_alerts(
    tenant_id: UUID = Path(...),
    supplier_id: Optional[UUID] = Query(None),
    alert_type: Optional[AlertType] = Query(None),
    severity: Optional[AlertSeverity] = Query(None),
    date_from: Optional[datetime] = Query(None),
    date_to: Optional[datetime] = Query(None),
    limit: int = Query(50, ge=1, le=500),
    current_user: dict = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """Get supplier alerts with filtering"""
    try:
        from app.models.performance import SupplierAlert
        from sqlalchemy import select, and_, desc

        # Build query for alerts
        query = select(SupplierAlert).where(
            SupplierAlert.tenant_id == tenant_id
        )

        # Apply filters
        if supplier_id:
            query = query.where(SupplierAlert.supplier_id == supplier_id)

        if alert_type:
            query = query.where(SupplierAlert.alert_type == alert_type)

        if severity:
            query = query.where(SupplierAlert.severity == severity)

        if date_from:
            query = query.where(SupplierAlert.created_at >= date_from)

        if date_to:
            query = query.where(SupplierAlert.created_at <= date_to)

        # Order by most recent and apply limit
        query = query.order_by(desc(SupplierAlert.created_at)).limit(limit)

        result = await db.execute(query)
        alerts = result.scalars().all()

        logger.info("Retrieved supplier alerts",
                   tenant_id=str(tenant_id),
                   count=len(alerts))

        return alerts

    except Exception as e:
        logger.error("Error getting supplier alerts",
                    tenant_id=str(tenant_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to retrieve supplier alerts"
        )


@router.get(
    route_builder.build_analytics_route("performance/alerts/summary"),
    response_model=List[AlertSummary]
)
async def get_alert_summary(
    tenant_id: UUID = Path(...),
    date_from: Optional[datetime] = Query(None),
    date_to: Optional[datetime] = Query(None),
    current_user: dict = Depends(get_current_user_dep),
    dashboard_service: DashboardService = Depends(get_dashboard_service),
    db: AsyncSession = Depends(get_db)
):
    """Get alert summary by type and severity"""
    try:
        summary = await dashboard_service.get_alert_summary(db, tenant_id, date_from, date_to)

        return summary

    except Exception as e:
        logger.error("Error getting alert summary",
                    tenant_id=str(tenant_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to retrieve alert summary"
        )


# ===== Dashboard Analytics =====

@router.get(
    route_builder.build_dashboard_route("performance/summary"),
    response_model=PerformanceDashboardSummary
)
async def get_performance_dashboard_summary(
    tenant_id: UUID = Path(...),
    date_from: Optional[datetime] = Query(None),
    date_to: Optional[datetime] = Query(None),
    current_user: dict = Depends(get_current_user_dep),
    dashboard_service: DashboardService = Depends(get_dashboard_service),
    db: AsyncSession = Depends(get_db)
):
    """Get comprehensive performance dashboard summary"""
    try:
        summary = await dashboard_service.get_performance_dashboard_summary(
            db, tenant_id, date_from, date_to
        )

        logger.info("Performance dashboard summary retrieved",
                   tenant_id=str(tenant_id))

        return summary

    except Exception as e:
        logger.error("Error getting dashboard summary",
                    tenant_id=str(tenant_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to retrieve dashboard summary"
        )


@router.get(
    route_builder.build_analytics_route("performance/{supplier_id}/insights"),
    response_model=SupplierPerformanceInsights
)
async def get_supplier_performance_insights(
    tenant_id: UUID = Path(...),
    supplier_id: UUID = Path(...),
    days_back: int = Query(30, ge=1, le=365),
    current_user: dict = Depends(get_current_user_dep),
    dashboard_service: DashboardService = Depends(get_dashboard_service),
    db: AsyncSession = Depends(get_db)
):
    """Get detailed performance insights for a specific supplier"""
    try:
        insights = await dashboard_service.get_supplier_performance_insights(
            db, tenant_id, supplier_id, days_back
        )

        logger.info("Supplier performance insights retrieved",
                   tenant_id=str(tenant_id),
                   supplier_id=str(supplier_id))

        return insights

    except Exception as e:
        logger.error("Error getting supplier insights",
                    tenant_id=str(tenant_id),
                    supplier_id=str(supplier_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to retrieve supplier insights"
        )


@router.get(
    route_builder.build_analytics_route("performance/performance"),
    response_model=PerformanceAnalytics
)
@analytics_tier_required
async def get_performance_analytics(
    tenant_id: UUID = Path(...),
    period_days: int = Query(90, ge=1, le=365),
    current_user: dict = Depends(get_current_user_dep),
    dashboard_service: DashboardService = Depends(get_dashboard_service),
    db: AsyncSession = Depends(get_db)
):
    """Get advanced performance analytics"""
    try:
        analytics = await dashboard_service.get_performance_analytics(
            db, tenant_id, period_days
        )

        logger.info("Performance analytics retrieved",
                   tenant_id=str(tenant_id),
                   period_days=period_days)

        return analytics

    except Exception as e:
        logger.error("Error getting performance analytics",
                    tenant_id=str(tenant_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to retrieve performance analytics"
        )


@router.get(
    route_builder.build_analytics_route("performance/business-model"),
    response_model=BusinessModelInsights
)
@analytics_tier_required
async def get_business_model_insights(
    tenant_id: UUID = Path(...),
    current_user: dict = Depends(get_current_user_dep),
    dashboard_service: DashboardService = Depends(get_dashboard_service),
    db: AsyncSession = Depends(get_db)
):
    """Get business model detection and insights"""
    try:
        insights = await dashboard_service.get_business_model_insights(db, tenant_id)

        logger.info("Business model insights retrieved",
                   tenant_id=str(tenant_id),
                   detected_model=insights.detected_model)

        return insights

    except Exception as e:
        logger.error("Error getting business model insights",
                    tenant_id=str(tenant_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to retrieve business model insights"
        )


# ===== Export and Reporting =====

@router.post(
    route_builder.build_analytics_route("performance/reports/generate"),
    response_model=ExportDataResponse
)
@require_user_role(['admin', 'owner'])
async def generate_performance_report(
    report_request: PerformanceReportRequest,
    tenant_id: UUID = Path(...),
    current_user: dict = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """Generate a performance report"""
    try:
        # TODO: Implement report generation
        raise HTTPException(
            status_code=status.HTTP_501_NOT_IMPLEMENTED,
            detail="Report generation not yet implemented"
        )

    except Exception as e:
        logger.error("Error generating performance report",
                    tenant_id=str(tenant_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to generate performance report"
        )


@router.get(
    route_builder.build_analytics_route("performance/export")
)
async def export_performance_data(
    tenant_id: UUID = Path(...),
    format: str = Query("json", description="Export format: json, csv, excel"),
    date_from: Optional[datetime] = Query(None),
    date_to: Optional[datetime] = Query(None),
    supplier_ids: Optional[List[UUID]] = Query(None),
    current_user: dict = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """Export performance data"""
    try:
        if format.lower() not in ["json", "csv", "excel"]:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="Unsupported export format. Use: json, csv, excel"
            )

        # TODO: Implement data export
        raise HTTPException(
            status_code=status.HTTP_501_NOT_IMPLEMENTED,
            detail="Data export not yet implemented"
        )

    except Exception as e:
        logger.error("Error exporting performance data",
                    tenant_id=str(tenant_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to export performance data"
        )


# ===== Configuration and Health =====

@router.get(
    route_builder.build_analytics_route("performance/config")
)
async def get_performance_config(
    tenant_id: UUID = Path(...),
    current_user: dict = Depends(get_current_user_dep)
):
    """Get performance tracking configuration"""
    try:
        from app.core.config import settings

        config = {
            "performance_tracking": {
                "enabled": settings.PERFORMANCE_TRACKING_ENABLED,
                "calculation_interval_minutes": settings.PERFORMANCE_CALCULATION_INTERVAL_MINUTES,
                "cache_ttl_seconds": settings.PERFORMANCE_CACHE_TTL
            },
            "thresholds": {
                "excellent_delivery_rate": settings.EXCELLENT_DELIVERY_RATE,
                "good_delivery_rate": settings.GOOD_DELIVERY_RATE,
                "acceptable_delivery_rate": settings.ACCEPTABLE_DELIVERY_RATE,
                "poor_delivery_rate": settings.POOR_DELIVERY_RATE,
                "excellent_quality_rate": settings.EXCELLENT_QUALITY_RATE,
                "good_quality_rate": settings.GOOD_QUALITY_RATE,
                "acceptable_quality_rate": settings.ACCEPTABLE_QUALITY_RATE,
                "poor_quality_rate": settings.POOR_QUALITY_RATE
            },
            "alerts": {
                "enabled": settings.ALERTS_ENABLED,
                "evaluation_interval_minutes": settings.ALERT_EVALUATION_INTERVAL_MINUTES,
                "retention_days": settings.ALERT_RETENTION_DAYS,
                "critical_delivery_delay_hours": settings.CRITICAL_DELIVERY_DELAY_HOURS,
                "critical_quality_rejection_rate": settings.CRITICAL_QUALITY_REJECTION_RATE
            },
            "dashboard": {
                "cache_ttl_seconds": settings.DASHBOARD_CACHE_TTL,
                "refresh_interval_seconds": settings.DASHBOARD_REFRESH_INTERVAL,
                "default_analytics_period_days": settings.DEFAULT_ANALYTICS_PERIOD_DAYS
            },
            "business_model": {
                "detection_enabled": settings.ENABLE_BUSINESS_MODEL_DETECTION,
                "central_bakery_threshold": settings.CENTRAL_BAKERY_THRESHOLD_SUPPLIERS,
                "individual_bakery_threshold": settings.INDIVIDUAL_BAKERY_THRESHOLD_SUPPLIERS
            }
        }

        return config

    except Exception as e:
        logger.error("Error getting performance config",
                    tenant_id=str(tenant_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to retrieve performance configuration"
        )


@router.get(
    route_builder.build_analytics_route("performance/health")
)
async def get_performance_health(
    tenant_id: UUID = Path(...),
    current_user: dict = Depends(get_current_user_dep)
):
    """Get performance service health status"""
    try:
        return {
            "service": "suppliers-performance",
            "status": "healthy",
            "timestamp": datetime.now().isoformat(),
            "tenant_id": str(tenant_id),
            "features": {
                "performance_tracking": "enabled",
                "alerts": "enabled",
                "dashboard_analytics": "enabled",
                "business_model_detection": "enabled"
            }
        }

    except Exception as e:
        logger.error("Error getting performance health",
                    tenant_id=str(tenant_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to get performance health status"
        )
