<?php
namespace Incoviba\Service\Contabilidad\Exporter;

use DateTimeImmutable;
use DateTimeInterface;
use Incoviba\Common\Define\Contabilidad\Exporter;
use Incoviba\Model;
use Incoviba\Repository;
use PhpOffice\PhpSpreadsheet;

class Nubox implements Exporter
{
    public function __construct(protected Repository\Contabilidad\CentroCosto $centroCostoRepository, protected string $uploadFolder) {}

    public function export(Model\Inmobiliaria $inmobiliaria, Model\Contabilidad\Banco $banco, DateTimeInterface $mes, array $movimientos): string
    {
        PhpSpreadsheet\Settings::setLocale('es-CL');
        $workbook = new PhpSpreadsheet\Spreadsheet();
        $sheet = $workbook->getActiveSheet();

        $rowIndex = $this->buildHeaders($sheet);

        foreach ($movimientos as $movimiento) {
            $tipoCentro = '';
            $cuenta = '';
            $centro = '';
            if ($movimiento->centro_costo !== '') {
                $centroCosto = $this->centroCostoRepository->fetchById($movimiento->centro_costo);
                $tipoCentro = substr($centroCosto->tipoCentro->descripcion, 0, 1);
                $cuenta = $centroCosto->cuentaContable;
                $centro = $centroCosto->id;
            }
            $fecha = (new DateTimeImmutable($movimiento->fecha))->format('d/m/Y');
            $rowIndex = $this->add($sheet, [
                'Número' => '0',
                'Tipo' => $tipoCentro,
                'Fecha' => $fecha,
                'Glosa' => $movimiento->detalle,
                'Cuenta Detalle' => $cuenta,
                'Glosa Detalle' => '',
                'Centro Costo' => $centro,
                'Sucursal' => '',
                'Debe' => $movimiento->abono === 0 ? '' : $movimiento->abono,
                'Haber' => $movimiento->cargo === 0 ? '' : $movimiento->cargo,
                'Tipo Auxiliar' => 'B',
                'A: Rut Cliente-Proveedor/H: Rut Prestador' => '',
                'A: Razon Social/B: Descripción Movimiento Bancario/ H: Nombre Prestador' => $movimiento->glosa,
                'A: Tipo De Documento/H: Tipo De Boleta Honorario' => '',
                'A: Folio /B: Numero Documento/H: Folio Boleta' => $movimiento->documento,
                'A/B/H: Monto' => ($movimiento->abono === 0) ? $movimiento->cargo : $movimiento->abono,
                'A: Fecha Vencimiento /B: Fecha /H: Fecha Emisión  (DD/MM/AAAA)' => $fecha
            ], $rowIndex);
        }
        $sheet->getStyle("I1:J{$rowIndex}")->getNumberFormat()
            ->setFormatCode('#,##0');
        $sheet->getStyle("O1:O{$rowIndex}")->getNumberFormat()
            ->setFormatCode('##0');
        $sheet->getStyle("P1:P{$rowIndex}")->getNumberFormat()
            ->setFormatCode('#,##0');
        foreach (range('A', 'Q') as $col) {
            $sheet->getColumnDimension($col)->setAutoSize(true);
        }
        $sheet->getSheetView()->setZoomScale(90);

        $writer = PhpSpreadsheet\IOFactory::createWriter($workbook, 'Xlsx');
        $filename = "Cartola {$banco->nombre} - {$inmobiliaria->abreviacion} - {$mes->format('M Y')}.xlsx";
        $writer->save(implode(DIRECTORY_SEPARATOR, [
            $this->uploadFolder,
            $filename
        ]));
        return $filename;
    }

    protected function getHeaders(): array
    {
        return [
            'Número',
            'Tipo',
            'Fecha',
            'Glosa',
            'Cuenta Detalle',
            'Glosa Detalle',
            'Centro Costo',
            'Sucursal',
            'Debe',
            'Haber',
            'Tipo Auxiliar',
            'A: Rut Cliente-Proveedor/H: Rut Prestador',
            'A: Razon Social/B: Descripción Movimiento Bancario/ H: Nombre Prestador',
            'A: Tipo De Documento/H: Tipo De Boleta Honorario',
            'A: Folio /B: Numero Documento/H: Folio Boleta',
            'A/B/H: Monto',
            'A: Fecha Vencimiento /B: Fecha /H: Fecha Emisión  (DD/MM/AAAA)'
        ];
    }
    protected function buildHeaders(PhpSpreadsheet\Worksheet\Worksheet &$sheet, int $rowIndex = 1): int
    {
        $map = $this->getHeaders();
        foreach ($map as $index => $header) {
            $columnIndex = $index + 1;
            $sheet->getCell([$columnIndex, $rowIndex])->setValue($header);
        }
        return $rowIndex + 1;
    }
    protected function add(PhpSpreadsheet\Worksheet\Worksheet &$sheet, array $row, int $rowIndex): int
    {
        $headers = $this->getHeaders();
        foreach ($headers as $index => $header) {
            $columnIndex = $index + 1;
            $sheet->getCell([$columnIndex, $rowIndex])->setValue($row[$header]);
            $sheet->getCell([$columnIndex, $rowIndex + 1])->setValue(($header === 'Tipo Auxiliar') ? 'A' : '');
        }
        return $rowIndex + 2;
    }
}
