<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\AdminBundle\Form;

use Ferienpass\AdminBundle\Form\CompoundType\PeriodType;
use Ferienpass\CoreBundle\Entity\PageConfig;
use Ferienpass\CoreBundle\Settings\MailConfigManager;
use Ferienpass\CoreBundle\Settings\SystemSettingsManager;
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\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * The whole Systemkonfiguration screen as one form.
 *
 * Values that the deployment fixes — an ADMIN_EMAIL from the environment, a
 * `ferienpass.*` option from YAML — are NOT added as fields, not merely
 * disabled: a submitted form maps every missing-but-registered field to null
 * (`clearMissing`), which would wipe the very value the deployment pinned.
 * The template renders those as locked values with a chip instead.
 */
class SystemConfigType extends AbstractType
{
    public function __construct(
        private readonly MailConfigManager $mailConfig,
        private readonly SystemSettingsManager $systemSettings,
    ) {
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => PageConfig::class,
            'label' => false,
            'translation_domain' => 'admin',
            // True when a configured online payment provider forces payments
            // on — the toggle then is not a real choice and stays out of the
            // form (the template shows the lock).
            'payments_locked_by_provider' => false,
        ]);

        $resolver->setAllowedTypes('payments_locked_by_provider', 'bool');
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $toggle = static fn (array $extra = []) => $extra + ['required' => false, 'label' => false, 'block_prefix' => 'switch'];

        // Identität & Erscheinungsbild — the logo lives in its own live
        // component (file uploads do not survive form re-renders).
        $builder
            ->add('pageTitle', TextType::class, ['label' => false])
            ->add('colorPrimary', TextType::class, ['label' => false, 'required' => false, 'attr' => ['placeholder' => '#1c6b9c', 'class' => 'font-mono']])
        ;

        // E-Mail-Absender
        if (!$this->mailConfig->isAdminEmailFromEnv()) {
            $builder->add('adminEmail', EmailType::class, ['label' => false]);
        }
        $builder->add('adminEmailName', TextType::class, ['label' => false, 'required' => false, 'attr' => ['placeholder' => 'z. B. Ferienpass Musterstadt']]);
        if (!$this->mailConfig->isReplyToFromConfig()) {
            $builder
                ->add('replyToEmail', EmailType::class, ['label' => false, 'required' => false, 'attr' => ['placeholder' => 'ferienpass@musterstadt.de']])
                ->add('replyToName', TextType::class, ['label' => false, 'required' => false, 'attr' => ['placeholder' => '—']])
            ;
        }

        // Anmeldung & Buchung
        if (!$this->systemSettings->isFriendsBookingFromConfig()) {
            $builder->add('friendsBooking', CheckboxType::class, $toggle());
        }
        if (!$this->systemSettings->isRequirePostalAddressFromConfig()) {
            $builder->add('requirePostalAddress', CheckboxType::class, $toggle());
        }
        if (!$this->systemSettings->isPreferredPostalCodesFromConfig()) {
            $builder->add('preferredPostalCodes', TextType::class, ['label' => false, 'required' => false, 'attr' => ['placeholder' => '48529, 48531']]);
        }
        if (!$this->systemSettings->isAgeToleranceFromConfig()) {
            $builder->add('ageTolerance', PeriodType::class, ['label' => false, 'units' => ['days', 'weeks', 'months']]);
        }

        // Abmeldung
        if (!$this->systemSettings->isWithdrawGracePeriodFromConfig()) {
            $builder->add('withdrawGracePeriod', PeriodType::class, ['label' => false, 'units' => ['hours', 'days', 'weeks']]);
        }
        if (!$this->systemSettings->isNoWithdrawAfterGracePeriodFromConfig()) {
            $builder->add('noWithdrawAfterGracePeriod', CheckboxType::class, $toggle());
        }
        if (!$this->systemSettings->isNoWithdrawAfterApplicationDeadlineFromConfig()) {
            $builder->add('noWithdrawAfterApplicationDeadline', CheckboxType::class, $toggle());
        }

        // Erinnerungen
        if (!$this->systemSettings->isRemindAttendanceFromConfig()) {
            $builder->add('remindAttendance', CheckboxType::class, $toggle());
        }
        if (!$this->systemSettings->isAttendanceRemindPeriodFromConfig()) {
            $builder->add('attendanceRemindPeriod', PeriodType::class, ['label' => false, 'units' => ['hours', 'days']]);
        }

        // Zahlungen — an online provider forces payments on; the template shows
        // the lock, so the field only exists while the choice is real.
        if (!$this->systemSettings->isPaymentsEnabledFromConfig() && !$options['payments_locked_by_provider']) {
            $builder->add('paymentsEnabled', CheckboxType::class, $toggle());
        }
        if (!$this->systemSettings->isPaymentAllowSelectFromConfig()) {
            $builder->add('paymentAllowSelect', CheckboxType::class, $toggle());
        }
        if (!$this->systemSettings->isReceiptNumberPrefixFromConfig()) {
            $builder->add('receiptNumberPrefix', TextType::class, ['label' => false, 'required' => false, 'attr' => ['placeholder' => '2026/', 'maxlength' => 20, 'class' => 'font-mono']]);
        }

        // Datenschutz & Aufbewahrung
        if (!$this->systemSettings->isEraseDataPeriodFromConfig()) {
            $builder->add('eraseDataPeriod', PeriodType::class, ['label' => false, 'units' => ['weeks', 'months', 'years']]);
        }
        $builder->add('hostDataRetentionPeriod', PeriodType::class, ['label' => false, 'units' => ['days', 'weeks', 'months']]);

        // Verantwortliche Stelle
        $builder
            ->add('imprintName', TextType::class, ['label' => false, 'required' => false, 'attr' => ['placeholder' => '—']])
            ->add('imprintDepartment', TextType::class, ['label' => false, 'required' => false, 'attr' => ['placeholder' => '—']])
            ->add('imprintStreet', TextType::class, ['label' => false, 'required' => false, 'attr' => ['placeholder' => '—']])
            ->add('imprintPostalCode', TextType::class, ['label' => false, 'required' => false, 'attr' => ['placeholder' => '—']])
            ->add('imprintCity', TextType::class, ['label' => false, 'required' => false, 'attr' => ['placeholder' => '—']])
        ;

        // Sprache & Darstellung
        if (!$this->systemSettings->isParticipantListSortFromConfig()) {
            $builder->add('participantListSort', ChoiceType::class, [
                'label' => false,
                'choices' => ['Nachname' => 'lastname', 'Vorname' => 'firstname'],
            ]);
        }
        $builder
            ->add('language', ChoiceType::class, [
                'label' => false,
                'choices' => ['Deutsch' => 'de', 'English' => 'en'],
            ])
            ->add('dateFormat', ChoiceType::class, [
                'label' => false,
                'choices' => ['31.07.2026' => 'd.m.Y', '2026-07-31' => 'Y-m-d', '07/31/2026' => 'm/d/Y'],
            ])
            ->add('timezone', ChoiceType::class, [
                'label' => false,
                'choices' => ['Europe/Berlin' => 'Europe/Berlin', 'Europe/Zurich' => 'Europe/Zurich', 'Europe/Vienna' => 'Europe/Vienna', 'UTC' => 'UTC'],
            ])
        ;
    }
}
