import 'package:uuid/uuid.dart';
import 'package:barber_app/core/database/database_service.dart';
import 'package:barber_app/features/finances/data/models/transaction_model.dart';

class TransactionRepository {
  final _uuid = const Uuid();

  String? get _currentUserId => DatabaseService.getCurrentUserId();

  // Criar transação de receita a partir de um corte
  Future<TransactionModel?> createRevenueFromHaircut({
    required String haircutId,
    required double amount,
    required String clientName,
    required String serviceType,
    bool isPaid = true,
  }) async {
    if (_currentUserId == null) return null;

    final transaction = TransactionModel(
      id: _uuid.v4(),
      userId: _currentUserId!,
      type: TransactionType.revenue,
      amount: amount,
      description: '$serviceType - $clientName',
      dueDate: DateTime.now(),
      isPaid: isPaid,
      paidDate: isPaid ? DateTime.now() : null,
      haircutId: haircutId,
      createdAt: DateTime.now(),
    );

    await DatabaseService.transactionsBoxInstance.put(
      transaction.id,
      transaction,
    );
    return transaction;
  }

  // Criar despesa
  Future<TransactionModel?> createExpense({
    required double amount,
    required String description,
    required DateTime dueDate,
    bool isPaid = false,
  }) async {
    if (_currentUserId == null) return null;

    final transaction = TransactionModel(
      id: _uuid.v4(),
      userId: _currentUserId!,
      type: TransactionType.expense,
      amount: amount,
      description: description.trim(),
      dueDate: dueDate,
      isPaid: isPaid,
      paidDate: isPaid ? DateTime.now() : null,
      createdAt: DateTime.now(),
    );

    await DatabaseService.transactionsBoxInstance.put(
      transaction.id,
      transaction,
    );
    return transaction;
  }

  // Criar receita manual
  Future<TransactionModel?> createRevenue({
    required double amount,
    required String description,
    required DateTime dueDate,
    bool isPaid = false,
  }) async {
    if (_currentUserId == null) return null;

    final transaction = TransactionModel(
      id: _uuid.v4(),
      userId: _currentUserId!,
      type: TransactionType.revenue,
      amount: amount,
      description: description.trim(),
      dueDate: dueDate,
      isPaid: isPaid,
      paidDate: isPaid ? DateTime.now() : null,
      createdAt: DateTime.now(),
    );

    await DatabaseService.transactionsBoxInstance.put(
      transaction.id,
      transaction,
    );
    return transaction;
  }

  // Listar todas as transações
  List<TransactionModel> getAllTransactions() {
    if (_currentUserId == null) return [];
    return DatabaseService.transactionsBoxInstance.values
        .where((t) => t.userId == _currentUserId)
        .toList()
      ..sort((a, b) => b.createdAt.compareTo(a.createdAt));
  }

  // Receitas
  List<TransactionModel> getRevenues() {
    return getAllTransactions()
        .where((t) => t.type == TransactionType.revenue)
        .toList();
  }

  // Despesas
  List<TransactionModel> getExpenses() {
    return getAllTransactions()
        .where((t) => t.type == TransactionType.expense)
        .toList();
  }

  // Pendentes a receber
  double getPendingReceivables() {
    return getRevenues()
        .where((t) => !t.isPaid)
        .fold(0.0, (sum, t) => sum + t.amount);
  }

  // Pendentes a pagar
  double getPendingPayables() {
    return getExpenses()
        .where((t) => !t.isPaid)
        .fold(0.0, (sum, t) => sum + t.amount);
  }

  // Total recebido (pago)
  double getTotalReceived() {
    return getRevenues()
        .where((t) => t.isPaid)
        .fold(0.0, (sum, t) => sum + t.amount);
  }

  // Total pago
  double getTotalPaid() {
    return getExpenses()
        .where((t) => t.isPaid)
        .fold(0.0, (sum, t) => sum + t.amount);
  }

  // Dashboard Helpers

  List<double> getLast7DaysRevenue() {
    final now = DateTime.now();
    final List<double> dailyRevenue = List.filled(7, 0.0);

    // Obtém todas as transações
    final allTransactions =
        getAllTransactions(); // Use o helper que filtra pelo usuário
    if (allTransactions.isEmpty) return dailyRevenue;

    for (int i = 0; i < 7; i++) {
      final targetDate = now.subtract(Duration(days: 6 - i));

      final dayRevenue = allTransactions
          .where(
            (t) =>
                t.type == TransactionType.revenue &&
                t.dueDate.year == targetDate.year &&
                t.dueDate.month == targetDate.month &&
                t.dueDate.day == targetDate.day,
          )
          .fold(0.0, (sum, t) => sum + t.amount);

      dailyRevenue[i] = dayRevenue;
    }

    return dailyRevenue;
  }

  // Saldo
  double getBalance() {
    return getTotalReceived() - getTotalPaid();
  }

  // Marcar como pago
  Future<TransactionModel?> markAsPaid(String id) async {
    final transaction = DatabaseService.transactionsBoxInstance.get(id);
    if (transaction == null) return null;

    final updated = transaction.copyWith(
      isPaid: true,
      paidDate: DateTime.now(),
    );

    await DatabaseService.transactionsBoxInstance.put(id, updated);
    return updated;
  }

  // Deletar transação
  Future<void> deleteTransaction(String id) async {
    await DatabaseService.transactionsBoxInstance.delete(id);
  }

  // Transações do mês
  List<TransactionModel> getMonthTransactions() {
    final now = DateTime.now();
    final monthStart = DateTime(now.year, now.month, 1);

    return getAllTransactions()
        .where((t) => t.createdAt.isAfter(monthStart))
        .toList();
  }

  Future<void> addTransaction(TransactionModel transaction) async {
    await DatabaseService.transactionsBoxInstance.put(
      transaction.id,
      transaction,
    );
  }
}
