import 'package:flutter/services.dart';
import 'package:flut/flut/object.dart';
import 'package:flut/flut/runtime.dart';

class _FlutMouseCursorSession extends MouseCursorSession {
  final String kind;
  final FlutRuntime runtime;
  final String? createSessionActionId;

  _FlutMouseCursorSession(
    super.cursor,
    super.device,
    this.kind,
    this.runtime,
    this.createSessionActionId,
  );

  @override
  Future<void> activate() {
    if (createSessionActionId != null) {
      runtime.callAction(createSessionActionId!, args: [device]);
    }
    return SystemChannels.mouseCursor.invokeMethod<void>(
      'activateSystemCursor',
      <String, dynamic>{'device': device, 'kind': kind},
    );
  }

  @override
  void dispose() {}
}

class FlutMouseCursor extends MouseCursor with FlutAbstractObject {
  final String kind;
  @override
  final FlutRuntime runtime;
  final String? createSessionActionId;

  const FlutMouseCursor._(this.kind, this.runtime, this.createSessionActionId);

  @override
  MouseCursorSession createSession(int device) {
    return _FlutMouseCursorSession(
      this,
      device,
      kind,
      runtime,
      createSessionActionId,
    );
  }

  @override
  String get debugDescription => 'FlutMouseCursor($kind)';

  static MouseCursor? flutDecode(
    FlutRuntime runtime,
    Map<String, dynamic> data,
  ) {
    final kind = runtime.unpackRequiredField<String>(data, 'kind');
    if (kind == 'defer') return MouseCursor.defer;
    final createSessionActionId = runtime.unpackOptionalField<String>(
      data,
      'createSessionActionId',
    );
    return FlutMouseCursor._(kind, runtime, createSessionActionId);
  }
}
