from __future__ import annotations

from dataclasses import replace
from pathlib import Path
from typing import Any

from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.response import Response

from endoreg_db.export.frames.export_frames_with_labels import (
    annotation_exporter_client,
    export_config,
    export_job_failed_error,
)
from endoreg_db.utils.permissions import EnvironmentAwarePermission


@api_view(["POST"])
@permission_classes([EnvironmentAwarePermission])
def export_annotated_data(request):
    payload: dict[str, Any] = request.data or {}

    config_path = payload.get("config_path")
    if config_path:
        config = export_config.from_yaml(config_path)
    else:
        output_dir = payload.get("output_dir")
        output_path = payload.get("output_path")
        if not output_path:
            output_path = "frames.csv" if output_dir else "data/export/frames.csv"
        config = export_config(output_path=Path(output_path))

    if payload.get("output_format"):
        config = replace(config, output_format=payload["output_format"])
    elif payload.get("format"):
        config = replace(config, output_format=payload["format"])

    updates: dict[str, Any] = {}
    for key in (
        "output_path",
        "output_dir",
        "video_id",
        "label_id",
        "information_source_name",
        "only_true",
        "limit",
        "load_base_data",
        "export_videos",
        "export_frames",
        "use_export_flags",
        "segment_ids",
        "transcode_frames",
        "transcode_fps",
        "transcode_quality",
        "transcode_ext",
        "transcode_overwrite",
        "use_frame_pk_paths",
    ):
        if key in payload and payload[key] is not None:
            updates[key] = payload[key]

    if not config_path:
        if "export_videos" not in updates:
            updates["export_videos"] = True
        if "export_frames" not in updates:
            updates["export_frames"] = True
        if "use_export_flags" not in updates and "segment_ids" not in updates:
            updates["use_export_flags"] = True

    if updates:
        config = replace(config, **updates)

    client = annotation_exporter_client()
    try:
        result = client.run_export(config)
    except export_job_failed_error as exc:
        return Response(
            {"success": False, "error": str(exc)},
            status=status.HTTP_500_INTERNAL_SERVER_ERROR,
        )

    return Response(
        {
            "success": result.success,
            "output_path": str(result.output_path),
            "row_count": result.row_count,
            "exported_video_count": result.exported_video_count,
            "exported_frame_count": result.exported_frame_count,
            "video_output_dir": (
                str(result.video_output_dir)
                if result.video_output_dir is not None
                else None
            ),
            "frame_output_dir": (
                str(result.frame_output_dir)
                if result.frame_output_dir is not None
                else None
            ),
        },
        status=status.HTTP_200_OK,
    )
