<?php
declare(strict_types=1);

namespace PpPhp\Core\Designer\Form;

final class DesignerFormField
{
    public function __construct(
        private readonly string $name,
        private readonly string $type = 'text',
        private readonly string $label = '',
        private readonly array $props = [],
        private readonly array $validation = [],
        private readonly array $layout = [],
        private readonly array $bindings = [],
        private readonly array $events = []
    ) {}

    public static function create(string $name, string $type = 'text', string $label = '', array $props = []): self
    {
        return new self(
            $name,
            $type,
            $label !== '' ? $label : self::humanize($name),
            array_replace(self::defaultProps($type), $props),
            self::defaultValidation($type),
            ['span' => 12, 'row' => null, 'column' => null],
            ['source' => $name],
            self::defaultEvents($type)
        );
    }

    public static function fromArray(array $data): self
    {
        return new self(
            (string) ($data['name'] ?? $data['field'] ?? 'field'),
            (string) ($data['type'] ?? 'text'),
            (string) ($data['label'] ?? self::humanize((string) ($data['name'] ?? 'field'))),
            (array) ($data['props'] ?? []),
            (array) ($data['validation'] ?? []),
            (array) ($data['layout'] ?? []),
            (array) ($data['bindings'] ?? []),
            (array) ($data['events'] ?? [])
        );
    }

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

    public function withLayout(array $layout): self
    {
        return new self($this->name, $this->type, $this->label, $this->props, $this->validation, array_replace($this->layout, $layout), $this->bindings, $this->events);
    }

    public function withValidation(array $validation): self
    {
        return new self($this->name, $this->type, $this->label, $this->props, array_replace($this->validation, $validation), $this->layout, $this->bindings, $this->events);
    }

    public function toArray(): array
    {
        return [
            'name' => $this->name,
            'type' => $this->type,
            'label' => $this->label,
            'props' => $this->props,
            'validation' => $this->validation,
            'layout' => $this->layout,
            'bindings' => $this->bindings,
            'events' => $this->events,
        ];
    }

    private static function defaultProps(string $type): array
    {
        return match ($type) {
            'textarea' => ['placeholder' => '', 'rows' => 4],
            'select', 'radio', 'multiselect' => ['options' => [], 'placeholder' => 'Select...'],
            'checkbox', 'switch' => ['checked' => false],
            'file', 'image' => ['accept' => '*/*', 'multiple' => false],
            'richtext' => ['toolbar' => 'basic'],
            default => ['placeholder' => ''],
        };
    }

    private static function defaultValidation(string $type): array
    {
        return match ($type) {
            'email' => ['email' => true],
            'number' => ['numeric' => true],
            'date', 'time', 'datetime' => ['date' => true],
            'file', 'image' => ['file' => true],
            default => [],
        };
    }

    private static function defaultEvents(string $type): array
    {
        return match ($type) {
            'text', 'email', 'number', 'textarea', 'select', 'multiselect' => ['change', 'focus', 'blur'],
            'checkbox', 'radio', 'switch' => ['change'],
            'file', 'image' => ['change', 'upload'],
            default => ['change'],
        };
    }

    private static function humanize(string $value): string
    {
        return ucwords(str_replace(['_', '-'], ' ', $value));
    }
}
