<?php
declare(strict_types=1);

namespace Autogedal\EanTools\Model\Spreadsheet;

use Generator;
use Magento\Framework\Exception\LocalizedException;
use OpenSpout\Common\Entity\Row;
use OpenSpout\Reader\XLSX\Options;
use OpenSpout\Reader\XLSX\Reader;
use Throwable;

class XlsxRowReader implements RowReaderInterface
{
    public function __construct(
        private readonly TempFolder $tempFolder,
        private readonly XlsxCellValueConverter $cellValueConverter
    ) {
    }

    public function read(string $path): Generator
    {
        $reader = new Reader($this->buildOptions());

        try {
            $reader->open($path);
        } catch (Throwable $e) {
            throw new LocalizedException(
                __('The uploaded XLSX file could not be read: %1', $e->getMessage())
            );
        }

        try {
            foreach ($reader->getSheetIterator() as $sheet) {
                foreach ($sheet->getRowIterator() as $line => $row) {
                    $cells = $this->decodeRow($row);

                    if ($cells === []) {
                        continue;
                    }

                    yield $line => $cells;
                }

                break;
            }
        } finally {
            $reader->close();
        }
    }

    private function buildOptions(): Options
    {
        $options = new Options();
        $options->SHOULD_PRESERVE_EMPTY_ROWS = true;
        $options->SHOULD_FORMAT_DATES = false;
        $options->setTempFolder($this->tempFolder->getPath());

        return $options;
    }

    private function decodeRow(Row $row): array
    {
        $cells = [];
        $hasValue = false;

        foreach ($row->getCells() as $index => $cell) {
            $value = $this->cellValueConverter->convert($cell);
            if ($value !== '') {
                $hasValue = true;
            }
            $cells[(int)$index] = $value;
        }

        return $hasValue ? $cells : [];
    }
}
