<?php
declare(strict_types=1);

namespace PpPhp\Core\Designer\Dashboard;

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

    public function createDashboard(string $id, string $title = '', string $layout = '4+4+4'): array
    {
        $dashboard = DesignerDashboardDefinition::create($id, $title, $layout);
        $this->record('createDashboard', ['id' => $id, 'layout' => $layout]);
        return $dashboard->toComponent();
    }

    public function addWidget(array $dashboardComponent, array $widget): array
    {
        $dashboard = DesignerDashboardDefinition::fromArray((array) ($dashboardComponent['props'] ?? $dashboardComponent));
        $dashboard = $dashboard->addWidget(DesignerDashboardWidget::fromArray($widget));
        $this->record('addWidget', ['dashboard' => $dashboard->toArray()['dashboardId'], 'widget' => $widget['id'] ?? '']);
        return $dashboard->toComponent();
    }

    public function moveWidget(array $dashboardComponent, string $widgetId, int $position): array
    {
        $dashboard = DesignerDashboardDefinition::fromArray((array) ($dashboardComponent['props'] ?? $dashboardComponent));
        $dashboard = $dashboard->moveWidget($widgetId, $position);
        $this->record('moveWidget', ['widget' => $widgetId, 'position' => $position]);
        return $dashboard->toComponent();
    }

    public function duplicateWidget(array $dashboardComponent, string $widgetId): array
    {
        $dashboard = DesignerDashboardDefinition::fromArray((array) ($dashboardComponent['props'] ?? $dashboardComponent));
        $dashboard = $dashboard->duplicateWidget($widgetId);
        $this->record('duplicateWidget', ['widget' => $widgetId]);
        return $dashboard->toComponent();
    }

    public function deleteWidget(array $dashboardComponent, string $widgetId): array
    {
        $dashboard = DesignerDashboardDefinition::fromArray((array) ($dashboardComponent['props'] ?? $dashboardComponent));
        $dashboard = $dashboard->deleteWidget($widgetId);
        $this->record('deleteWidget', ['widget' => $widgetId]);
        return $dashboard->toComponent();
    }

    public function template(string $name = 'admin'): array
    {
        $dashboard = DesignerDashboardDefinition::create($name . '_dashboard', ucfirst($name) . ' Dashboard', '3+3+3+3');

        $dashboard = match ($name) {
            'crm' => $dashboard
                ->addWidget(DesignerDashboardCard::stat('leads', 'Leads', '320', 'bi-person-plus', 3))
                ->addWidget(DesignerDashboardCard::stat('customers', 'Customers', '1,245', 'bi-people', 3))
                ->addWidget(DesignerDashboardChart::chart('pipeline_chart', 'Pipeline', 'bar', 6))
                ->addWidget(DesignerDashboardQuickAction::action('add_lead', 'Add Lead', 'leads_add', 'bi-plus', 3)),
            'helpdesk' => $dashboard
                ->addWidget(DesignerDashboardCard::stat('open_tickets', 'Open Tickets', '42', 'bi-ticket', 3))
                ->addWidget(DesignerDashboardCard::stat('closed_tickets', 'Closed Tickets', '180', 'bi-check-circle', 3))
                ->addWidget(DesignerDashboardCard::stat('sla', 'SLA', '98%', 'bi-clock', 3))
                ->addWidget(DesignerDashboardActivityFeed::feed('recent_activity', 'Recent Activity', 6)),
            default => $dashboard
                ->addWidget(DesignerDashboardCard::stat('total_customers', 'Customers', '1,245', 'bi-people', 3))
                ->addWidget(DesignerDashboardCard::stat('total_orders', 'Orders', '890', 'bi-bag', 3))
                ->addWidget(DesignerDashboardCard::stat('revenue', 'Revenue', '$42,500', 'bi-currency-dollar', 3))
                ->addWidget(DesignerDashboardCard::stat('active_users', 'Users', '215', 'bi-person-check', 3))
                ->addWidget(DesignerDashboardChart::chart('sales_chart', 'Sales Overview', 'bar', 6))
                ->addWidget(DesignerDashboardActivityFeed::feed('recent_activity', 'Recent Activity', 6)),
        };

        $this->record('template', ['name' => $name]);
        return $dashboard->toComponent();
    }

    public function pageFor(string $name = 'admin'): array
    {
        $dashboard = DesignerDashboardDefinition::fromArray($this->template($name)['props']);
        $this->record('pageFor', ['name' => $name]);
        return $dashboard->toPage();
    }

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

    public function validate(array $dashboardComponent): array
    {
        $props = (array) ($dashboardComponent['props'] ?? $dashboardComponent);
        $widgets = (array) ($props['widgets'] ?? []);
        $ids = [];
        $issues = [];

        foreach ($widgets as $widget) {
            $id = (string) ($widget['id'] ?? '');
            if ($id === '') {
                $issues[] = ['widget' => '', 'message' => 'Widget ID is required'];
            } elseif (in_array($id, $ids, true)) {
                $issues[] = ['widget' => $id, 'message' => 'Duplicate widget ID'];
            } else {
                $ids[] = $id;
            }

            $span = (int) ($widget['span'] ?? $widget['layout']['span'] ?? 4);
            if (!in_array($span, [3, 4, 6, 8, 9, 12], true)) {
                $issues[] = ['widget' => $id, 'message' => 'Invalid widget span'];
            }
        }

        return [
            'ok' => $issues === [],
            'issues' => $issues,
            'widgets' => count($widgets),
            'cards' => count(array_filter($widgets, static fn (array $w): bool => ($w['type'] ?? '') === 'stat_card')),
            'charts' => count(array_filter($widgets, static fn (array $w): bool => ($w['type'] ?? '') === 'chart')),
            'quickActions' => count(array_filter($widgets, static fn (array $w): bool => ($w['type'] ?? '') === 'quick_action')),
            'activityFeeds' => count(array_filter($widgets, static fn (array $w): bool => ($w['type'] ?? '') === 'activity_feed')),
        ];
    }

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

    public function stats(): array
    {
        return [
            'operations' => count($this->operations),
            'templates' => count(array_filter($this->operations, static fn (array $op): bool => ($op['operation'] ?? '') === 'template')),
            'widgetOperations' => count(array_filter($this->operations, static fn (array $op): bool => in_array(($op['operation'] ?? ''), ['addWidget', 'moveWidget', 'duplicateWidget', 'deleteWidget'], true))),
        ];
    }

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