<?php

/**
 * Copyright 2024-2025 Simply.IN Sp. z o.o.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the EUPL-1.2 or later.
 * You may not use this work except in compliance with the Licence.
 *
 * Copy of the Licence is available at:
 * https://joinup.ec.europa.eu/software/page/eupl
 * It is bundled with this package in the file LICENSE.txt
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Licence is distributed on an as is basis,
 * without warranties or conditions of any kind, either express or implied.
 * Check the Licence for the specific language governing permissions
 * and limitations under the License.
 *
 * @author   Simply.IN Sp. z o.o.
 * @copyright 2024-2025 Simply.IN Sp. z o.o.
 * @license   https://joinup.ec.europa.eu/software/page/eupl
 */

declare(strict_types=1);

namespace SimplyIn\Form\Type;

use SimplyIn\BackOffice\Environment;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\ColorType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;

if (!defined('_PS_VERSION_')) {
    exit;
}

final class SimplyInSettingsType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        /** @var array<string, int> $carrierChoices */
        $carrierChoices = $options['carrier_choices'];
        /** @var array<string, int> $orderStateChoices */
        $orderStateChoices = $options['order_state_choices'];
        /** @var bool $saveCheckboxForced */
        $saveCheckboxForced = $options['save_checkbox_forced'];

        $builder
            ->add('environment', ChoiceType::class, [
                'label' => 'Environment',
                // Derived from the enum's own cases/label() rather than hand-listed, so the two
                // stay in lockstep — the enum is the single closed source of truth.
                'choices' => array_combine(
                    array_map(static fn (Environment $environment): string => $environment->label(), Environment::cases()),
                    array_map(static fn (Environment $environment): string => $environment->value, Environment::cases()),
                ),
                'required' => true,
                'placeholder' => false,
                'help' => 'Which Simply.IN environment this shop connects to. Production is the correct choice for a live shop — Test sends data to a non-production environment and must never be left on for one.',
            ])
            ->add('secret_key', PasswordType::class, [
                'label' => 'Secret key',
                'required' => false,
                'always_empty' => true,
                'attr' => ['placeholder' => 'Leave blank to keep the current key'],
            ])
            ->add('payments_enabled', CheckboxType::class, [
                'label' => 'Enable SimplyIN payments',
                'required' => false,
                'false_values' => ['0'],
            ])
            ->add('save_checkbox', CheckboxType::class, [
                'label' => 'The "Remember your details with Simply.IN" checkbox is not selected by default for users who do not have an account at Simply.IN',
                'required' => false,
                'false_values' => ['0'],
                'disabled' => $saveCheckboxForced,
                'help' => $saveCheckboxForced
                    ? 'Currently locked by Simply.IN and cannot be changed here.'
                    : null,
            ])
            ->add('dpd_carrier_id', ChoiceType::class, $this->carrierField('DPD parcel locker carrier', $carrierChoices))
            ->add('dhl_carrier_id', ChoiceType::class, $this->carrierField('DHL parcel locker carrier', $carrierChoices))
            ->add('fedex_carrier_id', ChoiceType::class, $this->carrierField('FedEx parcel locker carrier', $carrierChoices))
            ->add('inpost_carrier_id', ChoiceType::class, $this->carrierField('InPost parcel locker carrier', $carrierChoices))
            ->add('orlen_carrier_id', ChoiceType::class, $this->carrierField('Orlen parcel locker carrier', $carrierChoices))
            ->add('ups_carrier_id', ChoiceType::class, $this->carrierField('UPS parcel locker carrier', $carrierChoices))
            ->add('default_carrier_id', ChoiceType::class, $this->carrierField('Default carrier', $carrierChoices))
            ->add('payment_status_pending', ChoiceType::class, [
                'label' => 'Order status for pending payments',
                'choices' => $orderStateChoices,
                'required' => false,
                'placeholder' => false,
            ])
            ->add('payment_status_canceled', ChoiceType::class, [
                'label' => 'Order status for canceled payments',
                'choices' => $orderStateChoices,
                'required' => false,
                'placeholder' => false,
            ])
            ->add('bar_enabled', CheckboxType::class, [
                'label' => 'Show the Simply.IN bar above the e-mail field',
                'required' => false,
                'false_values' => ['0'],
            ])
            ->add('bar_color', CheckboxType::class, [
                'label' => 'Colored bar (off = grayscale)',
                'required' => false,
                'false_values' => ['0'],
            ])
            ->add('badge_color', CheckboxType::class, [
                'label' => 'Colored badge (off = grayscale)',
                'required' => false,
                'false_values' => ['0'],
            ])
            ->add('confirmation_heading_override', CheckboxType::class, [
                'label' => 'Show the real payment status in the order-confirmation heading',
                'required' => false,
                'false_values' => ['0'],
                'help' => 'When enabled, an order the shop has not been paid for yet shows "Order placed" with no confirmation tick, switching to "Order confirmed" once the Simply.IN payment actually succeeds — instead of the theme\'s default heading, which shows the order as confirmed even while unpaid.',
            ])
            ->add('accent_color', ColorType::class, [
                'label' => 'Accent color',
                'required' => false,
                'help' => 'Accent color used across the Simply.IN checkout: buttons, input focus, checkboxes, selected items and the order confirmation box border.',
            ])
            ->add('font_color', ColorType::class, [
                'label' => 'Font color',
                'required' => false,
                'help' => 'Text color used across the Simply.IN checkout (labels and action menu text).',
            ]);
    }

    public function finishView(FormView $view, FormInterface $form, array $options): void
    {
        $legacyIds = [
            'secret_key' => 'SIMPLYIN_SECRET_KEY',
            'dpd_carrier_id' => 'SIMPLYIN_DPD_CARRIER_ID',
            'dhl_carrier_id' => 'SIMPLYIN_DHL_CARRIER_ID',
            'fedex_carrier_id' => 'SIMPLYIN_FEDEX_CARRIER_ID',
            'inpost_carrier_id' => 'SIMPLYIN_INPOST_CARRIER_ID',
            'orlen_carrier_id' => 'SIMPLYIN_ORLEN_CARRIER_ID',
            'ups_carrier_id' => 'SIMPLYIN_UPS_CARRIER_ID',
            'default_carrier_id' => 'SIMPLYIN_DEFAULT_CARRIER_ID',
        ];
        foreach ($legacyIds as $child => $id) {
            if (isset($view->children[$child])) {
                $view->children[$child]->vars['id'] = $id;
            }
        }
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver
            ->setDefaults([
                'carrier_choices' => [],
                'order_state_choices' => [],
                'save_checkbox_forced' => false,
                'translation_domain' => 'Modules.Simplyin.Admin',
            ])
            ->setAllowedTypes('carrier_choices', 'array')
            ->setAllowedTypes('order_state_choices', 'array')
            ->setAllowedTypes('save_checkbox_forced', 'bool');
    }

    /**
     * @param array<string, int> $choices
     *
     * @return array<string, mixed>
     */
    private function carrierField(string $label, array $choices): array
    {
        return [
            'label' => $label,
            'choices' => $choices,
            'required' => false,
            'placeholder' => false,
        ];
    }
}
