/*
 * Copyright (c) 2025
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

import 'package:media_kit/media_kit.dart';

/// Controller for managing video splash screen playback
///
/// Provides control over video playback and access to the underlying
/// media_kit Player instance.
class SplashVideoController {
  /// Creates a SplashVideoController
  ///
  /// [loopVideo] - When true, video will loop infinitely until manually stopped
  SplashVideoController({
    this.loopVideo = false,
  });

  /// Whether the video should loop infinitely
  ///
  /// When true:
  /// - Video will restart automatically when it ends
  /// - User must call [skip] or [pause] to stop playback
  /// - Cannot use onVideoComplete or nextScreen callbacks
  final bool loopVideo;

  Player? _player;
  bool _isDisposed = false;

  /// Access to the underlying media_kit Player instance
  ///
  /// Provides full control over video playback including:
  /// - Position seeking
  /// - Volume control
  /// - Playback rate
  /// - Stream listeners for state changes
  ///
  /// Throws [StateError] if accessed before initialization
  Player get player {
    if (_player == null) {
      throw StateError(
        'Player not initialized. Controller must be attached to SplashVideo widget.',
      );
    }
    return _player!;
  }

  /// Internal method to attach the Player instance
  void attach(Player player) {
    if (_isDisposed) {
      throw StateError('Cannot attach player to disposed controller');
    }
    _player = player;
  }

  /// Starts or resumes video playback
  Future<void> play() async {
    if (_isDisposed) return;
    await player.play();
  }

  /// Pauses video playback
  Future<void> pause() async {
    if (_isDisposed) return;
    await player.pause();
  }

  /// Completes the video splash immediately
  ///
  /// This will:
  /// - Stop video playback
  /// - Trigger navigation or completion callbacks
  /// - Clean up resources
  Future<void> skip() async {
    if (_isDisposed) return;
    await player.pause();
    // The SplashVideo widget will handle navigation
    _skipRequested = true;
  }

  bool _skipRequested = false;

  /// Whether skip was requested by the user
  bool get skipRequested => _skipRequested;

  /// Disposes the controller and releases resources
  ///
  /// Should be called when the splash screen is no longer needed
  void dispose() {
    if (_isDisposed) return;
    _isDisposed = true;
    _player?.dispose();
    _player = null;
  }

  /// Whether the controller has been disposed
  bool get isDisposed => _isDisposed;
}
