<?php

namespace Ignite\Core\Http\Forms\Admin;

use Ignite\Core\Entities\Participant;
use Ignite\Core\Entities\Transaction;
use Illuminate\Support\Arr;
use Illuminate\Validation\Rule;
use Kris\LaravelFormBuilder\Form;

class TransactionForm extends Form
{
    /**
     * Build the form.
     *
     * @return \Ignite\Core\Http\Forms\Admin\TransactionForm
     */
    public function buildForm()
    {
        $this->setFormOption('novalidate', 'novalidate');
        $this->add('user_id', 'select', $this->getUserIdOptions());
        $this->add('transaction_date', 'text', $this->getTransactionDateOptions());
        $this->add('tax_date', 'text', $this->getTaxDateOptions());
        $this->add('type', 'select', $this->getTypeOptions());
        $this->add('value', 'number', $this->getValueOptions());
        $this->add('description', 'text', $this->getDescriptionOptions());
        $this->add('notes', 'textarea', $this->getNotesOptions());
        $this->add('submit', 'submit', $this->getSaveButtonOptions());

        return $this;
    }

    /**
     * The options for the label field.
     *
     * @return array
     */
    protected function getUserIdOptions()
    {
        $choices = Arr::prepend($this->getUserChoices(), 'Please choose a participant...', '');

        return [
            'label' => 'Participant',
            'rules' => ['required', 'exists:Ignite\Core\Entities\User,user_id'],
            'attr' => ['class' => 'select2'],
            'choices' => $choices,
            'selected' => $this->getBestUserChoice()
        ];
    }

    protected function getTransactionDateOptions()
    {
        return [
            'label' => 'Transaction Date',
            'rules' => ['required', 'date:Y-m-d'],
            'attr' => ['class' => 'form-control datepicker'],
            'default_value' => now()->format('Y-m-d H:i:s')
        ];
    }

    protected function getTaxDateOptions()
    {
        return [
            'label' => 'Tax Date',
            'rules' => ['required', 'date:Y-m-d'],
            'attr' => ['class' => 'form-control datepicker'],
            'default_value' => now()->format('Y-m-d H:i:s')
        ];
    }

    protected function getTypeOptions()
    {
        return [
            'label' => 'Adjustment Type',
            'rules' => ['required', 'in:MANUAL-RECEIVE,MANUAL-REDEEM'],
            'attr' => ['class' => 'form-control select2'],
            'choices' => [
                '' => 'Please choose a type...',
                'MANUAL-RECEIVE' => 'MANUAL-RECEIVE',
                'MANUAL-REDEEM' => 'MANUAL-REDEEM'
            ],
            'selected' => ''
        ];
    }

    protected function getValueOptions()
    {
        return [
            'label' => 'Value',
            'rules' => ['required'],
            'attr' => ['class' => 'form-control'],
            'help_block' => [
                'text' => 'When subtracting points, you must include the minus sign, e.g. -100.',
                'tag' => 'p',
                'attr' => ['class' => 'help-block']
            ],
            'default_value' => 0
        ];
    }

    /**
     * The options for the code field.
     *
     * @return array
     */
    protected function getDescriptionOptions()
    {
        return [
            'label' => 'Description',
            'rules' => 'present|nullable|min:4|max:255'
        ];
    }

    /**
     * The options for the code field.
     *
     * @return array
     */
    protected function getNotesOptions()
    {
        return [
            'label' => 'Notes',
            'rules' => 'present|nullable|min:4|max:500'
        ];
    }

    /**
     * The options for the save button.
     *
     * @return array
     */
    protected function getSaveButtonOptions()
    {
        return [
            'attr' => ['class' => 'btn btn-primary'],
            'label' => 'Create'
        ];
    }

    /**
     * The participants to choose from.
     *
     * @return array
     */
    protected function getUserChoices()
    {
        return Participant::query()
            ->whereNull('deleted_at')
            ->get()
            ->mapWithKeys(function ($participant) {
                return [$participant->getKey() => $participant->fullName()];
            })
            ->toArray();
    }

    /**
     * Attempt to find the best choice based on the current model value.
     *
     * @return int|null
     */
    protected function getBestUserChoice()
    {
        if (! $this->model) {
            return null;
        }

        $result = Participant::query()->where('email', $this->model->identifier)->first();

        return optional($result)->getKey() ?? null;
    }
}
