"""Service for PX4 sensor calibration operations."""

from __future__ import annotations

from typing import AsyncGenerator, Dict, Any

from mavsdk import System

from ..models import CalibrationType
from ..utils.calibration_parser import (
    parse_accelerometer_progress,
    parse_gyroscope_progress,
    parse_magnetometer_progress,
    parse_horizon_progress,
)


async def calibrate_sensors(
    port: str,
    baudrate: int,
    calibration_type: CalibrationType,
) -> AsyncGenerator[Dict[str, Any], None]:
    """
    Calibrate PX4 sensors and stream progress as structured dict payloads.

    This function is transport-agnostic: it does NOT produce SSE-formatted strings.
    It yields plain Python dicts suitable for JSON serialization. The API layer
    (FastAPI endpoint) is responsible for converting these dicts into SSE frames.
    """

    serial = f"serial://{port}:{baudrate}"
    drone = System()

    # Initial status messages
    yield {
        "type": "status",
        "message": f"Connecting to {port}...",
    }

    # Connect to the PX4 system
    await drone.connect(system_address=serial)

    yield {
        "type": "status",
        "message": "Connected to device",
    }

    # Dispatch based on calibration type
    if calibration_type is CalibrationType.GYROSCOPE:
        # Gyroscope calibration
        yield {
            "type": "status",
            "message": "Starting gyroscope calibration...",
        }

        async for progress_data in drone.calibration.calibrate_gyro():
            structured_data = parse_gyroscope_progress(progress_data)
            yield structured_data

        yield {
            "type": "gyroscope_complete",
            "message": "Gyroscope calibration finished",
            "is_complete": True,
        }

    elif calibration_type is CalibrationType.ACCELEROMETER:
        # Accelerometer calibration
        yield {
            "type": "status",
            "message": "Starting accelerometer calibration...",
        }

        async for progress_data in drone.calibration.calibrate_accelerometer():
            structured_data = parse_accelerometer_progress(progress_data)
            yield structured_data

        yield {
            "type": "accelerometer_complete",
            "message": "Accelerometer calibration finished",
            "is_complete": True,
        }

    elif calibration_type is CalibrationType.MAGNETOMETER:
        # Magnetometer calibration
        yield {
            "type": "status",
            "message": "Starting magnetometer calibration...",
        }

        async for progress_data in drone.calibration.calibrate_magnetometer():
            structured_data = parse_magnetometer_progress(progress_data)
            yield structured_data

        yield {
            "type": "magnetometer_complete",
            "message": "Magnetometer calibration finished",
            "is_complete": True,
        }

    elif calibration_type is CalibrationType.HORIZON:
        # Level horizon calibration
        yield {
            "type": "status",
            "message": "Starting board level horizon calibration...",
        }

        async for progress_data in drone.calibration.calibrate_level_horizon():
            structured_data = parse_horizon_progress(progress_data)
            yield structured_data

        yield {
            "type": "horizon_complete",
            "message": "Level horizon calibration finished",
            "is_complete": True,
        }

    elif calibration_type is CalibrationType.ESC:
        # ESC calibration not implemented yet
        yield {
            "type": "status",
            "message": "Starting ESC calibration...",
        }
        yield {
            "type": "warning",
            "message": "ESC calibration not yet implemented",
        }
        yield {
            "type": "status",
            "message": "ESC calibration finished",
        }

    # Final success message for the whole calibration run
    yield {
        "type": "success",
        "message": "Calibration sequence completed",
    }
