<?php
namespace Incoviba\Service\Cartola;

use DateTimeImmutable;
use Psr\Http\Message\UploadedFileInterface;
use PhpOffice\PhpSpreadsheet;
use Incoviba\Common\Ideal\Cartola\Banco;

class Santander extends Banco
{
    protected function columnMap(): array
    {
        // MONTO	DESCRIPCIÓN MOVIMIENTO		FECHA	N° DOCUMENTO	SUCURSAL		CARGO/ABONO
        return [
            'cargo' => 'cargo',
            'abono' => 'abono',
            'DESCRIPCIÓN MOVIMIENTO' => 'glosa',
            'FECHA' => 'fecha',
            'N° DOCUMENTO' => 'documento',
            'SALDO' => 'saldo',
            'Fecha' => 'fecha',
            'Cargo ($)' => 'cargo',
            'Abono ($)' => 'abono',
            'Descripcin' => 'glosa',
            'Saldo Diario' => 'saldo'
        ];
    }
    protected function parseFile(UploadedFileInterface $uploadedFile): array
    {
        $filename = '/tmp/cartola.xlsx';
        $uploadedFile->moveTo($filename);

        $reader = PhpSpreadsheet\IOFactory::createReader('Xlsx');
        try {
            $xlsx = $reader->load($filename);
        } catch (PhpSpreadsheet\Reader\Exception) {
            return $this->parseHtml($filename);
        }
        $sheet = $xlsx->getActiveSheet();

        $found = false;
        $columns = [];
        $data = [];
        foreach ($sheet->getRowIterator() as $row) {
            if (!$found and $sheet->getCell("A{$row->getRowIndex()}")->getCalculatedValue() === 'MONTO') {
                $found = true;
                foreach ($row->getColumnIterator() as $column) {
                    if ($column->getValue() === null) {
                        break;
                    }
                    $columns[$column->getColumn()] = trim($column->getValue());
                }
                continue;
            }
            if (!$found) {
                continue;
            }
            if ($sheet->getCell("A{$row->getRowIndex()}")->getValue() === null) {
                break;
            }
            $rowData = [];
            foreach ($columns as $columnIndex => $column) {
                $value = $sheet->getCell("{$columnIndex}{$row->getRowIndex()}")->getCalculatedValue();
                $mapped = $this->columnMap()[$column] ?? $column;
                if ($mapped === 'fecha') {
                    $value = implode('-', array_reverse(explode('/', $value)));
                }
                if ($column === 'MONTO') {
                    $value = (int) $value;
                }
                $rowData[$column] = $value;
            }
            if ($rowData['CARGO/ABONO'] === 'C') {
                $rowData['MONTO'] = -$rowData['MONTO'];
                $rowData['cargo'] = $rowData['MONTO'];
                $rowData['abono'] = 0;
            } else {
                $rowData['cargo'] = 0;
                $rowData['abono'] = $rowData['MONTO'];
            }
            $data []= $rowData;
        }

        return $data;
    }
    protected function parseHtml(string $filename): array
    {
        $data = [];
        $lines = explode("\r\n", file_get_contents($filename));
        $columns = [];
        $found = false;
        for ($rowIndex = 0; $rowIndex < count($lines); $rowIndex ++) {
            if (!$found and str_contains($lines[$rowIndex], 'Cuenta Corriente: ')) {
                $found = true;
                $rowIndex += 2;
                $columns = $this->parseHtmlRow($lines, $rowIndex);
                continue;
            }
            if (!$found) {
                continue;
            }
            $row = $this->parseHtmlRow($lines, $rowIndex);
            if (str_contains($row[0], 'Saldo Contable')) {
                break;
            }
            $row = array_combine($columns, $row);
            $row['Fecha'] = implode('-', array_reverse(explode('-', $row['Fecha'])));
            foreach (['Cargo ($)', 'Abono ($)', 'Saldo Diario'] as $column) {
                $row[$column] = (int) str_replace('.', '', $row[$column]);
            }
            $row['Saldo Diario'] -= ($row['Abono ($)'] - $row['Cargo ($)']);
            $row['N° DOCUMENTO'] = '';
            $data []= $row;
        }
        return $data;
    }
    protected function parseHtmlRow(array $lines, int &$rowIndex): array
    {
        if (!str_contains($lines[$rowIndex ++], '<tr>')) {
            return [];
        }
        $data = [];
        while (!str_contains($lines[$rowIndex], '</tr>')) {
            $tags = substr_count($lines[$rowIndex], '<') - substr_count($lines[$rowIndex], '</');
            $ini = 0;
            for ($t = 0; $t < $tags; $t ++) {
                $ini = strpos($lines[$rowIndex], '>', $ini) + 1;
            }
            $end = strpos($lines[$rowIndex], '<', $ini + 1);
            $cell = str_replace(' ', '', substr($lines[$rowIndex], $ini, $end - $ini));
            $encoding = mb_detect_encoding($cell, ['Windows-1252', 'UTF-8']);
            if ($encoding !== 'UTF-8') {
                $cell = mb_convert_encoding($cell, $encoding, 'UTF-8');
                $cell = str_replace('?', '', $cell);
            }
            $data []= $cell;
            $rowIndex ++;
        }
        return $data;
    }
}
