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

from fastapi import APIRouter, Depends, HTTPException, Query, Path
from typing import List, Optional, Dict, Any
from uuid import UUID
from datetime import datetime
import structlog

from app.schemas.sales import (
    SalesDataCreate, 
    SalesDataUpdate,
    SalesDataResponse, 
    SalesDataQuery
)
from app.services.sales_service import SalesService
from shared.auth.decorators import get_current_user_dep

router = APIRouter(tags=["sales"])
logger = structlog.get_logger()


def get_sales_service():
    """Dependency injection for SalesService"""
    return SalesService()


@router.post("/tenants/{tenant_id}/sales", response_model=SalesDataResponse)
async def create_sales_record(
    sales_data: SalesDataCreate,
    tenant_id: UUID = Path(..., description="Tenant ID"),
    current_user: Dict[str, Any] = Depends(get_current_user_dep),
    sales_service: SalesService = Depends(get_sales_service)
):
    """Create a new sales record"""
    try:
        logger.info(
            "Creating sales record", 
            product=sales_data.product_name, 
            quantity=sales_data.quantity_sold,
            tenant_id=tenant_id,
            user_id=current_user.get("user_id")
        )
        
        # Create the record
        record = await sales_service.create_sales_record(
            sales_data, 
            tenant_id, 
            user_id=UUID(current_user["user_id"]) if current_user.get("user_id") else None
        )
        
        logger.info("Successfully created sales record", record_id=record.id, tenant_id=tenant_id)
        return record
        
    except ValueError as ve:
        logger.warning("Validation error creating sales record", error=str(ve), tenant_id=tenant_id)
        raise HTTPException(status_code=400, detail=str(ve))
    except Exception as e:
        logger.error("Failed to create sales record", error=str(e), tenant_id=tenant_id)
        raise HTTPException(status_code=500, detail=f"Failed to create sales record: {str(e)}")


@router.get("/tenants/{tenant_id}/sales", response_model=List[SalesDataResponse])
async def get_sales_records(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    start_date: Optional[datetime] = Query(None, description="Start date filter"),
    end_date: Optional[datetime] = Query(None, description="End date filter"),
    product_name: Optional[str] = Query(None, description="Product name filter"),
    product_category: Optional[str] = Query(None, description="Product category filter"),
    location_id: Optional[str] = Query(None, description="Location filter"),
    sales_channel: Optional[str] = Query(None, description="Sales channel filter"),
    source: Optional[str] = Query(None, description="Data source filter"),
    is_validated: Optional[bool] = Query(None, description="Validation status filter"),
    limit: int = Query(50, ge=1, le=1000, description="Number of records to return"),
    offset: int = Query(0, ge=0, description="Number of records to skip"),
    order_by: str = Query("date", description="Field to order by"),
    order_direction: str = Query("desc", description="Order direction (asc/desc)"),
    sales_service: SalesService = Depends(get_sales_service)
):
    """Get sales records for a tenant with filtering and pagination"""
    try:
        # Build query parameters
        query_params = SalesDataQuery(
            start_date=start_date,
            end_date=end_date,
            product_name=product_name,
            product_category=product_category,
            location_id=location_id,
            sales_channel=sales_channel,
            source=source,
            is_validated=is_validated,
            limit=limit,
            offset=offset,
            order_by=order_by,
            order_direction=order_direction
        )
        
        records = await sales_service.get_sales_records(tenant_id, query_params)
        
        logger.info("Retrieved sales records", count=len(records), tenant_id=tenant_id)
        return records
        
    except Exception as e:
        logger.error("Failed to get sales records", error=str(e), tenant_id=tenant_id)
        raise HTTPException(status_code=500, detail=f"Failed to get sales records: {str(e)}")




@router.get("/tenants/{tenant_id}/sales/analytics/summary")
async def get_sales_analytics(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    start_date: Optional[datetime] = Query(None, description="Start date filter"),
    end_date: Optional[datetime] = Query(None, description="End date filter"),
    sales_service: SalesService = Depends(get_sales_service)
):
    """Get sales analytics summary for a tenant"""
    try:
        analytics = await sales_service.get_sales_analytics(tenant_id, start_date, end_date)
        
        logger.info("Retrieved sales analytics", tenant_id=tenant_id)
        return analytics
        
    except Exception as e:
        logger.error("Failed to get sales analytics", error=str(e), tenant_id=tenant_id)
        raise HTTPException(status_code=500, detail=f"Failed to get sales analytics: {str(e)}")


