# ================================================================
# services/forecasting/app/jobs/sales_data_listener.py
# ================================================================
"""
Sales Data Listener

Listens for sales data import completions and triggers validation backfill.
Can be called via webhook, message queue, or direct API call from sales service.
"""

from typing import Dict, Any, Optional
from datetime import datetime, date
import structlog
import uuid

from app.services.historical_validation_service import HistoricalValidationService
from app.core.database import database_manager

logger = structlog.get_logger()


async def handle_sales_import_completion(
    tenant_id: uuid.UUID,
    import_job_id: str,
    start_date: date,
    end_date: date,
    records_count: int,
    import_source: str = "import"
) -> Dict[str, Any]:
    """
    Handle sales data import completion event

    This function is called when the sales service completes a data import.
    It registers the update and triggers validation for the imported date range.

    Args:
        tenant_id: Tenant identifier
        import_job_id: Sales import job ID
        start_date: Start date of imported data
        end_date: End date of imported data
        records_count: Number of records imported
        import_source: Source of import (csv, xlsx, api, pos_sync)

    Returns:
        Dictionary with registration and validation results
    """
    async with database_manager.get_session() as db:
        try:
            logger.info(
                "Handling sales import completion",
                tenant_id=tenant_id,
                import_job_id=import_job_id,
                date_range=f"{start_date} to {end_date}",
                records_count=records_count
            )

            service = HistoricalValidationService(db)

            # Register the sales data update and trigger validation
            result = await service.register_sales_data_update(
                tenant_id=tenant_id,
                start_date=start_date,
                end_date=end_date,
                records_affected=records_count,
                update_source=import_source,
                import_job_id=import_job_id,
                auto_trigger_validation=True
            )

            logger.info(
                "Sales import completion handled",
                tenant_id=tenant_id,
                import_job_id=import_job_id,
                update_id=result.get("update_id"),
                validation_triggered=result.get("validation_triggered")
            )

            return {
                "status": "success",
                "tenant_id": str(tenant_id),
                "import_job_id": import_job_id,
                **result
            }

        except Exception as e:
            logger.error(
                "Failed to handle sales import completion",
                tenant_id=tenant_id,
                import_job_id=import_job_id,
                error=str(e),
                error_type=type(e).__name__
            )
            return {
                "status": "failed",
                "error": str(e),
                "tenant_id": str(tenant_id),
                "import_job_id": import_job_id
            }


async def handle_pos_sync_completion(
    tenant_id: uuid.UUID,
    sync_log_id: str,
    sync_date: date,
    records_synced: int
) -> Dict[str, Any]:
    """
    Handle POS sync completion event

    Called when POS data is synchronized to the sales service.

    Args:
        tenant_id: Tenant identifier
        sync_log_id: POS sync log ID
        sync_date: Date of synced data
        records_synced: Number of records synced

    Returns:
        Dictionary with registration and validation results
    """
    async with database_manager.get_session() as db:
        try:
            logger.info(
                "Handling POS sync completion",
                tenant_id=tenant_id,
                sync_log_id=sync_log_id,
                sync_date=sync_date.isoformat(),
                records_synced=records_synced
            )

            service = HistoricalValidationService(db)

            # For POS syncs, we typically validate just the sync date
            result = await service.register_sales_data_update(
                tenant_id=tenant_id,
                start_date=sync_date,
                end_date=sync_date,
                records_affected=records_synced,
                update_source="pos_sync",
                import_job_id=sync_log_id,
                auto_trigger_validation=True
            )

            logger.info(
                "POS sync completion handled",
                tenant_id=tenant_id,
                sync_log_id=sync_log_id,
                update_id=result.get("update_id")
            )

            return {
                "status": "success",
                "tenant_id": str(tenant_id),
                "sync_log_id": sync_log_id,
                **result
            }

        except Exception as e:
            logger.error(
                "Failed to handle POS sync completion",
                tenant_id=tenant_id,
                sync_log_id=sync_log_id,
                error=str(e)
            )
            return {
                "status": "failed",
                "error": str(e),
                "tenant_id": str(tenant_id),
                "sync_log_id": sync_log_id
            }


async def process_pending_validations(
    tenant_id: Optional[uuid.UUID] = None,
    max_to_process: int = 10
) -> Dict[str, Any]:
    """
    Process pending validation requests

    Can be run as a scheduled job to handle any pending validations
    that failed to trigger automatically.

    Args:
        tenant_id: Optional tenant ID to filter (process all tenants if None)
        max_to_process: Maximum number of pending validations to process

    Returns:
        Summary of processing results
    """
    async with database_manager.get_session() as db:
        try:
            logger.info(
                "Processing pending validations",
                tenant_id=tenant_id,
                max_to_process=max_to_process
            )

            service = HistoricalValidationService(db)

            if tenant_id:
                # Process specific tenant
                pending = await service.get_pending_validations(
                    tenant_id=tenant_id,
                    limit=max_to_process
                )
            else:
                # Would need to implement get_all_pending_validations for all tenants
                # For now, require tenant_id
                logger.warning("Processing all tenants not implemented, tenant_id required")
                return {
                    "status": "skipped",
                    "message": "tenant_id required"
                }

            if not pending:
                logger.info("No pending validations found")
                return {
                    "status": "success",
                    "pending_count": 0,
                    "processed": 0
                }

            results = []
            for update_record in pending:
                try:
                    result = await service.backfill_validation(
                        tenant_id=update_record.tenant_id,
                        start_date=update_record.update_date_start,
                        end_date=update_record.update_date_end,
                        triggered_by="pending_processor",
                        sales_data_update_id=update_record.id
                    )
                    results.append({
                        "update_id": str(update_record.id),
                        "status": "success",
                        "validation_run_id": result.get("validation_run_id")
                    })
                except Exception as e:
                    logger.error(
                        "Failed to process pending validation",
                        update_id=update_record.id,
                        error=str(e)
                    )
                    results.append({
                        "update_id": str(update_record.id),
                        "status": "failed",
                        "error": str(e)
                    })

            successful = sum(1 for r in results if r["status"] == "success")

            logger.info(
                "Pending validations processed",
                pending_count=len(pending),
                processed=len(results),
                successful=successful
            )

            return {
                "status": "success",
                "pending_count": len(pending),
                "processed": len(results),
                "successful": successful,
                "failed": len(results) - successful,
                "results": results
            }

        except Exception as e:
            logger.error(
                "Failed to process pending validations",
                error=str(e)
            )
            return {
                "status": "failed",
                "error": str(e)
            }
