<?php

namespace Plainwork\Ui\Component;

use Plainwork\Ui\Component\TableCell;
use Plainwork\Ui\Component\HtmlElement;

final class Table extends AbstractTag
{
    private $cells = [];
    private $headRows = [];
    private $footRows = [];
    private bool $autoWidth = false;
    private bool $isResponsive = true;
    private $caption;
    private $captionAttr = [];
    private $rows = [];

    public function withHeadCell(string $rowId, string $columnId): TableCell
    {
        if (!isset($this->cells[$rowId][$columnId])) {
            $e = new TableCell();
            $e->setHead(true);
            $this->cells[$rowId][$columnId] = $e;
        }

        if (!isset($this->headRows[$rowId])) {
            $this->headRows[$rowId] = $rowId;
        }

        return $this->cells[$rowId][$columnId];
    }

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

    public function withFootCell(string $rowId, string $columnId): TableCell
    {
        if (!isset($this->cells[$rowId][$columnId])) {
            $this->cells[$rowId][$columnId] = (new TableCell())->setHead(true);
        }
        if (!isset($this->footRows[$rowId])) {
            $this->footRows[$rowId] = $rowId;
        }

        return $this->cells[$rowId][$columnId];
    }

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

    public function removeRow(string $rowId): self
    {
        unset($this->cells[$rowId]);
        unset($this->footRows[$rowId]);
        unset($this->headRows[$rowId]);

        return $this;
    }

    public function getRows()
    {
        return array_diff(array_keys($this->cells), $this->getHeadRows(), $this->getFootRows());
    }

    public function getColumns(): array
    {
        $ret = [];

        foreach ($this->cells as $rowId => $columns) {
            foreach ($columns as $columnId => $col) {
                if (!isset($ret[$columnId])) {
                    $ret[$columnId] = $columnId;
                }
            }
        }

        return $ret;
    }

    public function getCell(string $rowId, string $columnId)
    {
        // if (!isset($this->rows[$rowId])) {
            // throw new \InvalidArgumentException("'$rowId' table row is not registered");
        // }
        // if (!isset($this->columns[$columnId])) {
            // throw new \InvalidArgumentException("'$columnId' table column is not registered");
        // }

        return $this->cells[$rowId][$columnId] ?? null;
    }

    public function getRow(string $rowId): HtmlElement
    {
        if (!isset($this->rows[$rowId])) {
            $this->rows[$rowId] = new HtmlElement('tr');
        }

        return $this->rows[$rowId];
    }

    public function withRow(string $rowId): HtmlElement
    {
        return $this->getRow($rowId);
    }

    public function withCell(string $rowId, string $columnId): TableCell
    {
        if (!isset($this->cells[$rowId][$columnId])) {
            $e = new TableCell();
            $this->cells[$rowId][$columnId] = $e;
        }

        return $this->getCell($rowId, $columnId);
    }

    public function setAutoWidth(bool $on = true): self
    {
        $this->autoWidth = $on;

        return $this;
    }

    public function isAutoWidth(): bool
    {
        return $this->autoWidth;
    }

    public function setResponsive(bool $on = true): self
    {
        $this->isResponsive = $on;

        return $this;
    }

    public function isResponsive(): bool
    {
        return $this->isResponsive;
    }

    public function getCaption()
    {
        return $this->caption;
    }

    public function setCaption($caption): self
    {
        $this->caption = $caption;

        return $this;
    }

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

    public function withCaptionAttr(string $attrName, $v): self
    {
        if (in_array($attrName, ['style'])) {
            $this->captionAttr[$attrName] ??= [];
            $this->captionAttr[$attrName] = array_merge($this->captionAttr[$attrName], $v);
        } else {
            $this->captionAttr[$attrName] = $v;
        }

        return $this;
    }
}
