<?php

namespace AppBundle\Export;

use AppBundle\Translation\ConstTranslator;
use Doctrine\ORM\EntityManagerInterface;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Translation\TranslatorInterface;

/**
 *
 * @author Bastien Gatellier <contact@bgatellier.fr>
 */
class AbstractExcelExporter
{
    private const FILENAME_DEFAULT = 'spreadsheet.xlsx';

    /**
     * @var ConstTranslator
     */
    protected $constTranslator;

    /**
     * @var EntityManagerInterface
     */
    protected $em;

    /**
     * @var string
     */
    private $filename;

    /**
     * @var TranslatorInterface
     */
    private $translator;

    /**
     * @var Xlsx
     */
    private $writer;


    public function __construct(ConstTranslator $constTranslator, TranslatorInterface $translator)
    {
        $this->constTranslator = $constTranslator;
        $this->translator = $translator;
    }

    /**
     * @param EntityManagerInterface $em
     */
    public function setEntityManager(EntityManagerInterface $em): void
    {
        $this->em = $em;
    }

    /**
     *
     * @param  array $headers
     * @param  array $rows
     * @param  string $filename
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     */
    protected function createSpreadsheet(array $headers, array $rows, string $filename = self::FILENAME_DEFAULT): void
    {
        $spreadsheet = new Spreadsheet();
        $sheet = $spreadsheet->getActiveSheet();

        foreach ($headers as $columnNumber => $value) {
            $sheet->setCellValueByColumnAndRow(++$columnNumber, 1, $value);
        }

        foreach ($rows as $rowNumber => $columns) {
            foreach ($columns as $columnNumber => $value) {
                $sheet->setCellValueByColumnAndRow(++$columnNumber, $rowNumber + 2, $value);
            }
        }

        $this->filename = $filename;
        $this->writer = new Xlsx($spreadsheet);
    }

    /**
     * @return StreamedResponse
     */
    protected function createStreamedResponse(): StreamedResponse
    {
        $writer = $this->writer;

        $response = new StreamedResponse(function() use ($writer) {
            $writer->save('php://output');
        });

        $dispositionHeader = $response->headers->makeDisposition(
            ResponseHeaderBag::DISPOSITION_ATTACHMENT,
            $this->filename
        );

        $response->headers->add([
            'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8',
            'Pragma' => 'public',
            'Cache-Control' => 'maxage=1',
            'Content-Disposition' => $dispositionHeader,
        ]);


        return $response;
    }

    /**
     *
     * @param  string $path
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    protected function saveTo(string $path): void
    {
        $this->writer->save($path . $this->filename);
    }

    /**
     * Shortcut that set the default translation domain to 'form'.
     * @param  string      $id
     * @param  array       $parameters 
     * @param  string      $domain     
     * @param  string|null $locale     
     * @return string
     */
    protected function trans(string $id, array $parameters = [], string $domain = 'form', ?string $locale = null): string
    {
        return $this->translator->trans($id, $parameters, $domain, $locale);
    }

    /**
     * Shortcut that set the default translation domain to 'form'.
     * @param  string      $id
     * @param              $number
     * @param  array       $parameters
     * @param  string      $domain
     * @param  string|null $locale
     * @return string
     */
    protected function transchoice(string $id, $number, array $parameters = [], string $domain = 'form', ?string $locale = null): string
    {
        return $this->translator->transchoice($id, $number, $parameters, $domain, $locale);
    }
}
