import sys
from unittest.mock import MagicMock, AsyncMock, patch
from datetime import date, datetime, timedelta
import uuid
import pytest

# Mock shared.config.base and pydantic_settings
mock_base = MagicMock()
mock_base.BASE_REFERENCE_DATE = date(2025, 11, 25)
sys.modules["shared.config.base"] = mock_base
sys.modules["pydantic_settings"] = MagicMock()
sys.modules["shared.database.base"] = MagicMock()
sys.modules["app.models.distribution"] = MagicMock()
sys.modules["shared.clients.tenant_client"] = MagicMock()
sys.modules["shared.clients.inventory_client"] = MagicMock()
sys.modules["shared.clients.procurement_client"] = MagicMock()
sys.modules["httpx"] = MagicMock()

from app.services.distribution_service import DistributionService

@pytest.mark.asyncio
async def test_setup_demo_enterprise_distribution_clones_history():
    # Setup mocks
    route_repo = AsyncMock()
    shipment_repo = AsyncMock()
    schedule_repo = AsyncMock()
    procurement_client = AsyncMock()
    tenant_client = AsyncMock()
    inventory_client = AsyncMock()
    routing_optimizer = AsyncMock()

    service = DistributionService(
        route_repository=route_repo,
        shipment_repository=shipment_repo,
        schedule_repository=schedule_repo,
        procurement_client=procurement_client,
        tenant_client=tenant_client,
        inventory_client=inventory_client,
        routing_optimizer=routing_optimizer
    )

    # Mock data
    parent_tenant_id = str(uuid.uuid4())
    child_tenant_ids = [str(uuid.uuid4()), str(uuid.uuid4()), str(uuid.uuid4())]
    session_id = "test-session"
    
    # Mock tenant client responses
    async def get_locations(tenant_id):
        if tenant_id == parent_tenant_id:
            return [{"location_type": "central_production", "latitude": 40.0, "longitude": -3.0, "name": "Central"}]
        else:
            return [{"location_type": "retail_outlet", "latitude": 40.1, "longitude": -3.1, "name": "Outlet"}]
            
    tenant_client.get_tenant_locations.side_effect = get_locations
    
    # Mock routing optimizer
    routing_optimizer.optimize_daily_routes.return_value = {
        "total_distance_km": 50.0,
        "estimated_duration_minutes": 60,
        "routes": [
            {
                "vehicle_id": "VEH-NEW",
                "driver_id": "DRV-NEW",
                "total_distance_km": 50.0,
                "estimated_duration_minutes": 60,
                "route_sequence": [
                    {"stop": 1, "tenant_id": child_tenant_ids[0], "location": "Outlet"}
                ]
            }
        ]
    }
    
    # Mock historical data
    start_date = date(2025, 10, 26)
    end_date = date(2025, 11, 25)
    
    mock_routes = [
        {
            "id": "old-route-1",
            "route_number": "DEMO-20251120-001",
            "route_date": datetime(2025, 11, 20),
            "vehicle_id": "VEH-001",
            "total_distance_km": 100.0,
            "estimated_duration_minutes": 120,
            "route_sequence": [
                {"stop": 1, "tenant_id": "d4e5f6a7-b8c9-40d1-e2f3-a4b5c6d7e8f9"}, # Template child 1
                {"stop": 2, "tenant_id": "e5f6a7b8-c9d0-41e2-f3a4-b5c6d7e8f9a0"}  # Template child 2
            ],
            "status": "completed"
        }
    ]
    
    mock_shipments = [
        {
            "id": "old-shipment-1",
            "child_tenant_id": "d4e5f6a7-b8c9-40d1-e2f3-a4b5c6d7e8f9", # Template child 1
            "delivery_route_id": "old-route-1",
            "shipment_number": "DEMOSHP-20251120-001",
            "shipment_date": datetime(2025, 11, 20),
            "status": "delivered",
            "total_weight_kg": 50.0,
            "total_volume_m3": 0.5
        }
    ]
    
    route_repo.get_routes_by_date_range.return_value = mock_routes
    shipment_repo.get_shipments_by_date_range.return_value = mock_shipments
    
    route_repo.create_route.return_value = {"id": "new-route-1"}
    
    # Execute
    result = await service.setup_demo_enterprise_distribution(
        parent_tenant_id=parent_tenant_id,
        child_tenant_ids=child_tenant_ids,
        session_id=session_id
    )
    
    # Verify
    assert result["status"] == "completed"
    assert result["routes_count"] == 1
    assert result["shipment_count"] == 1
    
    # Verify route creation
    route_repo.create_route.assert_called()
    call_args = route_repo.create_route.call_args[0][0]
    assert call_args["tenant_id"] == parent_tenant_id
    assert call_args["route_number"] == "DEMO-20251120-001"
    # Verify child ID mapping in sequence
    assert call_args["route_sequence"][0]["tenant_id"] == child_tenant_ids[0]
    
    # Verify shipment creation
    shipment_repo.create_shipment.assert_called()
    call_args = shipment_repo.create_shipment.call_args[0][0]
    assert call_args["tenant_id"] == parent_tenant_id
    assert call_args["child_tenant_id"] == child_tenant_ids[0]
    assert call_args["delivery_route_id"] == "new-route-1"
