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

class FlutScrollController extends FlutRealtimeObject<ScrollController> {
  FlutScrollController._({
    required FlutRuntime runtime,
    required Map<String, dynamic> json,
    required ScrollController target,
  }) : super(
         runtime: runtime,
         json: json,
         type: 'ScrollController',
         target: target,
       );

  FlutScrollController.wrap({
    required FlutRuntime runtime,
    required int oid,
    required ScrollController target,
  }) : super.wrap(
         runtime: runtime,
         oid: oid,
         type: 'ScrollController',
         target: target,
       );

  static FlutScrollController flutDecode(
    FlutRuntime runtime,
    Map<String, dynamic> json,
  ) {
    return FlutScrollController._(
      runtime: runtime,
      json: json,
      target: ScrollController(
        initialScrollOffset: runtime.unpackRequiredField<double>(
          json,
          'initialScrollOffset',
        ),
      ),
    );
  }

  @override
  dynamic getRawProperty(String property) {
    switch (property) {
      case 'offset':
        return flutTarget.offset;
      case 'hasClients':
        return flutTarget.hasClients;
      case 'position':
        return flutTarget.position;
    }
    throw FlutUnknownPropertyException('ScrollController', property);
  }

  @override
  bool setProperty(String property, dynamic value) {
    throw FlutUnknownPropertyException('ScrollController', property);
  }

  @override
  dynamic callMethod(String method, Map<String, dynamic> args) {
    switch (method) {
      case 'jumpTo':
        final offset = (args['offset'] as num).toDouble();
        flutTarget.jumpTo(offset);
        return true;
      case 'animateTo':
        final offset = (args['offset'] as num).toDouble();
        final duration = flutRuntime.decodeObject<Duration>(args['duration'])!;
        final curve = flutRuntime.decodeObject<Curve>(args['curve'])!;
        flutTarget.animateTo(offset, duration: duration, curve: curve);
        return true;
    }
    throw FlutUnknownMethodException(method);
  }
}
