"""
Shipment API endpoints for distribution service
"""

from fastapi import APIRouter, Depends, HTTPException, Query
from typing import List, Optional
from datetime import date, timedelta

from app.api.dependencies import get_distribution_service
from shared.auth.tenant_access import verify_tenant_access_dep
from shared.routing.route_builder import RouteBuilder

router = APIRouter()

# Initialize route builder for distribution service
route_builder = RouteBuilder('distribution')


@router.get(route_builder.build_base_route("shipments"))
async def get_shipments(
    tenant_id: str,
    date_from: Optional[date] = Query(None, description="Start date for shipment filtering"),
    date_to: Optional[date] = Query(None, description="End date for shipment filtering"),
    status: Optional[str] = Query(None, description="Filter by shipment status"),
    distribution_service: object = Depends(get_distribution_service),
    verified_tenant: str = Depends(verify_tenant_access_dep)
):
    """
    List shipments with optional filtering
    """
    try:
        # If no date range specified, default to today
        if not date_from and not date_to:
            date_from = date.today()
            date_to = date.today()
        elif not date_to:
            date_to = date_from

        shipments = []
        current_date = date_from
        while current_date <= date_to:
            daily_shipments = await distribution_service.get_shipments_for_date(tenant_id, current_date)
            shipments.extend(daily_shipments)
            current_date = current_date + timedelta(days=1)
            
        if status:
            shipments = [s for s in shipments if s.get('status') == status]
            
        return {"shipments": shipments}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to get shipments: {str(e)}")


@router.put(route_builder.build_base_route("shipments/{shipment_id}/status"))
async def update_shipment_status(
    tenant_id: str,
    shipment_id: str,
    status_update: dict,  # Should be a proper Pydantic model
    distribution_service: object = Depends(get_distribution_service),
    verified_tenant: str = Depends(verify_tenant_access_dep)
):
    """
    Update shipment status
    """
    try:
        new_status = status_update.get('status')
        if not new_status:
            raise HTTPException(status_code=400, detail="Status is required")

        user_id = "temp_user_id"  # Would come from auth context
        result = await distribution_service.update_shipment_status(
            shipment_id=shipment_id,
            new_status=new_status,
            user_id=user_id,
            metadata=status_update.get('metadata')
        )
        return result
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to update shipment status: {str(e)}")


@router.post(route_builder.build_base_route("shipments/{shipment_id}/delivery-proof"))
async def upload_delivery_proof(
    tenant_id: str,
    shipment_id: str,
    delivery_proof: dict,  # Should be a proper Pydantic model
    distribution_service: object = Depends(get_distribution_service),
    verified_tenant: str = Depends(verify_tenant_access_dep)
):
    """
    Upload delivery proof (signature, photo, etc.)

    Expected delivery_proof fields:
    - signature: Base64 encoded signature image or signature data
    - photo_url: URL to uploaded delivery photo
    - received_by_name: Name of person who received delivery
    - delivery_notes: Optional notes about delivery
    """
    try:
        user_id = "temp_user_id"  # Would come from auth context

        # Prepare metadata for shipment update
        metadata = {}
        if 'signature' in delivery_proof:
            metadata['signature'] = delivery_proof['signature']
        if 'photo_url' in delivery_proof:
            metadata['photo_url'] = delivery_proof['photo_url']
        if 'received_by_name' in delivery_proof:
            metadata['received_by_name'] = delivery_proof['received_by_name']
        if 'delivery_notes' in delivery_proof:
            metadata['delivery_notes'] = delivery_proof['delivery_notes']

        # Update shipment with delivery proof
        result = await distribution_service.update_shipment_status(
            shipment_id=shipment_id,
            new_status='delivered',  # Automatically mark as delivered when proof uploaded
            user_id=user_id,
            metadata=metadata
        )

        if not result:
            raise HTTPException(status_code=404, detail="Shipment not found")

        return {
            "message": "Delivery proof uploaded successfully",
            "shipment_id": shipment_id,
            "status": "delivered"
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to upload delivery proof: {str(e)}")


@router.get(route_builder.build_base_route("shipments/{shipment_id}"))
async def get_shipment_detail(
    tenant_id: str,
    shipment_id: str,
    distribution_service: object = Depends(get_distribution_service),
    verified_tenant: str = Depends(verify_tenant_access_dep)
):
    """
    Get detailed information about a specific shipment including:
    - Basic shipment info (number, date, status)
    - Parent and child tenant details
    - Delivery route assignment
    - Purchase order reference
    - Delivery proof (signature, photo, received by)
    - Location tracking data
    """
    try:
        # Access the shipment repository from the distribution service
        shipment = await distribution_service.shipment_repository.get_shipment_by_id(shipment_id)

        if not shipment:
            raise HTTPException(status_code=404, detail="Shipment not found")

        # Verify tenant access
        if str(shipment.get('tenant_id')) != tenant_id:
            raise HTTPException(status_code=403, detail="Access denied to this shipment")

        return shipment
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Failed to get shipment details: {str(e)}")