import 'dart:async';
import 'dart:io';

import 'package:flutter/foundation.dart';

import '../../../core/infra/pip/android_pip_controller.dart';
import '../../../shared/utils/app_logger.dart';

const _tag = 'AndroidPipManager';


class AndroidPipManager {
  AndroidPipManager({required this._onStateChanged});

  final VoidCallback _onStateChanged;

  bool _isInPip = false;
  bool _isDisposed = false;
  bool _supported = false;
  StreamSubscription<bool>? _modeSub;
  StreamSubscription<PipAction>? _actionSub;


  void Function(PipAction action)? onAction;

  bool get isInPip => _isInPip;
  bool get isSupported => _supported;


  Future<void> initialize() async {
    if (!Platform.isAndroid) return;
    final supported = await AndroidPipController.instance.isSupported();
    if (_isDisposed) return;
    if (_supported != supported) {
      _supported = supported;
      _onStateChanged();
    }
    if (!_supported) return;
    if (_modeSub != null || _actionSub != null) return;

    final isInPip = await AndroidPipController.instance.isInPipMode();
    if (_isDisposed) return;
    if (_isInPip != isInPip) {
      _isInPip = isInPip;
      _onStateChanged();
    }

    _modeSub = AndroidPipController.instance.pipModeChanges.listen(
      (isInPip) {
        if (_isDisposed) return;
        if (_isInPip == isInPip) return;
        _isInPip = isInPip;
        AppLogger.info(_tag, 'PiP mode changed: $isInPip');
        _onStateChanged();
      },
      onError: (Object e) {
        AppLogger.warn(_tag, 'PiP mode stream error', e);
      },
    );

    _actionSub = AndroidPipController.instance.actionStream.listen(
      (action) {
        if (_isDisposed) return;
        AppLogger.debug(_tag, 'PiP action: $action');
        onAction?.call(action);
      },
      onError: (Object e) {
        AppLogger.warn(_tag, 'PiP action stream error', e);
      },
    );
  }


  Future<void> configure({
    int aspectX = 16,
    int aspectY = 9,
    bool autoEnterOnLeave = false,
    bool isPlaying = false,
    bool hasNext = false,
    bool hasPrev = false,
    bool useEpisodeActions = true,
  }) async {
    if (!_supported || _isDisposed) return;
    await AndroidPipController.instance.configure(
      aspectX: aspectX,
      aspectY: aspectY,
      autoEnterOnLeave: autoEnterOnLeave,
      isPlaying: isPlaying,
      hasNext: hasNext,
      hasPrev: hasPrev,
      useEpisodeActions: useEpisodeActions,
    );
  }


  Future<bool> enter({int? aspectX, int? aspectY}) async {
    if (!_supported || _isDisposed || _isInPip) return false;
    return AndroidPipController.instance.enterPip(
      aspectX: aspectX,
      aspectY: aspectY,
    );
  }


  Future<void> updatePlaybackState({
    required bool isPlaying,
    required bool hasNext,
    required bool hasPrev,
    required bool useEpisodeActions,
  }) async {
    if (!_supported || _isDisposed || !_isInPip) return;
    await AndroidPipController.instance.updatePlaybackState(
      isPlaying: isPlaying,
      hasNext: hasNext,
      hasPrev: hasPrev,
      useEpisodeActions: useEpisodeActions,
    );
  }

  void dispose() {
    if (_isDisposed) return;
    _isDisposed = true;
    final modeSub = _modeSub;
    _modeSub = null;
    final actionSub = _actionSub;
    _actionSub = null;
    onAction = null;
    unawaited(() async {
      await AndroidPipController.instance.configure(
        autoEnterOnLeave: false,
        isPlaying: false,
      );
      await modeSub?.cancel();
      await actionSub?.cancel();
      await AndroidPipController.instance.dispose();
    }());
  }
}
