/// Camera lock entity matching the coordinator's CameraLock model.
class CameraLock {
  final int cameraId;
  final CameraLockPriority priority;
  final String ownerName;
  final DateTime ownedSince;
  final DateTime expiresAt;

  const CameraLock({
    required this.cameraId,
    required this.priority,
    required this.ownerName,
    required this.ownedSince,
    required this.expiresAt,
  });

  factory CameraLock.fromJson(Map<String, dynamic> json) {
    return CameraLock(
      cameraId: json['cameraId'] as int? ?? json['CameraId'] as int? ?? 0,
      priority: CameraLockPriority.fromString(
          json['priority'] as String? ?? json['Priority'] as String? ?? 'Low'),
      ownerName:
          json['ownerName'] as String? ?? json['OwnerName'] as String? ?? '',
      ownedSince: DateTime.parse(
          json['ownedSince'] as String? ?? json['OwnedSince'] as String? ?? ''),
      expiresAt: DateTime.parse(
          json['expiresAt'] as String? ?? json['ExpiresAt'] as String? ?? ''),
    );
  }

  Duration get timeRemaining {
    final remaining = expiresAt.difference(DateTime.now().toUtc());
    return remaining.isNegative ? Duration.zero : remaining;
  }

  bool get isExpiringSoon => timeRemaining.inSeconds <= 60;
  bool get isExpired => timeRemaining == Duration.zero;
  bool isOwnedBy(String keyboardId) =>
      ownerName.toLowerCase() == keyboardId.toLowerCase();
}

enum CameraLockPriority {
  none,
  high,
  low;

  static CameraLockPriority fromString(String value) {
    switch (value.toLowerCase()) {
      case 'high':
        return CameraLockPriority.high;
      case 'low':
        return CameraLockPriority.low;
      default:
        return CameraLockPriority.none;
    }
  }

  String get name {
    switch (this) {
      case CameraLockPriority.high:
        return 'High';
      case CameraLockPriority.low:
        return 'Low';
      case CameraLockPriority.none:
        return 'None';
    }
  }
}

enum CameraLockNotificationType {
  acquired,
  takenOver,
  confirmTakeOver,
  confirmed,
  rejected,
  expireSoon,
  unlocked;

  static CameraLockNotificationType fromString(String value) {
    switch (value) {
      case 'Acquired':
        return CameraLockNotificationType.acquired;
      case 'TakenOver':
        return CameraLockNotificationType.takenOver;
      case 'ConfirmTakeOver':
        return CameraLockNotificationType.confirmTakeOver;
      case 'Confirmed':
        return CameraLockNotificationType.confirmed;
      case 'Rejected':
        return CameraLockNotificationType.rejected;
      case 'ExpireSoon':
        return CameraLockNotificationType.expireSoon;
      case 'Unlocked':
        return CameraLockNotificationType.unlocked;
      default:
        return CameraLockNotificationType.acquired;
    }
  }
}

/// Lock notification from the coordinator (sent via WebSocket)
class CameraLockNotification {
  final CameraLockNotificationType type;
  final int cameraId;
  final String copilotName;

  const CameraLockNotification({
    required this.type,
    required this.cameraId,
    required this.copilotName,
  });

  factory CameraLockNotification.fromJson(Map<String, dynamic> json) {
    return CameraLockNotification(
      type: CameraLockNotificationType.fromString(
          json['type'] as String? ?? json['Type'] as String? ?? ''),
      cameraId: json['cameraId'] as int? ?? json['CameraId'] as int? ?? 0,
      copilotName: json['copilotName'] as String? ??
          json['CopilotName'] as String? ??
          '',
    );
  }
}
