import 'package:json_annotation/json_annotation.dart';

import '../global/utils.dart';

part 'transaction_model.g.dart';

enum TransactionType {
  income,
  expense,
}

@JsonSerializable()
class Transaction {
  const Transaction({
    this.id,
    required this.amount,
    required this.type,
    required this.budgetId,
    this.budgetCategoryId,
    required this.createdByUserId,
    required this.date,
    this.memo,
    this.createdAt,
    this.updatedAt,
    this.hide = false,
  });

  final int? id, budgetCategoryId;
  final int budgetId, createdByUserId;
  final double amount;
  final String? memo;
  final TransactionType type;

  @JsonKey(fromJson: boolFromJson, toJson: boolToJson)
  final bool hide;

  @JsonKey(fromJson: dateFromJson, toJson: dateToJson)
  final DateTime date;

  @JsonKey(fromJson: dateFromJson, toJson: dateToJson)
  final DateTime? createdAt;

  @JsonKey(fromJson: dateFromJson, toJson: dateToJson)
  final DateTime? updatedAt;

  factory Transaction.fromJson(Map<String, dynamic> json) =>
      _$TransactionFromJson(json);

  factory Transaction.copyWith(Transaction trans, Map<String, dynamic> data) =>
      Transaction(
        id: data['id'] ?? trans.id,
        amount: data['amount'] ?? trans.amount,
        type: data['type'] ?? trans.type,
        budgetId: data['budget_id'] ?? trans.budgetId,
        budgetCategoryId: data['budget_category_id'] ?? trans.budgetCategoryId,
        createdByUserId: data['created_by_user_id'] ?? trans.createdByUserId,
        date: data['date'] ?? trans.date,
        memo: data['memo'] ?? trans.memo,
        createdAt: data['created_at'] ?? trans.createdAt,
        updatedAt: data['updated_at'] ?? trans.updatedAt,
        hide: data['hide'] ?? trans.hide,
      );

  Map<String, dynamic> toJson() => _$TransactionToJson(this);
}
