# services/sales/app/api/import_data.py
"""
Sales Data Import API Endpoints
"""

from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form, Path
from typing import Dict, Any, Optional
from uuid import UUID
import structlog
import json

from app.services.data_import_service import DataImportService
from shared.auth.decorators import get_current_user_dep

router = APIRouter(tags=["data-import"])
logger = structlog.get_logger()


def get_import_service():
    """Dependency injection for DataImportService"""
    return DataImportService()


@router.post("/tenants/{tenant_id}/sales/import/validate-json")
async def validate_json_data(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    data: Dict[str, Any] = None,
    current_user: Dict[str, Any] = Depends(get_current_user_dep),
    import_service: DataImportService = Depends(get_import_service)
):
    """Validate JSON sales data"""
    try:
        
        if not data:
            raise HTTPException(status_code=400, detail="No data provided")
        
        logger.info("Validating JSON data", tenant_id=tenant_id, record_count=len(data.get("records", [])))
        
        # Validate the data - handle different input formats
        if "records" in data:
            # New format with records array
            validation_data = {
                "tenant_id": str(tenant_id),
                "data": json.dumps(data.get("records", [])),
                "data_format": "json"
            }
        else:
            # Legacy format where the entire payload is the validation data
            validation_data = data.copy()
            validation_data["tenant_id"] = str(tenant_id)
            if "data_format" not in validation_data:
                validation_data["data_format"] = "json"
        
        validation_result = await import_service.validate_import_data(validation_data)
        
        logger.info("JSON validation completed", tenant_id=tenant_id, valid=validation_result.is_valid)
        
        return {
            "is_valid": validation_result.is_valid,
            "total_records": validation_result.total_records,
            "valid_records": validation_result.valid_records,
            "invalid_records": validation_result.invalid_records,
            "errors": validation_result.errors,
            "warnings": validation_result.warnings,
            "summary": validation_result.summary
        }
        
    except Exception as e:
        logger.error("Failed to validate JSON data", error=str(e), tenant_id=tenant_id)
        raise HTTPException(status_code=500, detail=f"Failed to validate data: {str(e)}")


@router.post("/tenants/{tenant_id}/sales/import/validate")
async def validate_sales_data_universal(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    file: Optional[UploadFile] = File(None),
    data: Optional[Dict[str, Any]] = None,
    file_format: Optional[str] = Form(None),
    current_user: Dict[str, Any] = Depends(get_current_user_dep),
    import_service: DataImportService = Depends(get_import_service)
):
    """Universal validation endpoint for sales data - supports files and JSON"""
    try:
        # Debug logging at the start
        logger.info("=== VALIDATION ENDPOINT CALLED ===", 
                   tenant_id=tenant_id,
                   file_present=file is not None,
                   file_filename=file.filename if file else None,
                   data_present=data is not None,
                   file_format=file_format)
        
        # Handle file upload validation
        if file and file.filename:
            logger.info("Processing file upload branch", tenant_id=tenant_id, filename=file.filename)
            
            # Auto-detect format from filename
            filename = file.filename.lower()
            if filename.endswith('.csv'):
                detected_format = 'csv'
            elif filename.endswith('.xlsx') or filename.endswith('.xls'):
                detected_format = 'excel'
            elif filename.endswith('.json'):
                detected_format = 'json'
            else:
                detected_format = file_format or 'csv'  # Default to CSV
            
            # Read file content
            content = await file.read()
            
            if detected_format in ['xlsx', 'xls', 'excel']:
                # For Excel files, encode as base64
                import base64
                file_content = base64.b64encode(content).decode('utf-8')
            else:
                # For CSV/JSON, decode as text
                file_content = content.decode('utf-8')
            
            validation_data = {
                "tenant_id": str(tenant_id),
                "data": file_content,
                "data_format": detected_format,
                "filename": file.filename
            }
            
        # Handle JSON data validation  
        elif data:
            logger.info("Processing JSON data branch", tenant_id=tenant_id, data_keys=list(data.keys()) if data else [])
            
            validation_data = data.copy()
            validation_data["tenant_id"] = str(tenant_id)
            if "data_format" not in validation_data:
                validation_data["data_format"] = "json"
        
        else:
            logger.error("No file or data provided", tenant_id=tenant_id, file_present=file is not None, data_present=data is not None)
            raise HTTPException(status_code=400, detail="No file or data provided for validation")
        
        # Perform validation
        logger.info("About to call validate_import_data", validation_data_keys=list(validation_data.keys()), data_size=len(validation_data.get("data", "")))
        validation_result = await import_service.validate_import_data(validation_data)
        logger.info("Validation completed", is_valid=validation_result.is_valid, errors_count=len(validation_result.errors))
        
        logger.info("Validation completed", 
                   tenant_id=tenant_id, 
                   valid=validation_result.is_valid,
                   total_records=validation_result.total_records)
        
        return {
            "is_valid": validation_result.is_valid,
            "total_records": validation_result.total_records,
            "valid_records": validation_result.valid_records,
            "invalid_records": validation_result.invalid_records,
            "errors": validation_result.errors,
            "warnings": validation_result.warnings,
            "summary": validation_result.summary,
            "unique_products": validation_result.unique_products,
            "product_list": validation_result.product_list,
            "message": "Validation completed successfully" if validation_result.is_valid else "Validation found errors",
            "details": {
                "total_records": validation_result.total_records,
                "format": validation_data.get("data_format", "unknown")
            }
        }
        
    except Exception as e:
        error_msg = str(e) if e else "Unknown error occurred during validation"
        logger.error("Failed to validate sales data", error=error_msg, tenant_id=tenant_id, exc_info=True)
        raise HTTPException(status_code=500, detail=f"Failed to validate data: {error_msg}")


