import 'package:equatable/equatable.dart';

/// Play mode enumeration matching SDK values
enum PlayMode {
  unknown(0),
  playStop(1),
  playForward(2),
  playBackward(3),
  fastForward(4),
  fastBackward(5),
  stepForward(6),
  stepBackward(7),
  playBOD(8),
  playEOD(9),
  quasiLive(10),
  live(11),
  nextEvent(12),
  prevEvent(13),
  peekLivePicture(14),
  nextDetectedMotion(17),
  prevDetectedMotion(18);

  final int value;
  const PlayMode(this.value);

  static PlayMode fromValue(int value) {
    return PlayMode.values.firstWhere(
      (m) => m.value == value,
      orElse: () => PlayMode.unknown,
    );
  }
}

/// State of a single monitor/viewer
class MonitorState extends Equatable {
  final int viewerId;
  final int currentChannel;
  final PlayMode playMode;
  final String? serverId;
  final DateTime lastUpdated;
  final bool hasAlarm;

  const MonitorState({
    required this.viewerId,
    required this.currentChannel,
    required this.playMode,
    this.serverId,
    required this.lastUpdated,
    this.hasAlarm = false,
  });

  /// Check if monitor is currently displaying a camera
  bool get isActive => currentChannel > 0;

  /// Check if monitor is in live mode
  bool get isLive => playMode == PlayMode.live || playMode == PlayMode.quasiLive;

  /// Create a cleared state
  MonitorState cleared() {
    return MonitorState(
      viewerId: viewerId,
      currentChannel: 0,
      playMode: PlayMode.unknown,
      serverId: serverId,
      lastUpdated: DateTime.now(),
      hasAlarm: hasAlarm,
    );
  }

  /// Create updated state with new camera
  MonitorState withCamera(int channel, PlayMode mode) {
    return MonitorState(
      viewerId: viewerId,
      currentChannel: channel,
      playMode: mode,
      serverId: serverId,
      lastUpdated: DateTime.now(),
      hasAlarm: hasAlarm,
    );
  }

  /// Create state with alarm flag updated
  MonitorState withAlarm(bool alarm) {
    return MonitorState(
      viewerId: viewerId,
      currentChannel: currentChannel,
      playMode: playMode,
      serverId: serverId,
      lastUpdated: lastUpdated,
      hasAlarm: alarm,
    );
  }

  factory MonitorState.fromJson(Map<String, dynamic> json) {
    return MonitorState(
      viewerId: json['viewer_id'] as int? ?? 0,
      currentChannel: json['current_channel'] as int? ?? 0,
      playMode: PlayMode.fromValue(json['play_mode'] as int? ?? 0),
      serverId: json['server_id'] as String?,
      lastUpdated: json['last_updated'] != null
          ? DateTime.parse(json['last_updated'] as String)
          : DateTime.now(),
      hasAlarm: json['has_alarm'] as bool? ?? false,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'viewer_id': viewerId,
      'current_channel': currentChannel,
      'play_mode': playMode.value,
      'server_id': serverId,
      'last_updated': lastUpdated.toIso8601String(),
      'has_alarm': hasAlarm,
    };
  }

  @override
  List<Object?> get props => [
        viewerId,
        currentChannel,
        playMode,
        serverId,
        lastUpdated,
        hasAlarm,
      ];
}
