<?php

namespace Ignite\Core\Console;

use Ignite\Core\Contracts\Repositories\TransactionRepository;
use Ignite\Core\Emails\BatchedEmailSummaryToProgramManager;
use Ignite\Core\Entities\Transaction;
use Ignite\Core\Notifications\NotifyParticipantWithTransactionPointsStatus;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Mail\Mailer;
use Illuminate\Support\Facades\DB;

/**
 */
class DailyTransactionsBatchedEmail extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'ignite:daily-transactions-batched-email';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = "Batch daily transactions into a single email";

    private Mailer $mailer;

    /**
     * @var TransactionRepository
     */
    private TransactionRepository $transactionRepository;

    /**
     * DailyTransactionsBatchedEmail constructor.
     *
     * @param Mailer                $mailer
     * @param TransactionRepository $transactionRepository
     */
    public function __construct(Mailer $mailer, TransactionRepository $transactionRepository)
    {
        parent::__construct();

        $this->mailer = $mailer;
        $this->transactionRepository = $transactionRepository;
    }

    /**
     * Execute the console command.
     */
    public function handle(): void
    {
        $transactions = Transaction::query()
            ->with('participant.user')
            ->select('user_id', DB::raw('SUM(value) as total'))
            ->whereBetween('created_at', [now()->subHours(24), now()])
            ->where('value', '>', 0)
            ->groupBy(['user_id'])
            ->get();

        if (count($transactions) === 0) {
            return;
        }

        $userWithTotalPoints = $transactions->pluck('total', 'user_id')->toArray();

        foreach ($transactions as $transaction) {
            $user = $transaction->participant->user;
            $data['value'] = $transaction->total;
            $data['balance'] = $this->transactionRepository->getBalance($transaction->user_id);
            $userTransactions = $this->getTransactionsCreatedToday($transaction->user_id);
            $user->notify(new NotifyParticipantWithTransactionPointsStatus($data, $userTransactions));
        }

        // this sends a summary email to the PM as well
        $this->mailer->send(new BatchedEmailSummaryToProgramManager($userWithTotalPoints));
    }

    /**
     * @param $userId
     * @return Collection
     */
    protected function getTransactionsCreatedToday($userId): Collection
    {
        return Transaction::query()
            ->select('value', 'description')
            ->whereBetween('created_at', [now()->subHours(24), now()])
            ->where('value', '>', 0)
            ->where('user_id', $userId)
            ->get();
    }
}
