<?php

declare(strict_types=1);

namespace App\Framework\Admin\FormFields\Fields;

use App\Framework\Admin\FormFields\Components\FieldWrapper;
use App\Framework\Admin\FormFields\FormField;
use App\Framework\Admin\FormFields\ValueObjects\FieldAttributes;
use App\Framework\Admin\FormFields\ValueObjects\FieldMetadata;
use App\Framework\View\FormBuilder;
use App\Framework\View\ValueObjects\FormElement;
use DateTimeInterface;

/**
 * DateTime Input Field
 *
 * DateTime input field with formatting using composition
 */
final readonly class DateTimeField implements FormField
{
    public function __construct(
        private FieldMetadata $metadata,
        private FieldAttributes $attributes,
        private FieldWrapper $wrapper,
        private mixed $value = null,
        private string $type = 'datetime-local'
    ) {
    }

    public static function create(
        string $name,
        string $label,
        mixed $value = null,
        bool $required = false,
        ?string $help = null,
        string $type = 'datetime-local'
    ): self {
        return new self(
            metadata: new FieldMetadata($name, $label, $help),
            attributes: new FieldAttributes(
                name: $name,
                id: $name,
                required: $required
            ),
            wrapper: new FieldWrapper(),
            value: $value,
            type: $type
        );
    }

    public function render(FormBuilder $form): FormBuilder
    {
        $attrs = $this->attributes->withAdditional(['type' => $this->type]);
        $attrArray = $attrs->toArray();

        if ($this->value !== null) {
            $attrArray['value'] = $this->formatValue($this->value);
        }

        $input = FormElement::create('input', $attrArray);
        $wrapped = $this->wrapper->wrap($input, $this->metadata);

        return $form->addElement($wrapped);
    }

    public function getName(): string
    {
        return $this->metadata->name;
    }

    public function getValue(): mixed
    {
        return $this->value;
    }

    public function getLabel(): string
    {
        return $this->metadata->label;
    }

    private function formatValue(mixed $value): string
    {
        if ($value instanceof DateTimeInterface) {
            return $value->format($this->getFormatForType());
        }

        if (is_string($value) && strtotime($value) !== false) {
            return date($this->getFormatForType(), strtotime($value));
        }

        return (string) $value;
    }

    private function getFormatForType(): string
    {
        return match ($this->type) {
            'date' => 'Y-m-d',
            'time' => 'H:i',
            'datetime-local' => 'Y-m-d\TH:i',
            'month' => 'Y-m',
            'week' => 'Y-\WW',
            default => 'Y-m-d\TH:i'
        };
    }
}
