import 'package:equatable/equatable.dart';

/// Alarm state enumeration matching SDK PlcViewerAlarmState
enum AlarmStatus {
  newAlarm(0, 'vasNewAlarm'),
  presented(1, 'vasPresented'),
  stacked(2, 'vasStacked'),
  confirmed(3, 'vasConfirmed'),
  removed(4, 'vasRemoved'),
  lastConfirmed(5, 'vasLastConfirmed'),
  lastRemoved(6, 'vasLastRemoved');

  final int value;
  final String name;
  const AlarmStatus(this.value, this.name);

  static AlarmStatus fromValue(int value) {
    return AlarmStatus.values.firstWhere(
      (s) => s.value == value,
      orElse: () => AlarmStatus.newAlarm,
    );
  }

  /// Check if this status blocks the monitor
  bool get blocksMonitor =>
      this == AlarmStatus.newAlarm || this == AlarmStatus.presented;
}

/// State of a single alarm/event
class AlarmState extends Equatable {
  final int eventId;
  final String eventName;
  final int typeId;
  final int foreignKey; // Camera or contact ID
  final String? serverId;
  final DateTime startedAt;
  final DateTime? stoppedAt;
  final bool isActive;
  final AlarmStatus status;
  final int? associatedMonitor;

  const AlarmState({
    required this.eventId,
    required this.eventName,
    required this.typeId,
    required this.foreignKey,
    this.serverId,
    required this.startedAt,
    this.stoppedAt,
    required this.isActive,
    this.status = AlarmStatus.newAlarm,
    this.associatedMonitor,
  });

  /// Check if this alarm blocks a monitor
  bool get blocksMonitor => isActive && status.blocksMonitor;

  /// Create a stopped alarm
  AlarmState stopped() {
    return AlarmState(
      eventId: eventId,
      eventName: eventName,
      typeId: typeId,
      foreignKey: foreignKey,
      serverId: serverId,
      startedAt: startedAt,
      stoppedAt: DateTime.now(),
      isActive: false,
      status: AlarmStatus.removed,
      associatedMonitor: associatedMonitor,
    );
  }

  /// Create alarm with updated status
  AlarmState withStatus(AlarmStatus newStatus) {
    return AlarmState(
      eventId: eventId,
      eventName: eventName,
      typeId: typeId,
      foreignKey: foreignKey,
      serverId: serverId,
      startedAt: startedAt,
      stoppedAt: stoppedAt,
      isActive: isActive,
      status: newStatus,
      associatedMonitor: associatedMonitor,
    );
  }

  factory AlarmState.fromJson(Map<String, dynamic> json) {
    return AlarmState(
      eventId: json['event_id'] as int? ?? 0,
      eventName: json['event_name'] as String? ?? '',
      typeId: json['type_id'] as int? ?? 0,
      foreignKey: json['foreign_key'] as int? ?? 0,
      serverId: json['server_id'] as String?,
      startedAt: json['started_at'] != null
          ? DateTime.parse(json['started_at'] as String)
          : DateTime.now(),
      stoppedAt: json['stopped_at'] != null
          ? DateTime.parse(json['stopped_at'] as String)
          : null,
      isActive: json['is_active'] as bool? ?? true,
      status: AlarmStatus.fromValue(json['status'] as int? ?? 0),
      associatedMonitor: json['associated_monitor'] as int?,
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'event_id': eventId,
      'event_name': eventName,
      'type_id': typeId,
      'foreign_key': foreignKey,
      'server_id': serverId,
      'started_at': startedAt.toIso8601String(),
      'stopped_at': stoppedAt?.toIso8601String(),
      'is_active': isActive,
      'status': status.value,
      'associated_monitor': associatedMonitor,
    };
  }

  @override
  List<Object?> get props => [
        eventId,
        eventName,
        typeId,
        foreignKey,
        serverId,
        startedAt,
        stoppedAt,
        isActive,
        status,
        associatedMonitor,
      ];
}
