# pylint: disable=import-outside-toplevel
import logging
import os
from typing import Dict, Any, Optional

logger = logging.getLogger(__name__)


class WorkflowService:
    """Service for managing Temporal workflows."""

    def __init__(self, temporal_url: Optional[str] = None):
        """
        Initialize workflow service.

        Args:
            temporal_url: Temporal server URL (defaults to env var or localhost:7233)
        """
        self.temporal_url = temporal_url or os.getenv("TEMPORAL_URL", "localhost:7233")

    async def start_video_pipeline(
        self, video_path: str, video_id: str, processor_kwargs: Dict[str, Any]
    ) -> Dict[str, Any]:
        """
        Start a video processing workflow.

        Args:
            video_path: Path or URL to video file
            video_id: Unique identifier for the video
            processor_kwargs: Additional kwargs passed to processors

        Returns:
            Dict with workflow_id, video_id, status, message

        Raises:
            Exception: If workflow start fails
        """
        from temporalio.client import Client
        from mini_videorag.temporal.workflows import VideoPipelineWorkflow
        from mini_videorag.utils.config_loader import load_video_rag_config

        client = await Client.connect(self.temporal_url)

        config = load_video_rag_config()
        workflow_config = config["workflow"]

        workflow_id = f"video-pipeline-{video_id}"

        await client.start_workflow(
            VideoPipelineWorkflow.run,
            args=[video_path, video_id, workflow_config, processor_kwargs],
            id=workflow_id,
            task_queue="video-processing",
        )

        logger.info(f"Started workflow {workflow_id} for video {video_id}")

        return {
            "workflow_id": workflow_id,
            "video_id": video_id,
            "status": "started",
            "message": f"Workflow started successfully. Use GET /workflows/{workflow_id}/progress to track progress.",
        }

    async def get_workflow_progress(self, workflow_id: str) -> Dict[str, Any]:
        """
        Get workflow progress.

        Args:
            workflow_id: Temporal workflow ID

        Returns:
            Dict with workflow_id, status, progress info

        Raises:
            Exception: If query fails
        """
        from temporalio.client import Client, WorkflowFailureError
        from temporalio.exceptions import (
            CancelledError,
            TerminatedError,
            TimeoutError as TemporalTimeoutError,
        )

        client = await Client.connect(self.temporal_url)

        handle = client.get_workflow_handle(workflow_id)

        try:
            progress = await handle.query("get_progress")
            description = await handle.describe()

            status_mapping = {
                "COMPLETED": "completed",
                "FAILED": "failed",
                "CANCELED": "cancelled",
                "TERMINATED": "terminated",
                "TIMED_OUT": "timed_out",
                "RUNNING": "running",
                "CONTINUED_AS_NEW": "running",
            }
            workflow_status = status_mapping.get(description.status.name, "running")

            return {"workflow_id": workflow_id, "status": workflow_status, **progress}

        except WorkflowFailureError as e:
            logger.warning(f"Workflow {workflow_id} failed: {e}")
            try:
                progress = await handle.query("get_progress")
                return {"workflow_id": workflow_id, "status": "failed", **progress}
            except Exception as query_error:
                logger.error(f"Failed to query progress of failed workflow: {query_error}")
                raise ValueError(f"Workflow failed and progress query failed: {str(e)}") from e
        except (CancelledError, TerminatedError) as e:
            logger.info(f"Workflow {workflow_id} was cancelled/terminated: {e}")
            raise ValueError(f"Workflow was {type(e).__name__}: {str(e)}") from e
        except TemporalTimeoutError as e:
            logger.error(f"Workflow {workflow_id} timed out: {e}")
            raise TimeoutError(f"Workflow timed out: {str(e)}") from e

    async def get_workflow_result(self, workflow_id: str) -> Dict[str, Any]:
        """
        Get final workflow result.

        Args:
            workflow_id: Temporal workflow ID

        Returns:
            Dict with workflow_id, video_id, status, results

        Raises:
            Exception: If result retrieval fails
        """
        from temporalio.client import Client

        client = await Client.connect(self.temporal_url)

        handle = client.get_workflow_handle(workflow_id)

        result = await handle.result()

        return {
            "workflow_id": workflow_id,
            "video_id": result.get("video_id", "unknown"),
            "status": "completed",
            "results": result.get("results", {}),
            "total_processors": result.get("total_processors", 0),
            "completed_processors": result.get("completed_processors", 0),
        }
