<?php
namespace Incoviba\Service\Contabilidad\Informe\Tesoreria\Input\Excel;

use PhpOffice\PhpSpreadsheet;
use Incoviba\Common\Ideal;

abstract class Sheet extends Ideal\Service
{
    protected function getCalculatedValue(PhpSpreadsheet\Worksheet\Worksheet $sheet, int|string $columnIndex, ?int $rowIndex = null, mixed $default = 0): mixed
    {
        try {
            if (is_string($columnIndex)) {
                if ($rowIndex === null) {
                    return $sheet->getCell($columnIndex)->getCalculatedValue() ?? $default;
                }
                return $sheet->getCell("{$columnIndex}{$rowIndex}")->getCalculatedValue() ?? $default;
            }
            return $sheet->getCell([$columnIndex, $rowIndex])->getCalculatedValue() ?? $default;
        } catch (PhpSpreadsheet\Calculation\Exception $e) {
            $this->logger->error($e->getMessage());
            return $default;
        }
    }
    protected function getTableTitles(PhpSpreadsheet\Worksheet\Worksheet $sheet, int $titleRow, int $columnOffset, int $maxColumns, string $duplicateSuffix = '', array $cutoffCharacters = []): array
    {
        $titles = [];
        $columnIndex = $columnOffset;
        while ($columnIndex < $maxColumns or $sheet->getCell([$columnIndex, $titleRow])->getValue() !== null) {
            if ($sheet->getCell([$columnIndex, $titleRow])->getValue() !== null) {
                $title = $this->transformTitle($sheet->getCell([$columnIndex, $titleRow])->getValue(), $cutoffCharacters);
                if (in_array($title, $titles)) {
                    $title .= $duplicateSuffix;
                }
                $titles []= $title;
            }
            $columnIndex ++;
        }
        return $titles;
    }
    protected function getRow(PhpSpreadsheet\Worksheet\Worksheet $sheet, array $titles, int $titleRow, int $rowIndex, int $columnOffset): object
    {
        $row = [];
        $columnIndex = $columnOffset;
        $titleIndex = 0;
        $currentTitle = $this->transformTitle($sheet->getCell([$columnIndex, $titleRow])->getValue());
        while ($columnIndex < count($titles) * 3 and $currentTitle !== last($titles)) {
            if ($sheet->getCell([$columnIndex, $titleRow])->getValue() === null) {
                $columnIndex ++;
                continue;
            }
            if (str_contains($titles[$titleIndex], 'fecha')) {
                $row[$titles[$titleIndex ++]] = PhpSpreadsheet\Shared\Date::excelToDateTimeObject($this->getCalculatedValue($sheet, $columnIndex ++, $rowIndex));
                continue;
            }
            $row[$titles[$titleIndex ++]] = $this->getCalculatedValue($sheet, $columnIndex ++, $rowIndex);
        }

        return (object) $row;
    }
    protected function transformTitle(string $title, array $cutoffCharacters = []): string
    {
        $title = str_replace(' ', '', ucwords(mb_strtolower($title)));
        $title = strtolower(substr($title, 0, 1)) . substr($title, 1);
        foreach ($cutoffCharacters as $cutoffCharacter) {
            if (str_contains($title, $cutoffCharacter)) {
                $title = substr($title, 0, strpos($title, $cutoffCharacter));
            }
        }
        return $title;
    }

    abstract public function load(PhpSpreadsheet\Spreadsheet $excel): array;
}
