<?php

namespace Ignite\Core\Http\ViewComposers;

use Ignite\Core\Models\Menu\ParticipantMenu;
use Illuminate\Support\HtmlString;
use Illuminate\View\View;
use Ignite\Core\Program;

class ParticipantMenuComposer
{
    /**
     * @var Program
     */
    private $program;

    /**
     * @var ParticipantMenu
     */
    private $manager;

    /**
     * MenuComposer constructor.
     *
     * @param Program $program
     */
    public function __construct(Program $program, ParticipantMenu $manager)
    {
        $this->program = $program;
        $this->manager = $manager;
    }

    /**
     * Bind data to the view.
     *
     * @param  View  $view
     * @return void
     */
    public function compose(View $view)
    {
        if (! $view->participant) {
            return;
        }

        $participantId = (int) $view->participant->getId();

        $this->manager->merge(
            $this->manager->hydrateItems(
                $this->getItems($participantId)
            )
        );

        $view->with('links', new HtmlString($this->manager->render($participantId)));
    }

    /**
     * Get the items for the menu.
     *
     * @param  int $participantId
     * @return \Illuminate\Support\Collection
     */
    protected function getItems($participantId)
    {
        return collect([
            [
                'position' => 10,
                'url' => route('admin.participant.show', ['userId' => $participantId]),
                'label' => 'Participant Info',
                'icon' => 'user',
                'allow' => auth()->user()->can('core.user.participant.browse')
            ],
            [
                'position' => 20,
                'url' => route('admin.participant.transactions', ['participant' => $participantId]),
                'label' => 'Transactions',
                'icon' => 'check-circle-o',
                'allow' => auth()->user()->can('core.user.transaction.browse'),
                'badge' => $this->countTransactions($participantId)
            ],
            [
                'position' => 30,
                'url' => route('admin.participant.notes', ['participant' => $participantId]),
                'label' => 'Notes',
                'icon' => 'sticky-note',
                'allow' => auth()->user()->can('core.user.notes.browse'),
                'badge' => $this->countNotes($participantId)
            ],
            [
                'position' => 40,
                'url' => route('admin.participant.history', ['participant' => $participantId]),
                'label' => 'History',
                'icon' => 'history',
                'allow' => auth()->user()->can('core.user.history.browse'),
                'badge' => $this->countHistory($participantId)
            ],
            [
                'position' => 50,
                'url' => route('admin.participant.activity', ['participant' => $participantId]),
                'label' => 'Activity',
                'icon' => 'heartbeat',
                'allow' => auth()->user()->can('core.user.activity.browse'),
                'badge' => $this->countActivity($participantId),
            ],
            [
                'position' => 60,
                'url' => route('admin.impersonate', [$participantId]),
                'label' => 'Impersonate',
                'icon' => 'user-secret',
                'allow' => auth()->user()->can('core.user.impersonate'),
            ],

            /*
             * We've decided to hide this ability for now until we fully settle on how soft-deleting a user should
             * function. Right now, the participant is allowed to be deleted as long as they do not have any
             * transactions. When they are deleted, their participant record is marked as deleted. This is currently
             * causing an issue with the activity module: When the trashed user had activity submissions, the activity
             * submissions listing breaks when trying to show those submissions because of a null reference error for
             * the participant.
             *
            [
                'position' => 70,
                'url' => route('admin.participant.delete', ['id' => $participantId]),
                'label' => 'Delete Participant',
                'icon' => 'trash text-danger',
                'allow' => auth()->user()->can('core.user.participant.delete')
            ],
            */
        ]);
    }

    /**
     * Count the number of transaction entries for the participant.
     *
     * @param int $participantId
     * @return array
     */
    protected function countTransactions($participantId)
    {
        return app(\Ignite\Core\Entities\Transaction::class)
            ->query()
            ->where('user_id', $participantId)
            ->count();
    }

    /**
     * Count the number of history entries for the participant.
     *
     * @param  int $participantId
     * @return array
     */
    protected function countHistory($participantId)
    {
        return app(\Ignite\Core\Entities\Audit::class)
            ->query()
            ->where('context_type', 'Ignite\Core\Entities\Participant')
            ->where('context_id', $participantId)
            ->count();
    }

    /**
     * Count the number of activity entries for the participant.
     *
     * @param  int $participantId
     * @return array
     */
    protected function countActivity($participantId)
    {
        return app(\Ignite\Core\Entities\Audit::class)
            ->query()
            ->where('user_id', $participantId)
            ->count();
    }

    /**
     * Count the number of note entries for the participant.
     *
     * @param  int $participantId
     * @return array
     */
    protected function countNotes($participantId)
    {
        return app(\Ignite\Core\Entities\Note::class)
            ->query()
            ->where('table_primary_id', $participantId)
            ->count();
    }
}
