from typing import Optional


def flut_unpack(data) -> Optional[object]:
    if not isinstance(data, dict):
        return None
    
    flut_type = data.get("_flut_type")
    if not flut_type:
        return None

    oid = data.get("_flut_oid")
    if oid is not None:
        from flut._flut.engine import FlutRealtimeObject
        existing = FlutRealtimeObject._lookup_oid(oid)
        if existing is not None:
            return existing

    match flut_type:
        case "Color":
            from flut.dart.ui import Color
            return Color._flut_unpack(data)
        case "Canvas":
            from flut.dart.ui import Canvas
            return Canvas._flut_unpack(data)
        case "Size":
            from flut.dart.ui import Size
            return Size._flut_unpack(data)
        case "Offset":
            from flut.dart.ui import Offset
            return Offset._flut_unpack(data)
        case "Rect":
            from flut.dart.ui import Rect
            return Rect._flut_unpack(data)
        case "DragStartDetails":
            from flut.flutter.gestures.drag_details import DragStartDetails
            return DragStartDetails._flut_unpack(data)
        case "DragUpdateDetails":
            from flut.flutter.gestures.drag_details import DragUpdateDetails
            return DragUpdateDetails._flut_unpack(data)
        case "DragEndDetails":
            from flut.flutter.gestures.drag_details import DragEndDetails
            return DragEndDetails._flut_unpack(data)
        case "Velocity":
            from flut.flutter.gestures.velocity_tracker import Velocity
            return Velocity._flut_unpack(data)
        case "KeyDownEvent":
            from flut.flutter.services.hardware_keyboard import KeyDownEvent
            return KeyDownEvent._flut_unpack(data)
        case "KeyUpEvent":
            from flut.flutter.services.hardware_keyboard import KeyUpEvent
            return KeyUpEvent._flut_unpack(data)
        case "KeyRepeatEvent":
            from flut.flutter.services.hardware_keyboard import KeyRepeatEvent
            return KeyRepeatEvent._flut_unpack(data)
        case "LogicalKeyboardKey":
            from flut.flutter.services.keyboard_key import LogicalKeyboardKey
            return LogicalKeyboardKey._flut_unpack(data)
        case "PhysicalKeyboardKey":
            from flut.flutter.services.keyboard_key import PhysicalKeyboardKey
            return PhysicalKeyboardKey._flut_unpack(data)
        case "Duration":
            from flut.dart.core import Duration
            return Duration._flut_unpack(data)
        case "EdgeInsets":
            from flut.flutter.painting.edge_insets import EdgeInsets
            return EdgeInsets._flut_unpack(data)
        case "ColorScheme":
            from flut.flutter.material.color_scheme import ColorScheme
            return ColorScheme._flut_unpack(data)
        case "ThemeData":
            from flut.flutter.material.theme_data import ThemeData
            return ThemeData._flut_unpack(data)
        case "TextTheme":
            from flut.flutter.material.text_theme import TextTheme
            return TextTheme._flut_unpack(data)
        case "TextStyle":
            from flut.flutter.painting.text_style import TextStyle
            return TextStyle._flut_unpack(data)
        case "FontWeight":
            from flut.dart.ui import _FontWeight
            return _FontWeight._flut_unpack(data)
        case "MediaQueryData":
            from flut.flutter.widgets.media_query import MediaQueryData
            return MediaQueryData._flut_unpack(data)
        case "HardwareKeyboard":
            from flut.flutter.services.hardware_keyboard import HardwareKeyboard
            return HardwareKeyboard._flut_unpack(data)
        case "SchedulerBinding":
            from flut.flutter.scheduler.binding import SchedulerBinding
            return SchedulerBinding._flut_unpack(data)
        case _:
            raise RuntimeError(f"Unknown _flut_type: {flut_type}")


def _flut_unpack_optional_field(data: dict, field: str) -> Optional[object]:
    value = data.get(field)
    if value is None:
        return None
    if isinstance(value, (bool, int, float, str)):
        return value
    if isinstance(value, dict):
        return flut_unpack(value)
    if isinstance(value, list):
        return [flut_unpack(item) if isinstance(item, dict) else item for item in value]
    return value


def _flut_unpack_required_field(data: dict, field: str) -> object:
    value = _flut_unpack_optional_field(data, field)
    if value is None:
        flut_type = data.get("_flut_type", "")
        raise ValueError(f"Missing required field '{field}' in {flut_type}")
    return value
