<?php

namespace Solspace\Freeform\Fields\Implementations\Pro;

use craft\helpers\Html;
use Solspace\Freeform\Attributes\Field\Type;
use Solspace\Freeform\Attributes\Property\DefaultValue;
use Solspace\Freeform\Attributes\Property\Input;
use Solspace\Freeform\Attributes\Property\Limitation;
use Solspace\Freeform\Fields\AbstractField;
use Solspace\Freeform\Fields\Implementations\DropdownField;
use Solspace\Freeform\Fields\Implementations\HiddenField;
use Solspace\Freeform\Fields\Implementations\NumberField;
use Solspace\Freeform\Fields\Implementations\RadiosField;
use Solspace\Freeform\Fields\Implementations\TextareaField;
use Solspace\Freeform\Fields\Implementations\TextField;
use Solspace\Freeform\Fields\Interfaces\DefaultValueInterface;
use Solspace\Freeform\Fields\Interfaces\ExtraFieldInterface;
use Solspace\Freeform\Fields\Interfaces\TextInterface;
use Solspace\Freeform\Fields\Traits\DefaultTextValueTrait;

#[Type(
    name: 'Calculation',
    typeShorthand: 'calculation',
    iconPath: __DIR__.'/../Icons/calculation.svg',
    previewTemplatePath: __DIR__.'/../PreviewTemplates/calculation.ejs',
)]
class CalculationField extends AbstractField implements DefaultValueInterface, TextInterface, ExtraFieldInterface
{
    use DefaultTextValueTrait;

    public const INPUT_TYPE_REGULAR = 'regularTextInput';
    public const INPUT_TYPE_PLAIN = 'plainText';
    public const INPUT_TYPE_HIDDEN = 'hidden';

    private const DEFAULT_CALCULATIONS = '';

    protected string $instructions = '';

    #[Input\CalculationBox(
        label: 'Calculation Logic',
        availableFieldTypes: [
            TextField::class,
            NumberField::class,
            TextareaField::class,
            DropdownField::class,
            RadiosField::class,
            HiddenField::class,
            InvisibleField::class,
            OpinionScaleField::class,
            RatingField::class,
            RegexField::class,
        ],
    )]
    protected string $calculations = self::DEFAULT_CALCULATIONS;

    #[Limitation('props.calculation', 'decimalCount')]
    #[DefaultValue('props.calculation.decimalCount')]
    #[Input\Integer(
        instructions: 'The number of decimal places allowed.',
        placeholder: 'Leave blank for empty / no rounding',
        min: 0,
    )]
    protected ?int $decimalCount = null;

    #[Limitation('props.calculation', 'inputType')]
    #[DefaultValue('props.calculation.inputType')]
    #[Input\Select(
        options: [
            self::INPUT_TYPE_REGULAR => 'Regular Text Input',
            self::INPUT_TYPE_PLAIN => 'Plain Text',
            self::INPUT_TYPE_HIDDEN => 'Hidden',
        ],
    )]
    private string $inputType = self::INPUT_TYPE_REGULAR;

    public function getType(): string
    {
        return self::TYPE_CALCULATION;
    }

    public function getCalculations(): string
    {
        return $this->calculations;
    }

    public function getDecimalCount(): ?int
    {
        return $this->decimalCount ?? null;
    }

    public function getValue(): mixed
    {
        $value = parent::getValue();
        $value = str_replace(',', '.', $value);
        if (is_numeric($value)) {
            $value += 0;
        }

        return $value;
    }

    public function canRender(): bool
    {
        return self::INPUT_TYPE_HIDDEN !== $this->inputType;
    }

    public function getHtmlInputType(): string
    {
        return self::INPUT_TYPE_REGULAR === $this->inputType ? self::TYPE_TEXT : self::TYPE_HIDDEN;
    }

    public function getInputHtml(): string
    {
        $attributes = $this->getAttributes()
            ->getInput()
            ->clone()
            ->setIfEmpty('name', $this->getHandle())
            ->setIfEmpty('id', $this->getIdAttribute())
            ->setIfEmpty('type', $this->getHtmlInputType())
            ->setIfEmpty('value', $this->getValue())
            ->replace('data-calculations', $this->getCalculations())
            ->replace('data-decimal', $this->getDecimalCount())
            ->replace('readonly', true)
        ;

        $input = Html::tag(
            $attributes->getTag('input'),
            '',
            $attributes->toHtmlTagArray(['field' => $this])
        );

        if (self::INPUT_TYPE_PLAIN === $this->inputType) {
            $paragraph = Html::tag(
                'p',
                htmlentities($this->getValue(), \ENT_QUOTES | \ENT_SUBSTITUTE | \ENT_HTML401),
                ['class' => 'freeform-calculation-plain-field']
            );

            return Html::tag(
                'div',
                $input.$paragraph,
                ['class' => 'freeform-calculation-wrapper']
            );
        }

        return $input;
    }
}
