// lib/providers/receipt_state.dart

import 'package:cashumit/models/receipt_group.dart';

class ReceiptState {
  List<ReceiptGroup> groups;
  DateTime transactionDate;
  List<Map<String, dynamic>> accounts;
  String? destinationAccountId;
  String? destinationAccountName;
  String? fireflyUrl;
  String? accessToken;
  double paymentAmount;
  String? tipSourceAccountId;
  String? tipSourceAccountName;

  ReceiptState({
    List<ReceiptGroup>? groups,
    DateTime? transactionDate,
    List<Map<String, dynamic>>? accounts,
    this.destinationAccountId,
    this.destinationAccountName,
    this.fireflyUrl,
    this.accessToken,
    this.paymentAmount = 0.0,
    this.tipSourceAccountId,
    this.tipSourceAccountName,
  })  : groups = groups ?? [],
        transactionDate = transactionDate ?? DateTime.now(),
        accounts = accounts ?? [];

  static const _unset = Object();

  ReceiptState copyWith({
    List<ReceiptGroup>? groups,
    DateTime? transactionDate,
    List<Map<String, dynamic>>? accounts,
    Object? destinationAccountId = _unset,
    Object? destinationAccountName = _unset,
    Object? fireflyUrl = _unset,
    Object? accessToken = _unset,
    double? paymentAmount,
    Object? tipSourceAccountId = _unset,
    Object? tipSourceAccountName = _unset,
  }) {
    return ReceiptState(
      groups: groups ?? this.groups,
      transactionDate: transactionDate ?? this.transactionDate,
      accounts: accounts ?? this.accounts,
      destinationAccountId: identical(destinationAccountId, _unset)
          ? this.destinationAccountId
          : destinationAccountId as String?,
      destinationAccountName: identical(destinationAccountName, _unset)
          ? this.destinationAccountName
          : destinationAccountName as String?,
      fireflyUrl: identical(fireflyUrl, _unset)
          ? this.fireflyUrl
          : fireflyUrl as String?,
      accessToken: identical(accessToken, _unset)
          ? this.accessToken
          : accessToken as String?,
      paymentAmount: paymentAmount ?? this.paymentAmount,
      tipSourceAccountId: identical(tipSourceAccountId, _unset)
          ? this.tipSourceAccountId
          : tipSourceAccountId as String?,
      tipSourceAccountName: identical(tipSourceAccountName, _unset)
          ? this.tipSourceAccountName
          : tipSourceAccountName as String?,
    );
  }

  // Total gabungan semua grup
  double get total => groups.fold(0.0, (sum, group) => sum + group.total);

  // Kembalian
  double get changeAmount => paymentAmount - total;

  // Apakah ada tip aktif (akun sumber tip dipilih dan ada kembalian)
  bool get hasTip =>
      tipSourceAccountId != null && paymentAmount > total;

  // Nominal tip = kembalian jika tip aktif
  double get tipAmount => hasTip ? (paymentAmount - total) : 0.0;

  // Helper validasi
  bool get hasItems => groups.any((g) => g.items.isNotEmpty);

  bool get allGroupsHaveSource =>
      groups.isEmpty || groups.every((g) => g.hasSource || g.items.isEmpty);

  @override
  String toString() {
    return 'ReceiptState(groups: $groups, transactionDate: $transactionDate, accounts: $accounts, destinationAccountId: $destinationAccountId, destinationAccountName: $destinationAccountName, fireflyUrl: $fireflyUrl, accessToken: $accessToken, paymentAmount: $paymentAmount, tipSourceAccountId: $tipSourceAccountId, tipSourceAccountName: $tipSourceAccountName)';
  }
}
