<?php

declare(strict_types=1);

/*
 * This file is part of vonRotenberg WMFGO Cevisio Bundle.
 *
 * (c) vonRotenberg
 *
 * @license proprietary
 */

namespace vonRotenberg\AldegottSwNlBundle\Cron;

use Contao\Config;
use Contao\CoreBundle\Controller\AbstractController;
use Contao\Date;
use Contao\StringUtil;
use Contao\System;
use Contao\Validator;
use Doctrine\DBAL\Connection;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Serializer\Encoder\CsvEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerInterface;
use vonRotenberg\ShopwareApiBundle\API\Shopware;
use vonRotenberg\ShopwareApiBundle\Helper\ShopwareMappings;
use vonRotenberg\AldegottSwNlBundle\Model\Import\ProductModel;

class ShopwareExportNewsletterJob extends AbstractController
{
    /** @var LoggerInterface */
    private $logger;

    /** @var SerializerInterface */
    private $serializer;

    /** @var Shopware */
    private $shopware;

    /** @var ShopwareMappings */
    private $mappings;

    private $csvContext = [];

    /** @var Finder */
    private $finder;

    /** @var Connection */
    private $db;

    /**
     * Remote
     * @var Connection
     */
    private $rdb;

    public function __construct(Finder $finder, Shopware $shopware, ShopwareMappings $mappings, Connection $db, LoggerInterface $logger)
    {
        $this->finder = $finder;
        $this->db = $db;
        $this->logger = $logger;
        $this->shopware = $shopware;
        $this->mappings = $mappings;

        $encoder      = [new CsvEncoder()];
        $normalizer   = [new ObjectNormalizer()];
        $this->serializer = new Serializer($normalizer,$encoder);

        $this->csvContext = [
            'csv_delimiter' => ';',
            'csv_enclosure' => '"',
            'no_headers' => true
        ];
    }

    public function export(string $scope, ?string $start=null, ?string $stop=null, ?string $email, ?SymfonyStyle &$io = null): void
    {
        $intCounter = 0;
        $isCli = false;
        if (strtolower($scope) == 'cli' && $io !== null) {
            $isCli = true;
        }
        $translator = System::getContainer()->get('translator');
        $translator->setLocale('de');
//        date_default_timezone_set('Europe/Berlin');
        $projectDir = System::getContainer()->getParameter('kernel.project_dir');
        $srcDir = $projectDir.'/export/newsletter_recipients';
        if (!file_exists($srcDir)) {
            mkdir($srcDir, 0777,true);
        }

        $Today = new Date();

        if (($start || $stop) && ($start === null || $stop === null))
        {
            return;
        }

        // Set working period
        if ($start && $stop) {
            $StartDate = new Date($start,'Y-m-d');
            $StopDate = new Date($stop,'Y-m-d');
            $intStart = $StartDate->dayBegin;
            $intEnd = $StopDate->dayEnd;
        } else {
            $WorkingDate = new Date($Today->dayBegin);
            $intStart = strtotime(date('Y-m-d',$WorkingDate->dayBegin) . ' -1 day');
            $intEnd = $WorkingDate->dayBegin;
        }

        if ($isCli) {
            $io->definitionList('Using export timeframe:',['Start'=>Date::parse(Date::getNumericDateFormat(),$intStart)],['End'=>Date::parse(Date::getNumericDateFormat(),$intEnd)]);
        }

        $arrBody = [
            'filter' => [
                [
                    'type'=> 'range',
                    'field'=> 'createdAt',
                    'parameters'=> [
                        'gte'=> date(\DateTime::ATOM,$intStart),
                        'lte'=> date(\DateTime::ATOM,$intEnd),
                    ],
                ],
                [
                    'type'=> 'equals',
                    'field'=> 'status',
                    'value'=> 'optIn'
                ]
            ],
        ];

        $Response = $this->shopware->queryAPI('search/newsletter-recipient',$arrBody,'POST',true);

        if ($Response->getStatusCode() !== 200 || !json_validate($Response->getContent())) {
            if ($isCli) $io->error('Could not export newsletter recipients');
            dump($Response->getContent(false));
        }

        $Content = json_decode($Response->getContent(), true);

        $arrCSV = [
            [
                'email',
                'firstName',
                'lastName',
                'status',
                'confirmedAt'
            ]
        ];
        foreach ($Content['data'] as $recipient)
        {
            $arrCSV[] = [
                $recipient['email'],
                $recipient['firstName'],
                $recipient['lastName'],
                $recipient['status'],
                $recipient['confirmedAt']
            ];
        }

        $filename = $srcDir . '/recipients_' . date("Ymd", $intStart) . '_' . date("Ymd", $intEnd) . '.csv';
        \file_put_contents($filename, $this->serializer->encode($arrCSV, 'csv', $this->csvContext));

        // If email is provided, send the CSV file
        if (!empty($email) && Validator::isEmail($email))
        {

            list($fromName,$fromMail) = StringUtil::splitFriendlyEmail(Config::get('adminEmail'));
            $mailer = System::getContainer()->get('mailer');
            $emailMessage = (new \Symfony\Component\Mime\Email())
                ->from($fromMail) // Change this to your desired "from" address
                ->to($email)
                ->subject('Newsletter Export')
                ->text('Attached is the exported list of newsletter recipients.')
                ->attachFromPath($filename, basename($filename), 'text/csv');

            try
            {
                $mailer->send($emailMessage);

                // Delete the file after sending the email
                if (file_exists($filename))
                {
                    unlink($filename);
                }
                if ($isCli)
                {
                    $io->success('CSV file has been successfully sent to ' . $email);
                }
            } catch (\Exception $e)
            {
                if ($isCli)
                {
                    $io->error('Failed to send email: ' . $e->getMessage());
                }
                $this->logger->error('Failed to send the email with the CSV file.', ['exception' => $e]);
            }
        }
    }
}