from typing import Any, List  # pydantic response_model uses List

from fastapi import APIRouter, HTTPException

import vna_system.core.singletons as singletons
from vna_system.core.logging.logger import get_component_logger
from vna_system.core.settings.calibration_manager import CalibrationStandard
from vna_system.core.visualization.magnitude_chart import (
    generate_standards_magnitude_plots,
)
from vna_system.api.models.settings import (
    PresetModel,
    CalibrationModel,
    SettingsStatusModel,
    SetPresetRequest,
    StartCalibrationRequest,
    CalibrateStandardRequest,
    SaveCalibrationRequest,
    SetCalibrationRequest,
    RemoveStandardRequest,
    WorkingCalibrationModel,
    ReferenceModel,
    CreateReferenceRequest,
    SetReferenceRequest,
)

router = APIRouter(prefix="/api/v1/settings", tags=["settings"])
logger = get_component_logger(__file__)


@router.get("/status", response_model=SettingsStatusModel)
async def get_status() -> dict[str, Any]:
    """Get current settings status."""
    try:
        return singletons.settings_manager.get_status_summary()
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to get settings status")
        raise HTTPException(status_code=500, detail=str(exc))


@router.get("/presets", response_model=List[PresetModel])
async def get_presets() -> list[PresetModel]:
    """Get all available configuration presets, optionally filtered by mode."""
    try:
        presets = singletons.settings_manager.get_available_presets()

        return [
            PresetModel(
                filename=p.filename,
                mode=p.mode.value,
                start_freq=p.start_freq,
                stop_freq=p.stop_freq,
                points=p.points,
                bandwidth=p.bandwidth,
            )
            for p in presets
        ]
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to list presets")
        raise HTTPException(status_code=500, detail=str(exc))


@router.post("/preset/set")
async def set_preset(request: SetPresetRequest) -> dict[str, Any]:
    """Set current configuration preset."""
    try:
        presets = singletons.settings_manager.get_available_presets()
        preset = next((p for p in presets if p.filename == request.filename), None)
        if preset is None:
            raise HTTPException(status_code=404, detail=f"Пресет не найден: {request.filename}")

        # Changing preset invalidates active calibration selection.
        singletons.settings_manager.calibration_manager.clear_current_calibration()
        singletons.settings_manager.set_current_preset(preset)

        logger.info("Preset selected via API", filename=preset.filename, mode=preset.mode.value)
        return {"success": True, "message": f"Пресет установлен: {request.filename}"}
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to set preset")
        raise HTTPException(status_code=500, detail=str(exc))


@router.get("/preset/current", response_model=PresetModel | None)
async def get_current_preset():
    """Get currently selected configuration preset."""
    try:
        preset = singletons.settings_manager.get_current_preset()
        if not preset:
            return None

        return PresetModel(
            filename=preset.filename,
            mode=preset.mode.value,
            start_freq=preset.start_freq,
            stop_freq=preset.stop_freq,
            points=preset.points,
            bandwidth=preset.bandwidth,
        )
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to get current preset")
        raise HTTPException(status_code=500, detail=str(exc))


@router.get("/calibrations", response_model=List[CalibrationModel])
async def get_calibrations(preset_filename: str | None = None) -> list[CalibrationModel]:
    """Get available calibrations for current or specified preset."""
    try:
        preset = None
        if preset_filename:
            presets = singletons.settings_manager.get_available_presets()
            preset = next((p for p in presets if p.filename == preset_filename), None)
            if preset is None:
                raise HTTPException(status_code=404, detail=f"Пресет не найден: {preset_filename}")

        calibrations = singletons.settings_manager.get_available_calibrations(preset)
        details: list[CalibrationModel] = []
        current_preset = preset or singletons.settings_manager.get_current_preset()

        if current_preset:
            for name in calibrations:
                info = singletons.settings_manager.get_calibration_info(name, current_preset)
                standards = info.get("standards", {})

                # Normalize standards into {standard: bool}
                if isinstance(standards, list):
                    required = singletons.settings_manager.get_required_standards(current_preset.mode)
                    standards = {std.value: (std.value in standards) for std in required}

                details.append(
                    CalibrationModel(
                        name=name,
                        is_complete=bool(info.get("is_complete", False)),
                        standards=standards,
                    )
                )

        return details
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to list calibrations")
        raise HTTPException(status_code=500, detail=str(exc))


