from packages.adapters.in_memory import (
    InMemoryAssetRepository,
    InMemoryIngestJobRepository,
)
from packages.application import SubmitIngestJobCommand, SubmitIngestJobUseCase
from packages.domain import Asset, IngestJobStatus


def simulate_ingest_asset(
    job_id: str,
    job_repo: InMemoryIngestJobRepository,
    asset_repo: InMemoryAssetRepository,
) -> dict:
    """
    Simulate ingest asset logic without Celery.
    This is the core business logic that would run inside the worker task.
    """
    job = job_repo.get(job_id)
    if job is None:
        return {"status": "failed", "error": "job not found"}

    try:
        # Update job status to PROCESSING
        job.status = IngestJobStatus.PROCESSING
        job_repo.update(job)

        # Mock metadata extraction
        mime_type = "video/mp4" if job.storage_key.endswith(".mp4") else "image/jpeg"
        metadata = {
            "duration": 10.5,
            "width": 1920,
            "height": 1080,
            "size_bytes": 1024000,
        }

        # Extract filename from storage_key
        filename = job.storage_key.split("/")[-1]

        # Create Asset
        asset = Asset.create(
            project_id=job.project_id,
            library_id=job.library_id,
            name=filename,
            storage_key=job.storage_key,
            mime_type=mime_type,
            metadata=metadata,
        )
        asset_repo.create(asset)

        # Update job status to COMPLETED
        job.status = IngestJobStatus.COMPLETED
        job.result_asset_id = asset.id
        job_repo.update(job)

        return {
            "status": "completed",
            "job_id": job.id,
            "asset_id": asset.id,
        }
    except Exception as e:
        # Update job status to FAILED
        job.status = IngestJobStatus.FAILED
        job.error_message = str(e)
        job_repo.update(job)

        return {
            "status": "failed",
            "job_id": job.id,
            "error": str(e),
        }


def test_ingest_asset_pipeline():
    """Test the full ingest pipeline: submit job -> worker processes -> asset created."""
    job_repo = InMemoryIngestJobRepository()
    asset_repo = InMemoryAssetRepository()

    # Submit ingest job
    use_case = SubmitIngestJobUseCase(job_repo)
    job = use_case.execute(
        SubmitIngestJobCommand(
            project_id="proj-1",
            library_id="lib-1",
            storage_key="uploads/test-video.mp4",
        )
    )

    assert job.status == IngestJobStatus.PENDING
    assert job.result_asset_id == ""

    # Simulate worker task execution
    result = simulate_ingest_asset(job.id, job_repo, asset_repo)

    assert result["status"] == "completed"
    assert "asset_id" in result

    # Verify job was updated
    updated_job = job_repo.get(job.id)
    assert updated_job is not None
    assert updated_job.status == IngestJobStatus.COMPLETED
    assert updated_job.result_asset_id != ""

    # Verify asset was created
    assets = asset_repo.list_by_library("lib-1")
    assert len(assets) == 1
    assert assets[0].id == updated_job.result_asset_id
    assert assets[0].name == "test-video.mp4"
    assert assets[0].metadata["duration"] == 10.5
