"""Route initialization and handlers for the single-file transcription workflow"""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/workflow/routes.ipynb.

# %% auto 0
__all__ = ['init_router']

# %% ../../nbs/workflow/routes.ipynb 3
from pathlib import Path
from typing import Optional
from fasthtml.common import *
from fasthtml.common import APIRouter

from cjm_fasthtml_workflows.core.workflow_session import WorkflowSession

from ..core.html_ids import SingleFileHtmlIds
from ..components.processor import transcription_in_progress
from ..components.results import transcription_results, transcription_error
from ..components.steps import render_plugin_details_route
from cjm_fasthtml_workflow_transcription_single_file.workflow.job_handler import (
    get_job_session_info,
    create_job_stream_handler,
)

from .workflow import SingleFileTranscriptionWorkflow

# %% ../../nbs/workflow/routes.ipynb 5
def init_router(
    workflow: SingleFileTranscriptionWorkflow,  # The workflow instance providing access to config and dependencies
) -> APIRouter:  # Configured APIRouter with all workflow routes
    """Initialize and return the workflow's API router with all routes."""
    router = APIRouter(prefix=workflow.config.route_prefix)

    @router
    def current_status(
        request,  # FastHTML request object
        sess,  # FastHTML session object
    ):  # Appropriate UI component based on current state
        """Return current transcription status - determines what to show."""
        manager = workflow._transcription_manager
        all_jobs = manager.get_all_jobs()

        # Priority 1: Check for running jobs
        if all_jobs:
            sorted_jobs = sorted(all_jobs, key=lambda j: j.created_at, reverse=True)
            recent_job = sorted_jobs[0]

            if recent_job.status == 'running':
                file_info, plugin_info = get_job_session_info(
                    recent_job.id, recent_job, sess, workflow._plugin_adapter
                )
                return transcription_in_progress(
                    job_id=recent_job.id,
                    plugin_info=plugin_info,
                    file_info=file_info,
                    config=workflow.config,
                    router=workflow._router,
                )

        # Priority 2: Check for in-progress workflow
        workflow_session = WorkflowSession(sess, workflow.config.workflow_id)
        has_workflow_state = bool(
            workflow_session.get("plugin_id") or workflow_session.get("file_path")
        )

        if has_workflow_state:
            # Resume in-progress workflow
            return workflow._stepflow_router.start(request, sess)

        # Priority 3: Show completed job results
        if all_jobs:
            recent_job = sorted(all_jobs, key=lambda j: j.created_at, reverse=True)[0]

            if recent_job.status == 'completed':
                result = manager.get_job_result(recent_job.id)
                if result and result.get('status') == 'success':
                    data = result.get('data', {})
                    file_info, plugin_info = get_job_session_info(
                        recent_job.id, recent_job, sess, workflow._plugin_adapter
                    )

                    return transcription_results(
                        job_id=recent_job.id,
                        transcription_text=data.get('text', ''),
                        metadata=data.get('metadata', {}),
                        file_info=file_info,
                        plugin_info=plugin_info,
                        config=workflow.config,
                        router=workflow._router,
                        stepflow_router=workflow._stepflow_router,
                    )

        # Priority 4: Start fresh
        return workflow._stepflow_router.start(request, sess)

    @router
    async def cancel_job(
        request,  # FastHTML request object
        sess,  # FastHTML session object
        job_id: str,  # ID of the job to cancel
    ):  # StepFlow start view or error component
        """Cancel a running transcription job."""
        manager = workflow._transcription_manager
        success = await manager.cancel_job(job_id)

        if success:
            # Reset workflow and return to plugin selection
            workflow_session = WorkflowSession(sess, workflow.config.workflow_id)
            workflow_session.clear()
            return workflow._stepflow_router.start(request, sess)
        else:
            return transcription_error(
                f"Failed to cancel job {job_id}",
                None,
                config=workflow.config,
                stepflow_router=workflow._stepflow_router,
            )

    @router
    def reset(
        request,  # FastHTML request object
        sess,  # FastHTML session object
    ):  # StepFlow start view
        """Reset transcription workflow and return to start."""
        workflow_session = WorkflowSession(sess, workflow.config.workflow_id)
        workflow_session.clear()
        return workflow._stepflow_router.start(request, sess)

    @router
    def stream_job(
        request,  # FastHTML request object
        sess,  # FastHTML session object
        job_id: str,  # ID of the job to monitor
    ):  # EventStream for SSE updates
        """SSE endpoint for monitoring job completion."""
        stream_generator = create_job_stream_handler(
            job_id,
            request,
            sess,
            config=workflow.config,
            router=workflow._router,
            stepflow_router=workflow._stepflow_router,
            transcription_manager=workflow._transcription_manager,
            plugin_registry=workflow._plugin_adapter,
            result_storage=workflow._result_storage,
        )
        return EventStream(stream_generator())

    @router
    def export(
        request,  # FastHTML request object
        job_id: str,  # ID of the job to export
        format: str = "txt",  # Export format (txt, srt, vtt)
    ):  # Response with file download
        """Export transcription in specified format."""
        manager = workflow._transcription_manager
        job = manager.get_job(job_id)
        result = manager.get_job_result(job_id)

        if not job or not result:
            return Response("Job not found", status_code=404)

        transcription_text = result.get("data", {}).get("text", "")
        file_name = getattr(job, "file_name", "transcription")

        # Format the transcription
        content = _export_transcription(transcription_text, format, file_name)

        # Create filename
        base_name = Path(file_name).stem
        filename = f"{base_name}_transcription.{format}"

        return Response(
            content=content,
            media_type="application/octet-stream",
            headers={
                "Content-Disposition": f"attachment; filename={filename}"
            }
        )

    @router
    def plugin_details(
        request,  # FastHTML request object
        plugin_id: str = "",  # ID of the plugin to show details for
    ):  # Plugin details component or empty Div
        """Get plugin details for display in workflow."""
        if plugin_id and plugin_id.strip():
            return render_plugin_details_route(
                plugin_id,
                workflow._plugin_adapter,
                workflow._plugin_registry,
                save_plugin_config.to(),
                reset_plugin_config.to()
            )
        else:
            return Div()

    @router
    async def save_plugin_config(
        request,  # FastHTML request object
        plugin_id: str = "",  # ID of the plugin to save config for
    ):  # Updated config form or error alert
        """Save plugin configuration from the collapse form."""
        from cjm_fasthtml_app_core.components.alerts import create_success_alert, create_error_alert
        from cjm_fasthtml_settings.core.utils import convert_form_data_to_config
        from cjm_fasthtml_workflow_transcription_single_file.components.steps import render_plugin_config_form

        if not plugin_id:
            return create_error_alert("No plugin selected")

        try:
            # Get plugin metadata to access schema
            plugin_meta = workflow._plugin_registry.get_plugin(plugin_id)
            if not plugin_meta or not plugin_meta.config_schema:
                return create_error_alert("Plugin schema not found")

            form_data = await request.form()
            config = convert_form_data_to_config(form_data, plugin_meta.config_schema)

            # Save configuration via the registry
            if workflow._plugin_registry.save_plugin_config(plugin_id, config):
                return render_plugin_config_form(
                    plugin_id=plugin_id,
                    plugin_registry=workflow._plugin_registry,
                    save_url=save_plugin_config.to(),
                    reset_url=reset_plugin_config.to(),
                    alert_message=create_success_alert("Plugin configuration saved!")
                )
            else:
                return create_error_alert("Failed to save plugin configuration")

        except Exception as e:
            import traceback
            traceback.print_exc()
            return create_error_alert(f"Error saving configuration: {str(e)}")

    @router
    def reset_plugin_config(
        request,  # FastHTML request object
        plugin_id: str = "",  # ID of the plugin to reset config for
    ):  # Updated config form with defaults or empty Div
        """Reset plugin configuration to defaults."""
        from cjm_fasthtml_app_core.components.alerts import create_success_alert
        from cjm_fasthtml_settings.core.utils import get_default_values_from_schema
        from cjm_fasthtml_workflow_transcription_single_file.components.steps import render_plugin_config_form

        if not plugin_id:
            return Div()

        # Get plugin metadata to access schema
        plugin_meta = workflow._plugin_registry.get_plugin(plugin_id)
        if not plugin_meta or not plugin_meta.config_schema:
            return Div()

        # Get default values and save them
        default_values = get_default_values_from_schema(plugin_meta.config_schema)
        workflow._plugin_registry.save_plugin_config(plugin_id, default_values)

        return render_plugin_config_form(
            plugin_id=plugin_id,
            plugin_registry=workflow._plugin_registry,
            save_url=save_plugin_config.to(),
            reset_url=reset_plugin_config.to(),
            alert_message=create_success_alert("Configuration reset to defaults")
        )

    @router
    def media_preview(
        request,  # FastHTML request object
        idx: int = 0,  # Index of the file to preview
        media_type: str = None,  # Optional filter by media type
    ):  # Media preview modal or error Div
        """Render media preview modal for a specific file."""
        from cjm_fasthtml_workflow_transcription_single_file.media.components import media_preview_modal

        # Get files (with optional filter)
        files = workflow._media_library.scan()
        if media_type and media_type != "all":
            files = [f for f in files if f.media_type == media_type]

        if idx < 0 or idx >= len(files):
            return Div("File not found")

        media_file = files[idx]
        media_url = workflow._media_library.get_url(media_file.path)

        return media_preview_modal(
            media_file=media_file,
            media_url=media_url,
            modal_id=SingleFileHtmlIds.MEDIA_PREVIEW_MODAL
        )

    @router
    def refresh_media(
        request,  # FastHTML request object
    ):  # JSON status response
        """Refresh media file cache."""
        workflow._media_library.clear_cache()
        return {"status": "success", "message": "Cache cleared"}

    @router
    def settings_modal(
        request,  # FastHTML request object
    ):  # Settings modal component
        """Render the settings modal for the workflow."""
        from cjm_fasthtml_workflow_transcription_single_file.settings.components import settings_modal as create_settings_modal
        from cjm_fasthtml_workflow_transcription_single_file.settings.schemas import WORKFLOW_SETTINGS_SCHEMA, WorkflowSettings

        # Get current settings from workflow config
        settings = WorkflowSettings.from_configs(
            workflow.config.media,
            workflow.config.storage,
            workflow.config
        )

        return create_settings_modal(
            modal_id=SingleFileHtmlIds.SETTINGS_MODAL,
            schema=WORKFLOW_SETTINGS_SCHEMA,
            current_values=settings.to_dict(),
            save_url=settings_save.to(),
            target_id=SingleFileHtmlIds.SETTINGS_CONTAINER
        )

    @router
    async def settings_save(
        request,  # FastHTML request object
    ):  # Success alert with modal close script or error alert
        """Save workflow settings."""
        from cjm_fasthtml_app_core.components.alerts import create_success_alert, create_error_alert
        from cjm_fasthtml_interactions.core.html_ids import InteractionHtmlIds
        from cjm_fasthtml_settings.core.utils import save_config, convert_form_data_to_config
        from cjm_fasthtml_workflow_transcription_single_file.settings.schemas import WORKFLOW_SETTINGS_SCHEMA, WorkflowSettings

        try:
            form_data = await request.form()

            # Convert form data to config dict using schema
            config_dict = convert_form_data_to_config(form_data, WORKFLOW_SETTINGS_SCHEMA)

            # Create WorkflowSettings from form data
            settings = WorkflowSettings(**config_dict)

            # Apply settings to runtime config objects
            settings.apply_to_configs(
                workflow.config.media,
                workflow.config.storage,
                workflow.config
            )

            # Update ResourceManager threshold separately (not part of config objects)
            workflow._resource_manager.gpu_memory_threshold_percent = settings.gpu_memory_threshold_percent

            # Save to workflow-internal config directory for persistence across restarts
            save_config("settings", settings.to_dict(), workflow.config.config_dir)

            # Re-mount directories
            if workflow._app:
                workflow._media_library.mount(workflow._app)

            # Clear cache to pick up new directories
            workflow._media_library.clear_cache()

            # Get the correct modal ID using the helper
            modal_dialog_id = InteractionHtmlIds.modal_dialog(SingleFileHtmlIds.SETTINGS_MODAL)

            return Div(
                create_success_alert("Settings saved successfully"),
                Script(f"document.getElementById('{modal_dialog_id}').close()"),
                id=SingleFileHtmlIds.SETTINGS_CONTAINER
            )

        except Exception as e:
            import traceback
            traceback.print_exc()
            return Div(
                create_error_alert(f"Failed to save settings: {str(e)}"),
                id=SingleFileHtmlIds.SETTINGS_CONTAINER
            )

    return router

# %% ../../nbs/workflow/routes.ipynb 6
def _export_transcription(
    text: str,  # Transcription text
    format: str,  # Export format (txt, srt, vtt)
    filename: str,  # Original filename for metadata
) -> str:  # Formatted transcription string
    """Format transcription for export."""
    if format == "txt":
        return text

    elif format == "srt":
        # Simple SRT format with single segment
        lines = text.split('\n')
        srt_content = []
        for i, line in enumerate(lines, 1):
            if line.strip():
                srt_content.append(f"{i}")
                srt_content.append(f"00:00:00,000 --> 00:00:00,000")
                srt_content.append(line.strip())
                srt_content.append("")
        return '\n'.join(srt_content) if srt_content else text

    elif format == "vtt":
        # WebVTT format
        vtt_content = ["WEBVTT", ""]
        lines = text.split('\n')
        for i, line in enumerate(lines, 1):
            if line.strip():
                vtt_content.append(f"00:00:00.000 --> 00:00:00.000")
                vtt_content.append(line.strip())
                vtt_content.append("")
        return '\n'.join(vtt_content)

    else:
        return text
