<?php

namespace PHPNative\Ui\Widget;

use PHPNative\Framework\TextRenderer;

class VirtualTable extends Container
{
    private Table $innerTable;
    private array $rows = [];
    private array $columns = [];
    private int $pageSize = 200;
    private int $currentPage = 0;
    private int $totalPages = 1;
    private $onRowSelect = null;
    private Label $pageInfoLabel;
    private Button $prevButton;
    private Button $nextButton;
    private bool $prevEnabled = false;
    private bool $nextEnabled = false;

    public function __construct(string $style = '')
    {
        parent::__construct('flex flex-col w-full' . $style);

        $this->innerTable = new Table(' flex-1');
        $this->addComponent($this->innerTable);

        $pagination = new Container('flex flex-row items-center justify-end gap-2 mt-1');

        $this->pageInfoLabel = new Label('', 'text-xs text-gray-600');

        $this->prevButton = new Button('←', 'px-2 py-1 text-xs bg-gray-200 rounded hover:bg-gray-300');
        $this->nextButton = new Button('→', 'px-2 py-1 text-xs bg-gray-200 rounded hover:bg-gray-300');

        $virtualTable = $this;
        $this->prevButton->setOnClick(function () use ($virtualTable) {
            $virtualTable->goToPreviousPage();
        });
        $this->nextButton->setOnClick(function () use ($virtualTable) {
            $virtualTable->goToNextPage();
        });

        $pagination->addComponent($this->pageInfoLabel);
        $pagination->addComponent($this->prevButton);
        $pagination->addComponent($this->nextButton);

        $this->addComponent($pagination);
    }

    public function layout(null|TextRenderer $textRenderer = null): void
    {
        parent::layout($textRenderer);
        $this->updatePaginationLabel();
    }

    public function setColumns(array $columns): void
    {
        $this->columns = $columns;
        $this->innerTable->setColumns($columns);
    }

    public function setData(array $data): void
    {
        $this->rows = array_values($data);
        $this->currentPage = 0;
        $this->recalculateTotalPages();
        $this->updatePageData();
    }

    public function setOnRowSelect(callable $callback): void
    {
        $this->onRowSelect = $callback;

        $virtualTable = $this;
        $this->innerTable->setOnRowSelect(function ($index, $row) use ($virtualTable) {
            if ($virtualTable->onRowSelect !== null) {
                $globalIndex = ($virtualTable->currentPage * $virtualTable->pageSize) + $index;
                ($virtualTable->onRowSelect)($globalIndex, $row);
            }
        });
    }

    public function getSelectedRow(): null|array
    {
        $selected = $this->innerTable->getSelectedRow();
        if ($selected === null) {
            return null;
        }

        return $selected;
    }

    private function recalculateTotalPages(): void
    {
        $rowCount = count($this->rows);
        $this->totalPages = max(1, (int) ceil($rowCount / $this->pageSize));
        if ($this->currentPage >= $this->totalPages) {
            $this->currentPage = $this->totalPages - 1;
        }
    }

    private function updatePageData(): void
    {
        $offset = $this->currentPage * $this->pageSize;
        $pageRows = array_slice($this->rows, $offset, $this->pageSize);
        $this->innerTable->setData($pageRows, false);
        $this->updatePaginationLabel();
    }

    private function updatePaginationLabel(): void
    {
        $totalRows = count($this->rows);
        if ($totalRows === 0) {
            $this->pageInfoLabel->setText('Keine Einträge');
            $this->prevEnabled = false;
            $this->nextEnabled = false;
            $this->prevButton->setStyle('px-2 py-1 text-xs bg-gray-100 rounded text-gray-400');
            $this->nextButton->setStyle('px-2 py-1 text-xs bg-gray-100 rounded text-gray-400');
            return;
        }

        $start = ($this->currentPage * $this->pageSize) + 1;
        $end = min($totalRows, ($this->currentPage + 1) * $this->pageSize);

        $this->pageInfoLabel->setText(sprintf('Zeige %d–%d von %d', $start, $end, $totalRows));

        $this->prevEnabled = $this->currentPage > 0;
        $this->nextEnabled = ($this->currentPage + 1) < $this->totalPages;

        $this->prevButton->setStyle(
            $this->prevEnabled
                ? 'px-2 py-1 text-xs bg-gray-200 rounded hover:bg-gray-300'
                : 'px-2 py-1 text-xs bg-gray-100 rounded text-gray-400'
        );
        $this->nextButton->setStyle(
            $this->nextEnabled
                ? 'px-2 py-1 text-xs bg-gray-200 rounded hover:bg-gray-300'
                : 'px-2 py-1 text-xs bg-gray-100 rounded text-gray-400'
        );
    }

    private function goToPreviousPage(): void
    {
        if ($this->currentPage <= 0 || !$this->prevEnabled) {
            return;
        }

        $this->currentPage--;
        $this->updatePageData();
        $this->markDirty(true);
    }

    private function goToNextPage(): void
    {
        if (($this->currentPage + 1) >= $this->totalPages || !$this->nextEnabled) {
            return;
        }

        $this->currentPage++;
        $this->updatePageData();
        $this->markDirty(true);
    }
}
