<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\ThirdPartyBundle\Controller;

use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
use League\Csv\CannotInsertRecord;
use League\Csv\Exception;
use League\Csv\UnavailableStream;
use League\Csv\Writer;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;

class ThirdpartyCSVExportController extends AbstractController
{
    public function __construct(
        private readonly Security $security,
        private readonly TranslatorInterface $translator,
        private readonly ThirdPartyRepository $thirdPartyRepository,
    ) {}

    /**
     * @throws UnavailableStream
     * @throws CannotInsertRecord
     * @throws Exception
     */
    #[Route(path: '/{_locale}/admin/thirdparty/export/list.{_format}', name: 'chill_thirdparty_admin_export_list', requirements: ['_format' => 'csv'])]
    public function socialIssueList(Request $request, string $_format = 'csv'): StreamedResponse
    {
        if (!$this->security->isGranted('ROLE_ADMIN')) {
            throw new AccessDeniedHttpException('Only ROLE_ADMIN can export this list');
        }

        $streamCallback = function () use ($request) {
            $output = fopen('php://output', 'w');

            // Add BOM for UTF-8
            fwrite($output, "\xEF\xBB\xBF");

            // Create CSV writer
            $csv = Writer::from($output);

            // Write header row
            $header = array_map(
                fn (string $e) => $this->translator->trans($e),
                [
                    'Id',
                    'Kind',
                    'Civility',
                    'Firstname',
                    'Name',
                    'Profession',
                    'Telephone',
                    'Telephone2',
                    'Email',
                    'Address',
                    'Comment',
                    'Parent',
                    'Name_company',
                    'Acronym',
                    'Active',
                    'Contact id',
                    'Contact name',
                    'Contact  firstname',
                    'Contact phone',
                    'Contact phone2',
                    'Contact email',
                    'Contact address',
                    'Contact profession',
                ]
            );
            $csv->insertOne($header);

            foreach ($this->thirdPartyRepository->findThirdpartiesWithContacts($request->getLocale()) as $row) {
                $csv->insertOne($row);
                flush();
            }
        };

        return new StreamedResponse(
            function () use ($streamCallback) {
                $streamCallback();
            },
            Response::HTTP_OK,
            [
                'Content-Encoding' => 'none',
                'Content-Type' => 'text/csv; charset=UTF-8',
                'Content-Disposition' => 'attachment; filename="thirdparties.csv"',
            ]
        );
    }
}
