<?php
declare(strict_types=1);

namespace PpPhp\Core\Designer\DataGrid;

final class DesignerDataGridDefinition
{
    public function __construct(
        private readonly string $gridId,
        private readonly string $title,
        private readonly string $source = '',
        private readonly array $columns = [],
        private readonly array $rowActions = [],
        private readonly array $bulkActions = [],
        private readonly array $filters = [],
        private readonly DesignerDataGridToolbar $toolbar = new DesignerDataGridToolbar(),
        private readonly DesignerDataGridPagination $pagination = new DesignerDataGridPagination(),
        private readonly array $selection = [],
        private readonly array $meta = []
    ) {}

    public static function create(string $gridId, string $title = '', string $source = ''): self
    {
        return new self(
            $gridId,
            $title !== '' ? $title : self::humanize($gridId),
            $source,
            [],
            [
                DesignerDataGridAction::create('view')->toArray(),
                DesignerDataGridAction::create('edit')->toArray(),
                DesignerDataGridAction::create('delete')->toArray(),
                DesignerDataGridAction::create('duplicate')->toArray(),
            ],
            [
                DesignerDataGridAction::create('delete_selected', 'Delete Selected', 'bulk')->toArray(),
                DesignerDataGridAction::create('update_selected', 'Update Selected', 'bulk')->toArray(),
                DesignerDataGridAction::create('export_selected', 'Export Selected', 'bulk')->toArray(),
            ],
            [],
            DesignerDataGridToolbar::defaults(),
            DesignerDataGridPagination::defaults(),
            ['mode' => 'checkbox', 'selectAll' => true]
        );
    }

    public static function fromArray(array $data): self
    {
        return new self(
            (string) ($data['gridId'] ?? $data['id'] ?? 'grid'),
            (string) ($data['title'] ?? 'Grid'),
            (string) ($data['source'] ?? ''),
            (array) ($data['columns'] ?? []),
            (array) ($data['rowActions'] ?? $data['actions']['row'] ?? []),
            (array) ($data['bulkActions'] ?? $data['actions']['bulk'] ?? []),
            (array) ($data['filters'] ?? []),
            DesignerDataGridToolbar::fromArray((array) ($data['toolbar'] ?? [])),
            DesignerDataGridPagination::fromArray((array) ($data['pagination'] ?? [])),
            (array) ($data['selection'] ?? ['mode' => 'checkbox', 'selectAll' => true]),
            (array) ($data['meta'] ?? [])
        );
    }

    public function addColumn(DesignerDataGridColumn $column): self
    {
        return new self($this->gridId, $this->title, $this->source, array_merge($this->columns, [$column->toArray()]), $this->rowActions, $this->bulkActions, $this->filters, $this->toolbar, $this->pagination, $this->selection, $this->meta);
    }

    public function addFilter(DesignerDataGridFilter $filter): self
    {
        return new self($this->gridId, $this->title, $this->source, $this->columns, $this->rowActions, $this->bulkActions, array_merge($this->filters, [$filter->toArray()]), $this->toolbar, $this->pagination, $this->selection, $this->meta);
    }

    public function toComponent(): array
    {
        return [
            'id' => $this->gridId,
            'name' => $this->gridId,
            'type' => 'data_grid',
            'label' => $this->title,
            'props' => $this->toArray(),
            'children' => [],
            'events' => ['rowClick', 'actionClick', 'selectionChange', 'filterChange'],
            'meta' => ['designerRuntime' => 'data-grid', 'version' => '1.0.0'],
        ];
    }

    public function toArray(): array
    {
        return [
            'gridId' => $this->gridId,
            'id' => $this->gridId,
            'title' => $this->title,
            'source' => $this->source,
            'columns' => $this->columns,
            'rowActions' => $this->rowActions,
            'bulkActions' => $this->bulkActions,
            'filters' => $this->filters,
            'toolbar' => $this->toolbar->toArray(),
            'pagination' => $this->pagination->toArray(),
            'selection' => $this->selection,
            'meta' => $this->meta,
            'columnCount' => count($this->columns),
            'filterCount' => count($this->filters),
        ];
    }

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