@router.post("/tenants/{tenant_id}/sales/import/validate-csv")
async def validate_csv_data_legacy(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    file: UploadFile = File(...),
    current_user: Dict[str, Any] = Depends(get_current_user_dep),
    import_service: DataImportService = Depends(get_import_service)
):
    """Legacy CSV validation endpoint - redirects to universal validator"""
    return await validate_sales_data_universal(
        tenant_id=tenant_id,
        file=file,
        current_user=current_user,
        import_service=import_service
    )


@router.post("/tenants/{tenant_id}/sales/import")
async def import_sales_data(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    data: Optional[Dict[str, Any]] = None,
    file: Optional[UploadFile] = File(None),
    file_format: Optional[str] = Form(None),
    update_existing: bool = Form(False, description="Whether to update existing records"),
    current_user: Dict[str, Any] = Depends(get_current_user_dep),
    import_service: DataImportService = Depends(get_import_service)
):
    """Enhanced import sales data - supports multiple file formats and JSON"""
    try:
        
        # Handle file upload (form data)
        if file:
            if not file.filename:
                raise HTTPException(status_code=400, detail="No file provided")
            
            logger.info("Starting enhanced file import", tenant_id=tenant_id, filename=file.filename)
            
            # Auto-detect format from filename
            filename = file.filename.lower()
            if filename.endswith('.csv'):
                detected_format = 'csv'
            elif filename.endswith('.xlsx') or filename.endswith('.xls'):
                detected_format = 'excel'
            elif filename.endswith('.json'):
                detected_format = 'json'
            else:
                detected_format = file_format or 'csv'  # Default to CSV
            
            # Read file content
            content = await file.read()
            
            if detected_format in ['xlsx', 'xls', 'excel']:
                # For Excel files, encode as base64
                import base64
                file_content = base64.b64encode(content).decode('utf-8')
            else:
                # For CSV/JSON, decode as text
                file_content = content.decode('utf-8')
                
            # Import the file using enhanced service
            import_result = await import_service.process_import(
                str(tenant_id),  # Ensure string type
                file_content,
                detected_format,
                filename=file.filename
            )
            
        # Handle JSON data
        elif data:
            logger.info("Starting enhanced JSON data import", tenant_id=tenant_id, record_count=len(data.get("records", [])))
            
            # Import the data - handle different input formats
            if "records" in data:
                # New format with records array  
                records_json = json.dumps(data.get("records", []))
                import_result = await import_service.process_import(
                    str(tenant_id),
                    records_json,
                    "json"
                )
            else:
                # Legacy format - data field contains the data directly
                import_result = await import_service.process_import(
                    str(tenant_id),
                    data.get("data", ""),
                    data.get("data_format", "json")
                )
        else:
            raise HTTPException(status_code=400, detail="No data or file provided")
        
        logger.info("Enhanced import completed", 
                   tenant_id=tenant_id, 
                   created=import_result.records_created,
                   updated=import_result.records_updated,
                   failed=import_result.records_failed,
                   processing_time=import_result.processing_time_seconds)
        
        # Return enhanced response matching frontend expectations
        response = {
            "success": import_result.success,
            "records_processed": import_result.records_processed,
            "records_created": import_result.records_created,
            "records_updated": import_result.records_updated,
            "records_failed": import_result.records_failed,
            "errors": import_result.errors,
            "warnings": import_result.warnings,
            "processing_time_seconds": import_result.processing_time_seconds,
            "records_imported": import_result.records_created,  # Frontend compatibility
            "message": f"Successfully imported {import_result.records_created} records" if import_result.success else "Import completed with errors"
        }
        
        # Add file-specific information if available
        if file:
            response["file_info"] = {
                "name": file.filename,
                "format": detected_format,
                "size_bytes": len(content) if 'content' in locals() else 0
            }
        
        return response
        
    except Exception as e:
        logger.error("Failed to import sales data", error=str(e), tenant_id=tenant_id, exc_info=True)
        raise HTTPException(status_code=500, detail=f"Failed to import data: {str(e)}")