@router.get("/tenants/{tenant_id}/inventory-products/{inventory_product_id}/sales", response_model=List[SalesDataResponse])
async def get_product_sales(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    inventory_product_id: UUID = Path(..., description="Inventory product ID"),
    start_date: Optional[datetime] = Query(None, description="Start date filter"),
    end_date: Optional[datetime] = Query(None, description="End date filter"),
    sales_service: SalesService = Depends(get_sales_service)
):
    """Get sales records for a specific product"""
    try:
        records = await sales_service.get_product_sales(tenant_id, inventory_product_id, start_date, end_date)
        
        logger.info("Retrieved product sales", count=len(records), inventory_product_id=inventory_product_id, tenant_id=tenant_id)
        return records
        
    except Exception as e:
        logger.error("Failed to get product sales", error=str(e), tenant_id=tenant_id, inventory_product_id=inventory_product_id)
        raise HTTPException(status_code=500, detail=f"Failed to get product sales: {str(e)}")


@router.get("/tenants/{tenant_id}/sales/categories", response_model=List[str])
async def get_product_categories(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    sales_service: SalesService = Depends(get_sales_service)
):
    """Get distinct product categories from sales data"""
    try:
        categories = await sales_service.get_product_categories(tenant_id)
        
        return categories
        
    except Exception as e:
        logger.error("Failed to get product categories", error=str(e), tenant_id=tenant_id)
        raise HTTPException(status_code=500, detail=f"Failed to get product categories: {str(e)}")


# ================================================================
# PARAMETERIZED ROUTES - Keep these at the end to avoid conflicts
# ================================================================

@router.get("/tenants/{tenant_id}/sales/{record_id}", response_model=SalesDataResponse)
async def get_sales_record(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    record_id: UUID = Path(..., description="Sales record ID"),
    sales_service: SalesService = Depends(get_sales_service)
):
    """Get a specific sales record"""
    try:
        record = await sales_service.get_sales_record(record_id, tenant_id)
        
        if not record:
            raise HTTPException(status_code=404, detail="Sales record not found")
        
        return record
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error("Failed to get sales record", error=str(e), record_id=record_id, tenant_id=tenant_id)
        raise HTTPException(status_code=500, detail=f"Failed to get sales record: {str(e)}")


@router.put("/tenants/{tenant_id}/sales/{record_id}", response_model=SalesDataResponse)
async def update_sales_record(
    update_data: SalesDataUpdate,
    tenant_id: UUID = Path(..., description="Tenant ID"),
    record_id: UUID = Path(..., description="Sales record ID"),
    sales_service: SalesService = Depends(get_sales_service)
):
    """Update a sales record"""
    try:
        updated_record = await sales_service.update_sales_record(record_id, update_data, tenant_id)
        
        logger.info("Updated sales record", record_id=record_id, tenant_id=tenant_id)
        return updated_record
        
    except ValueError as ve:
        logger.warning("Validation error updating sales record", error=str(ve), record_id=record_id)
        raise HTTPException(status_code=400, detail=str(ve))
    except Exception as e:
        logger.error("Failed to update sales record", error=str(e), record_id=record_id, tenant_id=tenant_id)
        raise HTTPException(status_code=500, detail=f"Failed to update sales record: {str(e)}")


@router.delete("/tenants/{tenant_id}/sales/{record_id}")
async def delete_sales_record(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    record_id: UUID = Path(..., description="Sales record ID"),
    sales_service: SalesService = Depends(get_sales_service)
):
    """Delete a sales record"""
    try:
        success = await sales_service.delete_sales_record(record_id, tenant_id)
        
        if not success:
            raise HTTPException(status_code=404, detail="Sales record not found")
        
        logger.info("Deleted sales record", record_id=record_id, tenant_id=tenant_id)
        return {"message": "Sales record deleted successfully"}
        
    except ValueError as ve:
        logger.warning("Error deleting sales record", error=str(ve), record_id=record_id)
        raise HTTPException(status_code=400, detail=str(ve))
    except Exception as e:
        logger.error("Failed to delete sales record", error=str(e), record_id=record_id, tenant_id=tenant_id)
        raise HTTPException(status_code=500, detail=f"Failed to delete sales record: {str(e)}")


@router.post("/tenants/{tenant_id}/sales/{record_id}/validate", response_model=SalesDataResponse)
async def validate_sales_record(
    tenant_id: UUID = Path(..., description="Tenant ID"),
    record_id: UUID = Path(..., description="Sales record ID"),
    validation_notes: Optional[str] = Query(None, description="Validation notes"),
    sales_service: SalesService = Depends(get_sales_service)
):
    """Mark a sales record as validated"""
    try:
        validated_record = await sales_service.validate_sales_record(record_id, tenant_id, validation_notes)
        
        logger.info("Validated sales record", record_id=record_id, tenant_id=tenant_id)
        return validated_record
        
    except ValueError as ve:
        logger.warning("Error validating sales record", error=str(ve), record_id=record_id)
        raise HTTPException(status_code=400, detail=str(ve))
    except Exception as e:
        logger.error("Failed to validate sales record", error=str(e), record_id=record_id, tenant_id=tenant_id)
        raise HTTPException(status_code=500, detail=f"Failed to validate sales record: {str(e)}")