@router.post("/calibration/start")
async def start_calibration(request: StartCalibrationRequest) -> dict[str, Any]:
    """Start new calibration for current or specified preset."""
    try:
        preset = None
        if request.preset_filename:
            presets = singletons.settings_manager.get_available_presets()
            preset = next((p for p in presets if p.filename == request.preset_filename), None)
            if preset is None:
                raise HTTPException(status_code=404, detail=f"Пресет не найден: {request.preset_filename}")

        calib = singletons.settings_manager.start_new_calibration(preset)
        required = singletons.settings_manager.get_required_standards(calib.preset.mode)

        return {
            "success": True,
            "message": "Калибровка запущена",
            "preset": calib.preset.filename,
            "required_standards": [s.value for s in required],
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to start calibration")
        raise HTTPException(status_code=500, detail=str(exc))


@router.post("/calibration/add-standard")
async def add_calibration_standard(request: CalibrateStandardRequest) -> dict[str, Any]:
    """Add calibration standard from the latest sweep."""
    try:
        try:
            standard = CalibrationStandard(request.standard)
        except ValueError:
            raise HTTPException(status_code=400, detail=f"Недопустимый стандарт калибровки: {request.standard}")

        sweep_no = singletons.settings_manager.capture_calibration_standard_from_acquisition(
            standard, singletons.vna_data_acquisition_instance
        )

        working = singletons.settings_manager.get_current_working_calibration()
        progress = working.get_progress() if working else (0, 0)

        return {
            "success": True,
            "message": f"Добавлен стандарт {standard.value} из свипа {sweep_no}",
            "sweep_number": sweep_no,
            "progress": f"{progress[0]}/{progress[1]}",
            "is_complete": working.is_complete() if working else False,
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to add calibration standard")
        raise HTTPException(status_code=500, detail=str(exc))


@router.post("/calibration/save")
async def save_calibration(request: SaveCalibrationRequest) -> dict[str, Any]:
    """Save current working calibration set."""
    try:
        saved = singletons.settings_manager.save_calibration_set(request.name)
        return {
            "success": True,
            "message": f"Калибровка \"{request.name}\" успешно сохранена",
            "preset": saved.preset.filename,
            "standards": [s.value for s in saved.standards.keys()],
        }
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to save calibration")
        raise HTTPException(status_code=500, detail=str(exc))


@router.post("/calibration/set")
async def set_calibration(request: SetCalibrationRequest) -> dict[str, Any]:
    """Set current active calibration."""
    try:
        preset = None
        if request.preset_filename:
            presets = singletons.settings_manager.get_available_presets()
            preset = next((p for p in presets if p.filename == request.preset_filename), None)
            if preset is None:
                raise HTTPException(status_code=404, detail=f"Пресет не найден: {request.preset_filename}")

        singletons.settings_manager.set_current_calibration(request.name, preset)
        return {"success": True, "message": f"Калибровка установлена: \"{request.name}\""}
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to set calibration")
        raise HTTPException(status_code=500, detail=str(exc))


@router.get("/working-calibration", response_model=WorkingCalibrationModel)
async def get_working_calibration() -> WorkingCalibrationModel:
    """Get current working calibration status."""
    try:
        working = singletons.settings_manager.get_current_working_calibration()
        if not working:
            return WorkingCalibrationModel(active=False)

        completed, total = working.get_progress()
        return WorkingCalibrationModel(
            active=True,
            preset=working.preset.filename,
            progress=f"{completed}/{total}",
            is_complete=working.is_complete(),
            completed_standards=[s.value for s in working.standards.keys()],
            missing_standards=[s.value for s in working.get_missing_standards()],
        )
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to get working calibration")
        raise HTTPException(status_code=500, detail=str(exc))


@router.delete("/calibration/remove-standard")
async def remove_calibration_standard(request: RemoveStandardRequest) -> dict[str, Any]:
    """Remove calibration standard from current working set."""
    try:
        try:
            standard = CalibrationStandard(request.standard)
        except ValueError:
            raise HTTPException(status_code=400, detail=f"Недопустимый стандарт калибровки: {request.standard}")

        singletons.settings_manager.remove_calibration_standard(standard)

        working = singletons.settings_manager.get_current_working_calibration()
        progress = working.get_progress() if working else (0, 0)

        return {
            "success": True,
            "message": f"Стандарт {standard.value} удалён",
            "progress": f"{progress[0]}/{progress[1]}",
            "is_complete": working.is_complete() if working else False,
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to remove calibration standard")
        raise HTTPException(status_code=500, detail=str(exc))


@router.get("/calibration/current")
async def get_current_calibration() -> dict[str, Any]:
    """Get currently selected calibration details."""
    try:
        current = singletons.settings_manager.get_current_calibration()
        if not current:
            return {"active": False}

        return {
            "active": True,
            "preset": {"filename": current.preset.filename, "mode": current.preset.mode.value},
            "calibration_name": current.name,
            "standards": [s.value for s in current.standards.keys()],
            "is_complete": current.is_complete(),
        }
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to get current calibration")
        raise HTTPException(status_code=500, detail=str(exc))


@router.get("/calibration/{calibration_name}/standards-plots")
async def get_calibration_standards_plots(
    calibration_name: str,
    preset_filename: str | None = None,
) -> dict[str, Any]:
    """Get magnitude plots for all standards in a calibration set."""
    try:
        # Resolve preset (explicit or current)
        preset = None
        if preset_filename:
            presets = singletons.settings_manager.get_available_presets()
            preset = next((p for p in presets if p.filename == preset_filename), None)
            if preset is None:
                raise HTTPException(status_code=404, detail=f"Пресет не найден: {preset_filename}")
        else:
            preset = singletons.settings_manager.get_current_preset()
            if preset is None:
                raise HTTPException(status_code=400, detail="Текущий пресет не выбран")

        # Resolve calibration directory (uses manager's internal layout)
        calibration_manager = singletons.settings_manager.calibration_manager
        calibration_dir = calibration_manager._get_preset_calibration_dir(preset) / calibration_name  # noqa: SLF001

        if not calibration_dir.exists():
            raise HTTPException(status_code=404, detail=f"Калибровка не найдена: {calibration_name}")

        individual_plots = generate_standards_magnitude_plots(calibration_dir, preset)

        return {
            "calibration_name": calibration_name,
            "preset": {"filename": preset.filename, "mode": preset.mode.value},
            "individual_plots": individual_plots,
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to build calibration standards plots")
        raise HTTPException(status_code=500, detail=str(exc))


@router.get("/working-calibration/standards-plots")
async def get_working_calibration_standards_plots() -> dict[str, Any]:
    """Get magnitude plots for standards in the current working calibration."""
    try:
        working = singletons.settings_manager.get_current_working_calibration()
        if not working:
            raise HTTPException(status_code=404, detail="Рабочая калибровка не активна")
        if not working.standards:
            raise HTTPException(status_code=404, detail="В рабочей калибровке нет сохранённых стандартов")

        from vna_system.core.visualization.magnitude_chart import generate_magnitude_plot_from_sweep_data

        individual: dict[str, Any] = {}
        standard_colors = {
            "open": "#2ca02c",
            "short": "#d62728",
            "load": "#ff7f0e",
            "through": "#1f77b4",
        }

        for standard, sweep in working.standards.items():
            try:
                fig = generate_magnitude_plot_from_sweep_data(sweep, working.preset)
                if "error" not in fig and fig.get("data"):
                    fig["data"][0]["line"]["color"] = standard_colors.get(standard.value, "#1f77b4")
                    fig["data"][0]["name"] = f"Стандарт {standard.value.upper()}"
                    fig["layout"]["title"] = f"Амплитуда стандарта {standard.value.upper()} (рабочая)"

                    fig["raw_sweep_data"] = {
                        "sweep_number": sweep.sweep_number,
                        "timestamp": sweep.timestamp,
                        "total_points": sweep.total_points,
                        "points": sweep.points,
                        "file_path": None,
                    }

                    fig["frequency_info"] = {
                        "start_freq": working.preset.start_freq,
                        "stop_freq": working.preset.stop_freq,
                        "points": working.preset.points,
                        "bandwidth": working.preset.bandwidth,
                    }
                individual[standard.value] = fig
            except Exception as exc:  # noqa: BLE001
                individual[standard.value] = {"error": f"Не удалось построить график для {standard.value}: {exc}"}

        if not individual:
            raise HTTPException(status_code=404, detail="Не удалось создать графики для рабочей калибровки")

        return {
            "calibration_name": "Рабочая калибровка",
            "preset": {"filename": working.preset.filename, "mode": working.preset.mode.value},
            "individual_plots": individual,
            "is_working": True,
            "is_complete": working.is_complete(),
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to build working calibration standards plots")
        raise HTTPException(status_code=500, detail=str(exc))


# ================================================================ #
# Reference Management Endpoints
# ================================================================ #

@router.get("/references", response_model=List[ReferenceModel])
async def get_references(preset_filename: str | None = None) -> List[dict[str, Any]]:
    """Get available references for a preset."""
    try:
        settings_manager = singletons.settings_manager

        if preset_filename:
            preset = next(
                (p for p in settings_manager.get_available_presets() if p.filename == preset_filename),
                None
            )
            if not preset:
                raise HTTPException(status_code=404, detail=f"Пресет \"{preset_filename}\" не найден")
        else:
            preset = settings_manager.get_current_preset()
            if not preset:
                raise HTTPException(status_code=400, detail="Текущий пресет не выбран и параметр preset_filename не указан")

        references = settings_manager.get_available_references(preset)

        return [
            {
                "name": ref.name,
                "timestamp": ref.timestamp.isoformat(),
                "preset_filename": ref.preset_filename,
                "description": ref.description,
                "metadata": ref.metadata
            }
            for ref in references
        ]
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to get references", error=repr(exc))
        raise HTTPException(status_code=500, detail=str(exc))


@router.get("/reference/current", response_model=ReferenceModel | None)
async def get_current_reference(preset_filename: str | None = None) -> dict[str, Any] | None:
    """Get the currently selected reference."""
    try:
        settings_manager = singletons.settings_manager

        if preset_filename:
            preset = next(
                (p for p in settings_manager.get_available_presets() if p.filename == preset_filename),
                None
            )
            if not preset:
                raise HTTPException(status_code=404, detail=f"Пресет \"{preset_filename}\" не найден")
        else:
            preset = settings_manager.get_current_preset()
            if not preset:
                raise HTTPException(status_code=400, detail="Текущий пресет не выбран и параметр preset_filename не указан")

        current_ref = settings_manager.get_current_reference(preset)

        if not current_ref:
            return None

        return {
            "name": current_ref.name,
            "timestamp": current_ref.timestamp.isoformat(),
            "preset_filename": current_ref.preset_filename,
            "description": current_ref.description,
            "metadata": current_ref.metadata
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to get current reference", error=repr(exc))
        raise HTTPException(status_code=500, detail=str(exc))


@router.post("/reference/create")
async def create_reference(request: CreateReferenceRequest) -> dict[str, Any]:
    """Create a new reference from current sweep data."""
    try:
        settings_manager = singletons.settings_manager
        data_acquisition = singletons.vna_data_acquisition_instance

        if request.preset_filename:
            preset = next(
                (p for p in settings_manager.get_available_presets() if p.filename == request.preset_filename),
                None
            )
            if not preset:
                raise HTTPException(status_code=404, detail=f"Пресет \"{request.preset_filename}\" не найден")
        else:
            preset = settings_manager.get_current_preset()
            if not preset:
                raise HTTPException(status_code=400, detail="Текущий пресет не выбран и параметр preset_filename не указан")

        # Create reference using the new capture method
        reference_info = settings_manager.capture_reference_from_acquisition(
            reference_name=request.name,
            data_acquisition=data_acquisition,
            description=request.description,
            metadata=request.metadata,
            preset=preset
        )

        return {
            "success": True,
            "message": f"Эталон \"{request.name}\" успешно создан",
            "reference": {
                "name": reference_info.name,
                "timestamp": reference_info.timestamp.isoformat(),
                "preset_filename": reference_info.preset_filename,
                "description": reference_info.description,
                "metadata": reference_info.metadata
            }
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to create reference", name=request.name, error=repr(exc))
        raise HTTPException(status_code=500, detail=str(exc))


@router.post("/reference/set")
async def set_current_reference(request: SetReferenceRequest) -> dict[str, Any]:
    """Set the current reference."""
    try:
        settings_manager = singletons.settings_manager

        if request.preset_filename:
            preset = next(
                (p for p in settings_manager.get_available_presets() if p.filename == request.preset_filename),
                None
            )
            if not preset:
                raise HTTPException(status_code=404, detail=f"Пресет \"{request.preset_filename}\" не найден")
        else:
            preset = settings_manager.get_current_preset()
            if not preset:
                raise HTTPException(status_code=400, detail="Текущий пресет не выбран и параметр preset_filename не указан")

        success = settings_manager.set_current_reference(request.name, preset)

        if not success:
            raise HTTPException(status_code=404, detail=f"Эталон \"{request.name}\" не найден")

        return {
            "success": True,
            "message": f"Эталон \"{request.name}\" выбран текущим"
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to set current reference", name=request.name, error=repr(exc))
        raise HTTPException(status_code=500, detail=str(exc))


@router.delete("/reference/current")
async def clear_current_reference() -> dict[str, Any]:
    """Clear the current reference selection."""
    try:
        settings_manager = singletons.settings_manager
        success = settings_manager.clear_current_reference()

        if not success:
            raise HTTPException(status_code=500, detail="Не удалось сбросить текущий эталон")

        return {
            "success": True,
            "message": "Текущий эталон сброшен"
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to clear current reference", error=repr(exc))
        raise HTTPException(status_code=500, detail=str(exc))


@router.get("/reference/{reference_name}", response_model=ReferenceModel)
async def get_reference(reference_name: str, preset_filename: str | None = None) -> ReferenceModel:
    """Get information about a specific reference."""
    try:
        settings_manager = singletons.settings_manager

        if preset_filename:
            preset = next(
                (p for p in settings_manager.get_available_presets() if p.filename == preset_filename),
                None
            )
            if not preset:
                raise HTTPException(status_code=404, detail=f"Пресет \"{preset_filename}\" не найден")
        else:
            preset = settings_manager.get_current_preset()
            if not preset:
                raise HTTPException(status_code=400, detail="Текущий пресет не выбран и параметр preset_filename не указан")

        info = settings_manager.get_reference_info(reference_name, preset)
        if not info:
            raise HTTPException(status_code=404, detail=f"Эталон \"{reference_name}\" не найден")

        return ReferenceModel(
            name=info.name,
            timestamp=info.timestamp.isoformat(),
            preset_filename=info.preset_filename,
            description=info.description,
            metadata=info.metadata,
        )
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to get reference info", name=reference_name, error=repr(exc))
        raise HTTPException(status_code=500, detail=str(exc))


@router.get("/reference/{reference_name}/plot")
async def get_reference_plot(reference_name: str, preset_filename: str | None = None) -> dict[str, Any]:
    """Get magnitude plot for a reference measurement."""
    try:
        settings_manager = singletons.settings_manager

        if preset_filename:
            preset = next(
                (p for p in settings_manager.get_available_presets() if p.filename == preset_filename),
                None
            )
            if not preset:
                raise HTTPException(status_code=404, detail=f"Пресет \"{preset_filename}\" не найден")
        else:
            preset = settings_manager.get_current_preset()
            if not preset:
                raise HTTPException(status_code=400, detail="Текущий пресет не выбран и параметр preset_filename не указан")

        reference_info = settings_manager.get_reference_info(reference_name, preset)
        if not reference_info:
            raise HTTPException(status_code=404, detail=f"Эталон \"{reference_name}\" не найден")

        sweep_data = settings_manager.reference_manager.get_reference_sweep(reference_name, preset)
        if not sweep_data:
            raise HTTPException(status_code=404, detail=f"Данные эталона \"{reference_name}\" не найдены")

        from vna_system.core.visualization.magnitude_chart import generate_magnitude_plot_from_sweep_data

        plot_fig = generate_magnitude_plot_from_sweep_data(sweep_data, preset)
        if "error" in plot_fig:
            raise HTTPException(status_code=500, detail=plot_fig["error"])

        return {
            "reference_name": reference_name,
            "preset": {"filename": preset.filename, "mode": preset.mode.value},
            "plot": plot_fig,
            "timestamp": reference_info.timestamp.isoformat(),
            "description": reference_info.description
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to get reference plot", name=reference_name, error=repr(exc))
        raise HTTPException(status_code=500, detail=str(exc))


@router.delete("/reference/{reference_name}")
async def delete_reference(reference_name: str, preset_filename: str | None = None) -> dict[str, Any]:
    """Delete a reference."""
    try:
        settings_manager = singletons.settings_manager

        if preset_filename:
            preset = next(
                (p for p in settings_manager.get_available_presets() if p.filename == preset_filename),
                None
            )
            if not preset:
                raise HTTPException(status_code=404, detail=f"Пресет \"{preset_filename}\" не найден")
        else:
            preset = settings_manager.get_current_preset()
            if not preset:
                raise HTTPException(status_code=400, detail="Текущий пресет не выбран и параметр preset_filename не указан")

        success = settings_manager.delete_reference(reference_name, preset)

        if not success:
            raise HTTPException(status_code=404, detail=f"Эталон \"{reference_name}\" не найден")

        return {
            "success": True,
            "message": f"Эталон \"{reference_name}\" успешно удалён"
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to delete reference", name=reference_name, error=repr(exc))
        raise HTTPException(status_code=500, detail=str(exc))


@router.delete("/calibration/current")
async def clear_current_calibration() -> dict[str, Any]:
    """Clear the current calibration selection."""
    try:
        singletons.settings_manager.calibration_manager.clear_current_calibration()
        return {"success": True, "message": "Текущая калибровка сброшена"}
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to clear current calibration", error=repr(exc))
        raise HTTPException(status_code=500, detail=str(exc))


@router.delete("/calibration/{calibration_name}")
async def delete_calibration(calibration_name: str, preset_filename: str | None = None) -> dict[str, Any]:
    """Delete a calibration set."""
    try:
        settings_manager = singletons.settings_manager

        if preset_filename:
            preset = next(
                (p for p in settings_manager.get_available_presets() if p.filename == preset_filename),
                None
            )
            if not preset:
                raise HTTPException(status_code=404, detail=f"Пресет \"{preset_filename}\" не найден")
        else:
            preset = settings_manager.get_current_preset()
            if not preset:
                raise HTTPException(status_code=400, detail="Текущий пресет не выбран и параметр preset_filename не указан")

        settings_manager.delete_calibration(preset, calibration_name)

        return {
            "success": True,
            "message": f"Калибровка \"{calibration_name}\" удалена"
        }
    except HTTPException:
        raise
    except Exception as exc:  # noqa: BLE001
        logger.error("Failed to delete calibration", name=calibration_name, error=repr(exc))
        raise HTTPException(status_code=500, detail=str(exc))
