<?php

namespace Ignite\Core\Http\Forms;

use Exception;
use Ignite\Core\Models\Form\CoreForm;
use Ignite\Core\Models\Form\GroupByTableTrait;
use Illuminate\Http\RedirectResponse;
use Kris\LaravelFormBuilder\Fields\FormField;

class ProfileForm extends CoreForm
{
    use GroupByTableTrait;

    /**
     * Should the values be grouped by table.
     *
     * @var bool
     */
    protected $groupByTable = true;

    /**
     * Build the enrollment form.
     *
     * @return mixed|void
     * @throws Exception
     */
    public function buildForm()
    {
        $this->setFormOptions([
            'id' => 'profile-form',
            'novalidate'
        ]);

        $this->buildFromSchema('enrollment', $this->getData('renderGroups', true));
        $this->applySectionHeadingValues();

        if (! empty($type = $this->getFormOption('internal'))) {
            $this->getField('internal')->setOption('selected', $type)->setValue($type);
        }

        if (isset($this->data['readonly'])) {
            /** @var FormField $field */
            foreach ($this->fields as $field) {
                $field->setOption('attr.readonly', true);
                $field->disable();

                if (in_array($field->getType(), ['button', 'submit', 'reset'])) {
                    $this->remove($field->getName());
                }
            }
        }

        /* Remove reCAPTCHA from routes that are unnecessary
         * -------------------------------------------------- */
        if (!in_array(url()->current(), $this->routesForRecaptcha())) {
            $this->remove(config('services.recaptcha.field_name'));
        }
    }

    /**
     * Alter the schema before building the profile form.
     *
     * @param array $schema
     * @return array
     */
    protected function schemaAlter(array $schema): array
    {
        $schema = parent::schemaAlter($schema);

        $schema = $this->insertSectionHeading(
            $schema,
            'first',
            'section_personal_information',
            'Personal Information'
        );

        $schema = $this->insertSectionHeading(
            $schema,
            'company',
            'section_company_address',
            'Company & Address'
        );

        return $this->insertSectionHeading(
            $schema,
            'ssn',
            'section_security',
            'Security'
        );
    }

    /**
     * Insert a heading row before a schema field.
     *
     * @param array $schema
     * @param string $beforeField
     * @param string $headingName
     * @param string $headingLabel
     * @return array
     */
    protected function insertSectionHeading(
        array $schema,
        string $beforeField,
        string $headingName,
        string $headingLabel
    ): array {
        $fields = $schema['fields'] ?? [];
        $fieldNames = array_column($fields, 'name');
        $position = array_search($beforeField, $fieldNames, true);

        if ($position === false) {
            return $schema;
        }

        $heading = [
            'frontend_type' => 'static',
            'name' => $headingName,
            'label' => false,
            'label_show' => false,
            'tag' => 'div',
            'value' => $headingLabel,
            'attr' => [
                'class' => 'profile-section-heading',
            ],
            'wrapper' => [
                'class' => 'form-group',
            ],
        ];

        array_splice($fields, $position, 0, [$heading]);
        $schema['fields'] = $fields;

        return $schema;
    }

    /**
     * Ensure inserted static section headings have visible values.
     *
     * @return void
     */
    protected function applySectionHeadingValues()
    {
        $headings = [
            'section_personal_information' => 'Personal Information',
            'section_company_address' => 'Company & Address',
            'section_security' => 'Security',
        ];

        foreach ($headings as $fieldName => $label) {
            if (! $this->has($fieldName)) {
                continue;
            }

            $field = $this->getField($fieldName);

            if ($this->isViewingBackend()) {
                $field->setOption('label', $label);
                $field->setOption('label_show', true);
                $field->setOption('label_attr.class', 'control-label col-sm-3 text-bold');
                $field->setOption('label_attr.style', 'border-bottom: 1px solid #d2d6de; padding-bottom: 4px;');
                $field->setOption('value', '');
                $field->setOption('default_value', '');
                $field->setOption('attr.class', 'hidden');
                continue;
            }

            $field->setOption('value', $label);
            $field->setOption('default_value', $label);
            $field->setOption('attr.class', 'profile-section-heading');
        }
    }

    /**
     * Returns an array of routes in which reCAPTCHA should be used.
     * This is meant to be extended by sites that use more than one
     * enrollment form. It will pass the built-in enrollment form
     * by default.
     *
     * @return array
     */
    public function routesForRecaptcha(): array
    {
        $routes = [];
        if (config('services.recaptcha.sitekey')) {
            $routes[] = route('participant.enroll.create');
        }

        return $routes;
    }
}
