<?php

declare(strict_types=1);

namespace App\Framework\View\Table;

final readonly class TableRow
{
    /**
     * @param TableCell[] $cells
     */
    public function __construct(
        public array $cells,
        public ?string $cssClass = null,
        public ?array $attributes = null
    ) {
    }

    public function render(): string
    {
        $attributesString = $this->buildAttributesString();
        $classString = $this->cssClass ? " class=\"{$this->cssClass}\"" : '';

        $cellsHtml = array_map(fn (TableCell $cell) => $cell->render(), $this->cells);

        return "<tr{$classString}{$attributesString}>" . implode('', $cellsHtml) . "</tr>";
    }

    private function buildAttributesString(): string
    {
        if (! $this->attributes) {
            return '';
        }

        $parts = [];
        foreach ($this->attributes as $key => $value) {
            $parts[] = $key . '="' . htmlspecialchars((string) $value, ENT_QUOTES) . '"';
        }

        return $parts ? ' ' . implode(' ', $parts) : '';
    }

    /**
     * @param TableColumn[] $columns
     */
    public static function fromData(array $data, array $columns, ?string $cssClass = null): self
    {
        $cells = [];

        foreach ($columns as $column) {
            $value = $data[$column->key] ?? null;
            $cells[] = $column->createCell($value);
        }

        return new self($cells, $cssClass);
    }

    /**
     * @param mixed[] $values
     */
    public static function fromValues(array $values, ?string $cssClass = null): self
    {
        $cells = array_map(fn ($value) => TableCell::text($value), $values);

        return new self($cells, $cssClass);
    }

    public static function withCells(TableCell ...$cells): self
    {
        return new self($cells);
    }
}
