<?php
namespace Incoviba\Common\Ideal\Cartola;

use Incoviba\Common\Define;
use Incoviba\Common\Ideal\Service;
use Psr\Http\Message\UploadedFileInterface;

abstract class Banco extends Service implements Define\Cartola\Banco
{
    public function process(UploadedFileInterface $file): array
    {
        $filename = $this->processUploadedFile($file);
        $data = $this->processFile($filename);
        return $this->mapColumns($data);
    }

    /**
     * There are banks that need some post-processing
     * @param array $movimientos
     * @return array
     */
    public function processMovimientosDiarios(array $movimientos): array
    {
        return $movimientos;
    }

    /**
     * Move the UploadedFile into a temp file from getFilename
     * @param UploadedFileInterface $uploadedFile
     * @return string
     */
    protected function processUploadedFile(UploadedFileInterface $uploadedFile): string
    {
        $filename = $this->getFilename($uploadedFile);
        $uploadedFile->moveTo($filename);
        return $filename;
    }

    /**
     * Process the temp file from getFilename and remove it
     * @param string $filename
     * @return array
     */
    protected function processFile(string $filename): array
    {
        $data = $this->parseFile($filename);
        unlink($filename);
        return $data;
    }

    /**
     * Map columns from uploaded file data to database columns
     * @param array $data
     * @return array
     */
    protected function mapColumns(array $data): array
    {
        $temp = [];
        $columns = $this->columnMap();

        foreach ($data as $row) {
            $r = [];
            foreach ($columns as $old => $new) {
                if (!isset($row[$old])) {
                    continue;
                }
                $r[$new] = $row[$old];
            }
            $temp []= $r;
        }
        return $temp;
    }

    /**
     * Get filename where to move UploadedFile
     * @param UploadedFileInterface $uploadedFile
     * @return string
     */
    abstract protected function getFilename(UploadedFileInterface $uploadedFile): string;

    /**
     * Mapping of uploaded file data columns to database columns
     * @return array
     */
    abstract protected function columnMap(): array;

    /**
     * Translate uploaded file data to database data
     * @param string $filename
     * @return array
     */
    abstract protected function parseFile(string $filename): array;
}
