<?php
declare(strict_types=1);

namespace PpPhp\Core\Designer\DataGrid;

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

    public function create(string $gridId, string $title = '', string $source = ''): array
    {
        $grid = DesignerDataGridDefinition::create($gridId, $title, $source);
        $this->record('create', ['gridId' => $gridId]);
        return $grid->toComponent();
    }

    public function fromFields(string $gridId, array $fields, string $title = '', string $source = ''): array
    {
        $grid = DesignerDataGridDefinition::create($gridId, $title, $source);

        foreach ($fields as $field) {
            if (is_array($field)) {
                $grid = $grid->addColumn(DesignerDataGridColumn::fromArray($field));
                if (($field['filterable'] ?? true) !== false) {
                    $grid = $grid->addFilter(DesignerDataGridFilter::create((string) ($field['name'] ?? $field['field'] ?? 'field'), $this->filterType((string) ($field['type'] ?? 'text'))));
                }
            }
        }

        $this->record('fromFields', ['gridId' => $gridId, 'columns' => count($fields)]);
        return $grid->toComponent();
    }

    public function addColumn(array $gridComponent, array $column): array
    {
        $grid = DesignerDataGridDefinition::fromArray((array) ($gridComponent['props'] ?? $gridComponent));
        $grid = $grid->addColumn(DesignerDataGridColumn::fromArray($column));
        $this->record('addColumn', ['gridId' => $grid->toArray()['gridId'], 'column' => $column['name'] ?? '']);
        return $grid->toComponent();
    }

    public function addFilter(array $gridComponent, array $filter): array
    {
        $grid = DesignerDataGridDefinition::fromArray((array) ($gridComponent['props'] ?? $gridComponent));
        $grid = $grid->addFilter(DesignerDataGridFilter::fromArray($filter));
        $this->record('addFilter', ['gridId' => $grid->toArray()['gridId'], 'field' => $filter['field'] ?? '']);
        return $grid->toComponent();
    }

    public function pageFor(string $table, array $fields = []): array
    {
        $grid = $this->fromFields($table . '_grid', $fields, ucfirst($table), $table);

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

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

    public function render(array $gridComponent): string
    {
        return (new DesignerDataGridRenderer())->render($gridComponent);
    }

    public function validate(array $gridComponent): array
    {
        $props = (array) ($gridComponent['props'] ?? $gridComponent);
        $columns = (array) ($props['columns'] ?? []);
        $names = [];
        $issues = [];

        foreach ($columns as $column) {
            $name = (string) ($column['name'] ?? '');
            if ($name === '') {
                $issues[] = ['column' => '', 'message' => 'Column name is required'];
                continue;
            }
            if (in_array($name, $names, true)) {
                $issues[] = ['column' => $name, 'message' => 'Duplicate column name'];
            }
            $names[] = $name;
        }

        return [
            'ok' => $issues === [],
            'issues' => $issues,
            'columnCount' => count($columns),
            'filterCount' => count((array) ($props['filters'] ?? [])),
            'rowActions' => count((array) ($props['rowActions'] ?? [])),
            'bulkActions' => count((array) ($props['bulkActions'] ?? [])),
        ];
    }

    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')),
            'columnOperations' => count(array_filter($this->operations, static fn (array $op): bool => ($op['operation'] ?? '') === 'addColumn')),
            'filterOperations' => count(array_filter($this->operations, static fn (array $op): bool => ($op['operation'] ?? '') === 'addFilter')),
        ];
    }

    private function filterType(string $columnType): string
    {
        return match ($columnType) {
            'number', 'currency', 'percentage' => 'number',
            'date', 'datetime' => 'daterange',
            'boolean' => 'boolean',
            'badge', 'select' => 'select',
            default => 'text',
        };
    }

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