<?php
declare(strict_types=1);

namespace PpPhp\Core\Designer\Form;

final class DesignerFormRuntime
{
    private array $operations = [];

    public function create(string $formId, string $mode = 'add', string $title = '', string $layout = 'one_column'): array
    {
        $form = DesignerFormDefinition::create($formId, $mode, $title, $layout);
        $this->record('create', ['formId' => $formId, 'mode' => $mode, 'layout' => $layout]);

        return $form->toComponent();
    }

    public function fromFields(string $formId, array $fields, string $mode = 'add', string $layout = 'two_column'): array
    {
        $form = DesignerFormDefinition::create($formId, $mode, ucfirst($mode) . ' ' . str_replace('_', ' ', $formId), $layout);

        foreach ($fields as $field) {
            if (is_array($field)) {
                $form = $form->addField(DesignerFormField::fromArray($field), (string) ($field['section'] ?? 'general'));
            }
        }

        $this->record('fromFields', ['formId' => $formId, 'fields' => count($fields), 'mode' => $mode]);
        return $form->toComponent();
    }

    public function addField(array $formComponent, array $field, string $sectionId = 'general'): array
    {
        $form = DesignerFormDefinition::fromArray((array) ($formComponent['props'] ?? $formComponent));
        $form = $form->addField(DesignerFormField::fromArray($field), $sectionId);

        $updated = $form->toComponent();
        $this->record('addField', ['formId' => $form->formId(), 'field' => $field['name'] ?? '', 'section' => $sectionId]);

        return $updated;
    }

    public function removeField(array $formComponent, string $fieldName): array
    {
        $form = DesignerFormDefinition::fromArray((array) ($formComponent['props'] ?? $formComponent));
        $form = $form->removeField($fieldName);

        $updated = $form->toComponent();
        $this->record('removeField', ['formId' => $form->formId(), 'field' => $fieldName]);

        return $updated;
    }

    public function pageFor(string $table, string $mode = 'add', array $fields = []): array
    {
        $form = $this->fromFields($table . '_' . $mode . '_form', $fields, $mode, 'two_column');

        $page = [
            'version' => '1.0',
            'pageId' => $table . '_' . $mode,
            'table' => $table,
            'pageType' => $mode,
            'title' => ucfirst($mode) . ' ' . ucfirst($table),
            'components' => [
                [
                    'id' => 'page_header',
                    'type' => 'heading',
                    'label' => ucfirst($mode) . ' ' . ucfirst($table),
                    'props' => ['text' => ucfirst($mode) . ' ' . ucfirst($table), 'level' => 2],
                    'children' => [],
                ],
                $form,
            ],
            'meta' => [
                'designerRuntime' => 'form-page',
                'generatedAt' => date('c'),
            ],
        ];

        $this->record('pageFor', ['table' => $table, 'mode' => $mode]);
        return $page;
    }

    public function validate(array $formComponent): array
    {
        $form = DesignerFormDefinition::fromArray((array) ($formComponent['props'] ?? $formComponent));
        $fields = $form->fields();
        $names = [];
        $issues = [];

        foreach ($fields as $field) {
            $row = $field->toArray();
            if (($row['name'] ?? '') === '') {
                $issues[] = ['field' => '', 'message' => 'Field name is required'];
                continue;
            }
            if (in_array($row['name'], $names, true)) {
                $issues[] = ['field' => $row['name'], 'message' => 'Duplicate field name'];
            }
            $names[] = $row['name'];
        }

        return [
            'ok' => $issues === [],
            'issues' => $issues,
            'fieldCount' => count($fields),
            'mode' => $form->mode(),
        ];
    }

    public function operations(): array { return $this->operations; }

    public function stats(): array
    {
        return [
            'operations' => count($this->operations),
            'created' => count(array_filter($this->operations, static fn (array $op): bool => ($op['operation'] ?? '') === 'create')),
            'fromFields' => count(array_filter($this->operations, static fn (array $op): bool => ($op['operation'] ?? '') === 'fromFields')),
            'fieldOperations' => count(array_filter($this->operations, static fn (array $op): bool => in_array(($op['operation'] ?? ''), ['addField', 'removeField'], true))),
        ];
    }

    private function record(string $operation, array $payload): void
    {
        $this->operations[] = [
            'operation' => $operation,
            'payload' => $payload,
            'createdAt' => date('c'),
        ];
    }
}
