<?php

declare(strict_types=1);

namespace MauticPlugin\DealFlowBundle\Form\Type;

use Mautic\LeadBundle\Form\Type\CompanyListType;
use Mautic\LeadBundle\Form\Type\HtmlType;
use MauticPlugin\DealFlowBundle\Entity\Deal;
use MauticPlugin\DealFlowBundle\Entity\DealStage;
use MauticPlugin\DealFlowBundle\Entity\Pipeline;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

final class DealType extends AbstractType
{
    /**
     * @return array<string, int>
     */
    private static function buildConfidenceChoices(): array
    {
        $choices = [];

        foreach (range(10, 100, 10) as $value) {
            $choices[sprintf('%d%%', $value)] = $value;
        }

        return $choices;
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('title', TextType::class, [
                'label' => 'Deal title',
                'attr' => [
                    'class' => 'form-control',
                    'autofocus' => true,
                    'placeholder' => 'Acme expansion opportunity',
                ],
            ])
            ->add('pipeline', EntityType::class, [
                'label' => 'Pipeline',
                'class' => Pipeline::class,
                'choices' => $options['pipeline_choices'],
                'choice_label' => 'name',
                'attr' => [
                    'data-dealflow-pipeline-select' => 'true',
                ],
            ])
            ->add('stage', EntityType::class, [
                'label' => 'Stage',
                'class' => DealStage::class,
                'choices' => $options['stage_choices'],
                'choice_label' => 'name',
                'group_by' => static function (DealStage $stage): string {
                    return $stage->getPipeline()?->getName() ?? 'Pipeline';
                },
                'attr' => [
                    'data-dealflow-stage-select' => 'true',
                ],
            ])
            ->add('amount', NumberType::class, [
                'label' => 'Amount',
                'required' => false,
                'scale' => 2,
                'attr' => [
                    'class' => 'form-control',
                    'step' => '0.01',
                    'placeholder' => '0.00',
                ],
            ])
            ->add('currency', ChoiceType::class, [
                'label' => 'Currency',
                'required' => false,
                'choices' => $options['currency_choices'],
            ])
            ->add('confidence', ChoiceType::class, [
                'label' => 'Confidence',
                'required' => false,
                'choices' => self::buildConfidenceChoices(),
                'placeholder' => 'Select confidence',
            ])
            ->add('sourceSelection', ChoiceType::class, [
                'label' => 'Source',
                'mapped' => false,
                'required' => false,
                'choices' => $options['source_choices'],
                'placeholder' => 'Select a source',
                'data' => $options['current_source_selection'],
                'attr' => [
                    'data-dealflow-source-select' => 'true',
                ],
            ])
            ->add('sourceNew', TextType::class, [
                'label' => 'Add source',
                'mapped' => false,
                'required' => false,
                'data' => $options['current_source_new'],
                'attr' => [
                    'class' => 'form-control',
                    'placeholder' => 'Partner referral',
                ],
            ])
            ->add('expectedCloseDate', DateType::class, [
                'label' => 'Expected close date',
                'required' => false,
                'widget' => 'single_text',
                'attr' => [
                    'class' => 'form-control',
                ],
            ])
            ->add('companyId', CompanyListType::class, [
                'label' => 'Company',
                'required' => false,
                'multiple' => false,
                'label_attr' => ['class' => 'control-label'],
            ])
            ->add('ownerId', ChoiceType::class, [
                'label' => 'Owner',
                'required' => false,
                'choices' => $options['owner_choices'],
                'placeholder' => 'No owner assigned',
            ])
            ->add('description', HtmlType::class, [
                'label' => 'Description',
                'required' => false,
                'attr' => [
                    'class' => 'editor editor-basic',
                    'rows' => 10,
                    'placeholder' => 'Capture the deal summary, customer need, and next step.',
                ],
            ]);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'pipeline_choices' => [],
            'data_class' => Deal::class,
            'allow_extra_fields' => true,
            'stage_choices' => [],
            'owner_choices' => [],
            'source_choices' => [],
            'currency_choices' => [],
            'current_source_selection' => null,
            'current_source_new' => null,
        ]);

        $resolver->setAllowedTypes('pipeline_choices', 'array');
        $resolver->setAllowedTypes('stage_choices', 'array');
        $resolver->setAllowedTypes('owner_choices', 'array');
        $resolver->setAllowedTypes('source_choices', 'array');
        $resolver->setAllowedTypes('currency_choices', 'array');
        $resolver->setAllowedTypes('current_source_selection', ['null', 'string']);
        $resolver->setAllowedTypes('current_source_new', ['null', 'string']);
    }
}
