<?php

namespace App\Services;

use App\Models\Account;
use App\Models\Transaction;
use Illuminate\Support\Carbon;

class TransactionLimitService
{
      /**
       * Check if an amount is allowed based on account limits.
       *
       * @return array{allowed: bool, message: ?string}
       */
      public function check(Account $account, string $amount): array
      {
            // normalize
            $amount = (string) $amount;

            // 1) Per-transaction limit
            if (!empty($account->per_transaction_limit)) {
                  if (bccomp($amount, (string) $account->per_transaction_limit, 2) === 1) {
                        return [
                              'allowed' => false,
                              'message' => "This transaction exceeds your per-transaction limit.",
                        ];
                  }
            }

            // 2) Daily limit
            if (!empty($account->daily_transaction_limit)) {
                  $dailyTotal = $this->getDailySpent($account);

                  $dailyAfter = bcadd($dailyTotal, $amount, 2);

                  if (bccomp($dailyAfter, (string) $account->daily_transaction_limit, 2) === 1) {
                        return [
                              'allowed' => false,
                              'message' => "This transaction exceeds your daily transaction limit.",
                        ];
                  }
            }

            // 3) Monthly limit
            if (!empty($account->monthly_transaction_limit)) {
                  $monthlyTotal = $this->getMonthlySpent($account);

                  $monthlyAfter = bcadd($monthlyTotal, $amount, 2);

                  if (bccomp($monthlyAfter, (string) $account->monthly_transaction_limit, 2) === 1) {
                        return [
                              'allowed' => false,
                              'message' => "This transaction exceeds your monthly transaction limit.",
                        ];
                  }
            }

            return [
                  'allowed' => true,
                  'message' => null,
            ];
      }

      /**
       * Total spent today for this account.
       */
      private function getDailySpent(Account $account): string
      {
            $start = Carbon::today();
            $end = Carbon::tomorrow();

            // Sum only debit transactions
            $sum = Transaction::where('account_id', $account->id)
                  ->where('type', 'transfer_out')
                  ->whereIn('status', [
                        Transaction::STATUS_PENDING,
                        Transaction::STATUS_APPROVED,
                  ])
                  ->whereBetween('created_at', [$start, $end])
                  ->sum('amount');

            return (string) $sum;
      }

      /**
       * Total spent this month for this account.
       */
      private function getMonthlySpent(Account $account): string
      {
            $start = Carbon::now()->startOfMonth();
            $end = Carbon::now()->endOfMonth();

            $sum = Transaction::where('account_id', $account->id)
                  ->where('type', 'transfer_out')
                  ->whereIn('status', [
                        Transaction::STATUS_PENDING,
                        Transaction::STATUS_APPROVED,
                  ])
                  ->whereBetween('created_at', [$start, $end])
                  ->sum('amount');

            return (string) $sum;
      }
}