@router.post("/tenants/{tenant_id}/sales/import/csv")
async def import_csv_data(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    file: UploadFile = File(...),
    update_existing: bool = Form(False, description="Whether to update existing records"),
    current_user: Dict[str, Any] = Depends(get_current_user_dep),
    import_service: DataImportService = Depends(get_import_service)
):
    """Import CSV sales data file"""
    try:
        
        if not file.filename.endswith('.csv'):
            raise HTTPException(status_code=400, detail="File must be a CSV file")
        
        logger.info("Starting CSV data import", tenant_id=tenant_id, filename=file.filename)
        
        # Read file content
        content = await file.read()
        file_content = content.decode('utf-8')
        
        # Import the data
        import_result = await import_service.process_import(
            tenant_id,
            file_content,
            "csv",
            filename=file.filename
        )
        
        logger.info("CSV import completed", 
                   tenant_id=tenant_id, 
                   filename=file.filename,
                   created=import_result.records_created,
                   updated=import_result.records_updated,
                   failed=import_result.records_failed)
        
        return {
            "success": import_result.success,
            "records_processed": import_result.records_processed,
            "records_created": import_result.records_created,
            "records_updated": import_result.records_updated,
            "records_failed": import_result.records_failed,
            "errors": import_result.errors,
            "warnings": import_result.warnings,
            "processing_time_seconds": import_result.processing_time_seconds
        }
        
    except Exception as e:
        logger.error("Failed to import CSV data", error=str(e), tenant_id=tenant_id)
        raise HTTPException(status_code=500, detail=f"Failed to import CSV data: {str(e)}")


@router.get("/tenants/{tenant_id}/sales/import/template")
async def get_import_template(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    format: str = "csv"
):
    """Get sales data import template"""
    try:
        
        if format not in ["csv", "json"]:
            raise HTTPException(status_code=400, detail="Format must be 'csv' or 'json'")
        
        if format == "csv":
            template = "date,product_name,product_category,product_sku,quantity_sold,unit_price,revenue,cost_of_goods,discount_applied,location_id,sales_channel,source,notes,weather_condition,is_holiday,is_weekend"
        else:
            template = {
                "records": [
                    {
                        "date": "2024-01-01T10:00:00Z",
                        "product_name": "Sample Product",
                        "product_category": "Sample Category", 
                        "product_sku": "SAMPLE001",
                        "quantity_sold": 1,
                        "unit_price": 10.50,
                        "revenue": 10.50,
                        "cost_of_goods": 5.25,
                        "discount_applied": 0.0,
                        "location_id": "LOC001",
                        "sales_channel": "in_store",
                        "source": "manual",
                        "notes": "Sample sales record",
                        "weather_condition": "sunny",
                        "is_holiday": False,
                        "is_weekend": False
                    }
                ]
            }
        
        return {"template": template, "format": format}
        
    except Exception as e:
        logger.error("Failed to get import template", error=str(e), tenant_id=tenant_id)
        raise HTTPException(status_code=500, detail=f"Failed to get import template: {str(e)}")