import 'package:flutter/widgets.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import '../nut_player_platform_interface.dart';
import 'model/platform_player_content.dart';
import 'video_event.dart';

class _PlaceholderImplementation extends NutPlayerPlatform {}

typedef PlayerId = int;

abstract class NutPlayerPlatform extends PlatformInterface {

  static final Object _token = Object();

  /// Constructs NutPlayerPlatform
  NutPlayerPlatform(): super(token: _token);

  static NutPlayerPlatform get instance => _instance;

  /// Default implementation.
  static NutPlayerPlatform _instance = _PlaceholderImplementation();

  // MARK: - PlatformInterface

  static set instance(NutPlayerPlatform instance) {
    PlatformInterface.verify(instance, _token);
    _instance = instance;
  }

  /// Platform Methods

  Future<int> state(PlayerId playerId) async {

    throw UnimplementedError('state() has not been implemented.');
  }

  /// Initializes the platform interface and disposes all existing players.
  ///
  /// This method is called when the plugin is first initialized
  /// and on every full restart.
  Future<void> init() {
    throw UnimplementedError('init() has not been implemented.');
  }

  /// Clears one video.
  Future<void> dispose(PlayerId id) {
    throw UnimplementedError('dispose() has not been implemented.');
  }

  /// Creates an instance of a video player and returns its PlayerId.
  Future<PlayerId> create({required PlatformPlayerContent content, Map<String, Object>? params}) {
    throw UnimplementedError('create() has not been implemented.');
  }

  /// Returns a Stream of [VideoEventType]s.
  Stream<VideoEvent> videoEventsFor(PlayerId playerId) {
    throw UnimplementedError('videoEventsFor() has not been implemented.');
  }

  /// Starts the video playback.
  Future<void> play(PlayerId playerId) {
    throw UnimplementedError('play() has not been implemented.');
  }

  /// Stops the video playback.
  Future<void> pause(PlayerId playerId) {
    throw UnimplementedError('pause() has not been implemented.');
  }

  /// Завершает видео.
  Future<void> end(PlayerId playerId) {
    throw UnimplementedError('end() has not been implemented.');
  }

  Future<double> volume(PlayerId playerId) async {
    throw UnimplementedError('volume() has not been implemented.');
  }

  /// Sets the volume to a range between 0.0 and 1.0.
  Future<void> setVolume(PlayerId playerId, double volume) {
    throw UnimplementedError('setVolume() has not been implemented.');
  }

  /// Sets the log limit output level.
  Future<void> setLimitOutputLevel(String limitOutputLevel) {
    throw UnimplementedError('setLimitOutputLevel() has not been implemented.');
  }

  /// Sets the subtitles by their id.
  Future<void> setSubtitle(PlayerId playerId, String subtitleID) {
    throw UnimplementedError('setSubtitle() has not been implemented.');
  }

  /// Установить новое качество видео
  Future<void> setQuality(PlayerId playerId, String qualityID) {
    throw UnimplementedError('setQuality() has not been implemented.');
  }

  /// Sets the video position to a [Duration] from the start.
  Future<void> seek(PlayerId playerId, Duration position) {
    throw UnimplementedError('seekTo() has not been implemented.');
  }

  /// Sets the playback speed to a [speed] value indicating the playback rate.
  Future<void> setPlaybackSpeed(PlayerId playerId, double speed) {
    throw UnimplementedError('setPlaybackSpeed() has not been implemented.');
  }

  /// Gets the video position as [Duration] from the start.
  Future<Duration> getPosition(PlayerId playerId) async {
    throw UnimplementedError('getPosition() has not been implemented.');
  }

  /// Returns a widget displaying the video with a given PlayerId.
  Widget buildView(PlayerId playerId) {
    throw UnimplementedError('buildView() has not been implemented.');
  }

  /// Sets the audio mode to mix with other sources
  Future<void> setMixWithOthers(bool mixWithOthers) {
    throw UnimplementedError('setMixWithOthers() has not been implemented.');
  }

  Stream<String> logStream() {
    throw UnimplementedError('logStream() has not been implemented.');
  }

  Stream<Object> skinActionStream() {
    throw UnimplementedError('skinActionStream() has not been implemented.');
  }
}