<?php

declare(strict_types=1);

namespace App\Framework\View\Table\Generators;

use App\Framework\View\Table\CellFormatter;
use App\Framework\View\Table\Table;
use App\Framework\View\Table\TableColumn;
use App\Framework\View\Table\TableGenerator;
use App\Framework\View\Table\TableOptions;
use App\Framework\View\Table\TableRow;

final readonly class HealthCheckTableGenerator implements TableGenerator
{
    public function generate(object|array $data, ?TableOptions $options = null): Table
    {
        if (! is_array($data)) {
            throw new \InvalidArgumentException('HealthCheckTableGenerator expects array data');
        }

        $columns = [
            new TableColumn(
                key: 'componentName',
                header: 'Component',
                cssClass: 'health-component',
                formatter: $this->createComponentFormatter()
            ),
            new TableColumn(
                key: 'statusText',
                header: 'Status',
                cssClass: 'health-status',
                formatter: $this->createStatusFormatter()
            ),
            TableColumn::text('message', 'Message', 'health-message'),
            new TableColumn(
                key: 'responseTime',
                header: 'Response Time',
                cssClass: 'health-response-time',
                formatter: $this->createResponseTimeFormatter()
            ),
        ];

        $rows = [];
        foreach ($data as $check) {
            // Extract status class from the check data
            $statusClass = is_array($check) ? ($check['statusClass'] ?? 'unknown') : ($check->statusClass ?? 'unknown');

            $rows[] = TableRow::fromData($check, $columns, "health-check health-check--{$statusClass}");
        }

        $tableOptions = $options ?? new TableOptions(
            striped: true,
            bordered: true,
            hover: true,
            responsive: true,
            emptyMessage: 'No health checks available'
        );

        return new Table(
            columns: $columns,
            rows: $rows,
            cssClass: 'admin-table health-check-table',
            options: $tableOptions,
            id: 'healthCheckTable'
        );
    }

    public function supports(object|array $data): bool
    {
        if (! is_array($data) || empty($data)) {
            return false;
        }

        $firstItem = reset($data);
        if (! is_array($firstItem) && ! is_object($firstItem)) {
            return false;
        }

        // Check if it has health check structure
        if (is_array($firstItem)) {
            return isset($firstItem['componentName']) && isset($firstItem['statusText']);
        }

        // Check if object has health check properties
        return property_exists($firstItem, 'componentName') && property_exists($firstItem, 'statusText');
    }

    private function createComponentFormatter(): CellFormatter
    {
        return new class () implements CellFormatter {
            public function format(mixed $value): string
            {
                if ($value === null || $value === '') {
                    return '';
                }

                return '<strong>' . htmlspecialchars((string) $value, ENT_QUOTES) . '</strong>';
            }
        };
    }

    private function createStatusFormatter(): CellFormatter
    {
        return new class () implements CellFormatter {
            public function format(mixed $value): string
            {
                if ($value === null || $value === '') {
                    return '';
                }

                $status = strtolower((string) $value);
                $statusClass = match ($status) {
                    'healthy', 'ok', 'success' => 'success',
                    'warning', 'degraded' => 'warning',
                    'error', 'failed', 'unhealthy' => 'error',
                    default => 'unknown'
                };

                $icon = match ($statusClass) {
                    'success' => '✅',
                    'warning' => '⚠️',
                    'error' => '❌',
                    default => '❓'
                };

                return sprintf(
                    '<span class="admin-table__status admin-table__status--%s">%s %s</span>',
                    $statusClass,
                    $icon,
                    htmlspecialchars(ucfirst((string) $value), ENT_QUOTES)
                );
            }
        };
    }

    private function createResponseTimeFormatter(): CellFormatter
    {
        return new class () implements CellFormatter {
            public function format(mixed $value): string
            {
                if ($value === null || $value === '') {
                    return '-';
                }

                $stringValue = (string) $value;

                // If already formatted with unit (e.g., "12ms"), return as is
                if (preg_match('/^\d+(\.\d+)?\s?(ms|s)$/i', $stringValue)) {
                    return htmlspecialchars($stringValue, ENT_QUOTES);
                }

                // If numeric, format as milliseconds
                if (is_numeric($value)) {
                    $ms = (float) $value;
                    if ($ms < 1000) {
                        return sprintf('%.1fms', $ms);
                    } else {
                        return sprintf('%.2fs', $ms / 1000);
                    }
                }

                return htmlspecialchars($stringValue, ENT_QUOTES);
            }
        };
    }
}
