import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
import 'package:protobuf/protobuf.dart';
import 'package:veilid_support/veilid_support.dart';

import '../../proto/proto.dart' as proto;

/// Profile and Account configurable fields
/// Some are publicly visible via the proto.Profile
/// Some are privately held as proto.Account configurations
@immutable
class AccountSpec extends Equatable {
  const AccountSpec(
      {required this.name,
      required this.pronouns,
      required this.about,
      required this.availability,
      required this.invisible,
      required this.freeMessage,
      required this.awayMessage,
      required this.busyMessage,
      required this.avatar,
      required this.autoAway,
      required this.autoAwayTimeout});

  const AccountSpec.empty()
      : name = '',
        pronouns = '',
        about = '',
        availability = proto.Availability.AVAILABILITY_FREE,
        invisible = false,
        freeMessage = '',
        awayMessage = '',
        busyMessage = '',
        avatar = null,
        autoAway = false,
        autoAwayTimeout = 15;

  AccountSpec.fromProto(proto.Account p)
      : name = p.profile.name,
        pronouns = p.profile.pronouns,
        about = p.profile.about,
        availability = p.profile.availability,
        invisible = p.invisible,
        freeMessage = p.freeMessage,
        awayMessage = p.awayMessage,
        busyMessage = p.busyMessage,
        avatar = p.profile.hasAvatar() ? p.profile.avatar : null,
        autoAway = p.autodetectAway,
        autoAwayTimeout = p.autoAwayTimeoutMin;

  String get status {
    late final String status;
    switch (availability) {
      case proto.Availability.AVAILABILITY_AWAY:
        status = awayMessage;
      case proto.Availability.AVAILABILITY_BUSY:
        status = busyMessage;
      case proto.Availability.AVAILABILITY_FREE:
        status = freeMessage;
      case proto.Availability.AVAILABILITY_UNSPECIFIED:
      case proto.Availability.AVAILABILITY_OFFLINE:
        status = '';
    }
    return status;
  }

  Future<proto.Account> updateProto(proto.Account old) async {
    final newProto = old.deepCopy()
      ..profile.name = name
      ..profile.pronouns = pronouns
      ..profile.about = about
      ..profile.availability = availability
      ..profile.status = status
      ..profile.timestamp = Veilid.instance.now().toInt64()
      ..invisible = invisible
      ..autodetectAway = autoAway
      ..autoAwayTimeoutMin = autoAwayTimeout
      ..freeMessage = freeMessage
      ..awayMessage = awayMessage
      ..busyMessage = busyMessage;

    final newAvatar = avatar;
    if (newAvatar != null) {
      newProto.profile.avatar = newAvatar;
    } else {
      newProto.profile.clearAvatar();
    }

    return newProto;
  }

  ////////////////////////////////////////////////////////////////////////////

  final String name;
  final String pronouns;
  final String about;
  final proto.Availability availability;
  final bool invisible;
  final String freeMessage;
  final String awayMessage;
  final String busyMessage;
  final proto.DataReference? avatar;
  final bool autoAway;
  final int autoAwayTimeout;

  @override
  List<Object?> get props => [
        name,
        pronouns,
        about,
        availability,
        invisible,
        freeMessage,
        awayMessage,
        busyMessage,
        avatar,
        autoAway,
        autoAwayTimeout
      ];
}