<?php

namespace Ignite\Core\Models\Dashboard\Charts;

use Carbon\Carbon;
use Ignite\Core\Entities\Filters\QueryPermissionFilters;
use Ignite\Core\Facades\Format;
use Ignite\Core\Models\Dashboard\Donut;
use Illuminate\Support\Facades\DB;

class AwardsByOfferDonut extends Donut
{
    /**
     * Create a new stat instance.
     *
     * @param array|object $attributes
     */
    public function __construct($attributes = [])
    {
        $attributes = parent::__construct(array_merge([
            'label' => 'Awards by Offer',
            'colors' => [
                "#ff595a", // 01 tomato
                "#10b9a2", // 02 lightseagreen
                "#8e82c1", // 03 mediumpurple
                "#cb5e93", // 04 palevioletred
                "#bed73c", // 05 yellowgreen
                "#eb961d", // 06 goldenrod
                "#626491", // 07 slategray
                "#febc14", // 08 orange -- really looks yellow
                "#f15622", // 09 chocolate (looks dark orange)
                "#575d60", // 10 dimgray
                "#7f2c2c", // 11 saddlebrown
            ],
        ], $attributes ?? []));
    }


    /**
     * The HTML element ID.
     *
     * @return string
     */
    public function getElement()
    {
        return 'awards-by-offer';
    }

    /**
     * The chart size in the layout.
     *
     * @return string
     */
    public function getSize()
    {
        return $this->get('size', 'col-xs-6 col-sm-3');
    }

    /**
     * Get the correct data value from storage.
     *
     * @return mixed
     */
    public function getData()
    {
        if (! $this->get('data', false)) {
            /**
             * @var \Carbon\Carbon $start
             * @var \Carbon\Carbon $end
             */
            list($start, $end) = $this->getDateRange();

            $this->attributes['data'] = $this->byOfferQuery($start, $end)
                ->get()
                ->map(function ($row) {
                    $row->x = $row->x;
                    $row->y = (int)Format::amount($row->y, 2);
                    return $row;
                });
        }

        return $this->get('data');
    }

    /**
     * @param Carbon $start
     * @param Carbon $end
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
     */
    protected function byOfferQuery(Carbon $start, Carbon $end)
    {
        /* This is a generic Awards by Offer report
         * -------------------------------------------------- //
         * The following should probably be updated per
         * project based on however points are awarded
         * (activity submissions, transactions, etc.)
         *
         * SQL:
         * select sum(activity_submission.value) as y,
         *        activity_offer.label as x
         * from activity
         *          join activity_offer on activity.offer_id = activity_offer.id
         *          left join activity_submission on activity.id = activity_submission.activity_id
         * group by activity_offer.id
         * -------------------------------------------------- */
        return QueryPermissionFilters::for('activity.submission.all.browse')->apply(
            DB::query()
                ->select(
                    DB::raw("activity_offer.label AS x"),
                    DB::raw('sum(activity_submission.value) as y')
                )
                ->from('activity')
                ->join('activity_offer', 'activity.offer_id', 'activity_offer.id')
                ->join('activity_submission', 'activity.id', 'activity_submission.activity_id')
                ->groupBy('activity_offer.id')
                ->whereBetween('activity.created_at', [$start->format('Y-m-d H:i:s'), $end->format('Y-m-d H:i:s')])
                ->whereNotIn('activity_submission.status', ['declined'])
                ->orderBy('y')
        );
    }
}
