<?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()
    {
        $userId = $this->getFormOption('userId');

        $this->setFormOption('novalidate', 'novalidate');
        $this->add('user_id', 'select', $this->getUserIdOptions($userId));
        $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.
     *
     * @param  int|null $userId
     * @return array
     */
    protected function getUserIdOptions(?int $userId = null)
    {
        $defaultUserId = $userId;
        if (!$defaultUserId) {
            $defaultUserId = $this->getBestUserChoice();
        }

        $options = [
            'label' => 'Participant',
            'attr' => [
                'class' => 'select2 js-data-participant-lookup',
                'data-key' => $defaultUserId,
            ],
            'choices' => [],
            'selected' => $defaultUserId,
        ];

        if ($userId) {
            // user given is readonly and not required
            $options['attr']['readonly'] = true;
            $options['attr']['disabled'] = true;
        } else {
            // user choice is required
            $options['rules'] = [
                'required',
                'exists:Ignite\Core\Entities\User,user_id'
            ];
        }

        return $options;
    }

    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()
    {
        $help = '<ul><li>Use this to manually adjust how many points the user has received (earned) or redeemed.</li>'
            . '<li>You may want to consider the tax implications for which type it should be.<ul>'
            . '<li>MANUAL-RECEIVE points usually WILL NOT effect their taxable amount for catalog programs.</li>'
            . '<li>MANUAL-REDEEM points usually WILL effect the total taxable amount for catalog programs.</li>'
            . '</ul></li><li>You can adjust either by adding more points or removing points.'
            . ' In either case, if you intend to REMOVE points, you MUST add a minus sign for the value below.'
            . '</li></ul>';

        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' => '',
            'help_block' => [
                'text' => $help,
                'attr' => ['class' => 'help-block']
            ],
        ];
    }

    protected function getValueOptions()
    {
        return [
            'label' => 'Value',
            'rules' => ['required'],
            'attr' => ['class' => 'form-control'],
            'help_block' => [
                'text' => 'If 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|required|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',
            'attr' => [
                'placeholder' => 'Add some additional context if needed...',
            ],
        ];
    }

    /**
     * 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()
    {
        return auth()->id();
    }
}
