<?php

namespace Ignite\Core\Http\ViewComposers;

use Ignite\Core\Models\Summary\Metric;
use Illuminate\Support\Collection;
use Illuminate\View\View;

class TransactionSummaryComposer
{
    /**
     * Bind data to the view.
     *
     * @param  View $view
     * @return void
     */
    public function compose(View $view)
    {
        $view->with('summary', $summary = $this->decorate($this->query()->map(function ($metric) {
            return app(Metric::class, (array) $metric);
        })->keyBy(function ($metric) {
            return $metric->name();
        })));

        $view->with('summaryTotal', $summary->sum(function ($metric) {
            return (int) $metric->count();
        }));
    }

    /**
     * Query the metrics from the database.
     *
     * @return Collection
     */
    protected function query()
    {
        $earnedQuery = app('db')->table('core_transaction')
            ->selectRaw('"earned" as name, COUNT(*) AS count, SUM(value) as total')
            ->where('user_id', '=', auth()->id())
            ->whereIn('type', [
                'EARNED', 'MANUAL-RECEIVE', 'RESET', 'RETURN', 'REFUND', 'EXPIRED', 'CANCELLED'
            ]);

        $redeemedQuery = app('db')->table('core_transaction')
            ->selectRaw('"redeemed" as name, COUNT(*) AS count, SUM(value) as total')
            ->where('user_id', '=', auth()->id())
            ->whereIn('type', [
                'REDEEMED', 'MANUAL-REDEEM'
            ]);

        return app('db')->table('core_transaction')
            ->selectRaw('"balance" as name, COUNT(*) as count, SUM(value) as total')
            ->where('user_id', '=', auth()->id())
            ->union($earnedQuery)
            ->union($redeemedQuery)
            ->get();
    }

    /**
     * Decorate the summary collection.
     *
     * @param  Collection $collection
     * @return Collection
     */
    protected function decorate(Collection $collection)
    {
        $allowedTypes = ['earned', 'redeemed', 'balance'];

        foreach ($allowedTypes as $allowedType) {
            if (! $collection->has($allowedType)) {
                $collection->push(app(Metric::class, [
                    'name' => $allowedType,
                    'count' => 0,
                    'total' => 0
                ]));
            }
        };

        return $collection->keyBy(function ($metric) {
            return $metric->name();
        });
    }
}
