import asyncio
import sys
import os
from unittest.mock import MagicMock, patch

sys.path.append(os.getcwd())

from app.services import video_upscaler
from app.models.job import Job
from app.models.asset import Asset
from app.config import settings

# Mock objects to simulate DB and Asset
mock_db = MagicMock()
mock_job = MagicMock()
mock_asset = MagicMock()

mock_job.id = "test_job_123"
mock_job.input_asset_ids = ["asset_123"]
mock_job.input_data = {
    "scale": 2,
    "model": "Proteus", # Test mapping to prob-4
    "fps": 60.0, 
    "sharpening": 50, 
    "recover_detail": 30, 
    "face_enhancement": False # Disable to test model mapping
}

mock_asset.id = "asset_123"
mock_asset.file_path = "test_video.mp4"
mock_asset.duration_seconds = 10.0
mock_asset.width = 1920
mock_asset.height = 1080
mock_asset.file_size_bytes = 1024 * 1024 * 10

# Mock DB queries
mock_db.query.return_value.filter.return_value.first.side_effect = [mock_job, mock_asset]

async def test_topaz_payload():
    print("Testing Topaz Video Upscaling Payload Construction...")
    
    # Check if Topaz API Key is set
    if not settings.topaz_api_key:
        print("  [SKIP] Topaz API Key not set (skipping actual API call)")
        return

    # We want to verify the parameters passed to client.post
    # expecting: 'https://api.topazlabs.com/video/'
    
    with patch("app.services.video_upscaler.SessionLocal", return_value=mock_db):
        with patch("app.services.video_upscaler.httpx.AsyncClient") as MockClient:
            mock_client_instance = MockClient.return_value.__aenter__.return_value
            # Mock the post response to avoid actual API call failure
            mock_client_instance.post.return_value.status_code = 200
            mock_client_instance.post.return_value.json.return_value = {"requestId": "mock_req_id"}
            
            # Mock extract_video_metadata to avoid FFmpeg dependency if missing
            with patch("app.utils.video.extract_video_metadata", return_value={"duration_seconds": 10, "fps": 30, "width": 1920, "height": 1080}):
                try:
                    # We only care about the initial POST to /video/
                    # The function continues to wait for upload URLs, etc.
                    # We can mock that too or expect it to fail later.
                    # Let's mock the subsequent calls to let it proceed slightly or catch the call.
                    
                    mock_client_instance.patch.return_value.json.return_value = {"urls": []}
                     # We'll likely error out at file reading or upload loop, but we can inspect the POST call before that.
                    
                    # Run the function (it will fail on file read likely)
                    try:
                        await video_upscaler.upscale("test_job_123")
                    except Exception as e:
                        print(f"  [INFO] Execution stopped as expected: {e}")

                    # VERIFY POST CALL
                    # assert mock_client_instance.post.called
                    call_args = mock_client_instance.post.call_args
                    if call_args:
                        url, kwargs = call_args
                        if url[0] == "https://api.topazlabs.com/video/":
                            print("  [SUCCESS] API Endpoint Correct")
                            payload = kwargs.get("json", {})
                            filters = payload.get("filters", [])
                            output = payload.get("output", {})
                            
                            print(f"  Filters Sent: {filters}")
                            print(f"  Output FrameRate: {output.get('frameRate')}")
                            
                            # Verify new parameters
                            if len(filters) > 0:
                                f = filters[0]
                                if f.get("details") == 50 and f.get("recoverOriginalDetailValue") == 30 and f.get("model") == "prob-4":
                                     print("  [VERIFIED] Parameters (details, recoverOriginalDetailValue, Model=prob-4) correctly mapped from Proteus!")
                                else:
                                     print(f"  [FAILED] Parameter mapping incorrect. Got: {f}")
                            
                            if output.get("frameRate") == 60.0:
                                print("  [VERIFIED] FPS correctly mapped!")
                            else:
                                print(f"  [FAILED] FPS incorrect. Got: {output.get('frameRate')}")

                        else:
                             print(f"  [FAILED] different URL called: {url}")
                    else:
                        print("  [FAILED] POST not called")

                except Exception as e:
                    print(f"  [ERROR] {e}")

if __name__ == "__main__":
    asyncio.run(test_topaz_payload())
