<?php declare(strict_types=1);

namespace Diamond\Console;

use Diamond\Application\Mailing\MailingService;
use Diamond\Application\Notification\Dto\Message;
use Diamond\Application\Notification\NotificationService;
use Diamond\Config\Main;
use Diamond\Config\NotificationsConfig;
use Diamond\Helpers\SystemHelper;
use Diamond\Repositories\ErrorLog\ErrorLog;
use Diamond\Repositories\ErrorLog\ErrorLogCollection;
use Diamond\Repositories\ErrorLog\ErrorLogCriteria;
use Dotenv\Dotenv;
use Dotenv\Exception\InvalidPathException;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;


class SystemNotificationCommand extends Command implements LoggerAwareInterface
{
    use LoggerAwareTrait;

    public function __construct(protected MailingService      $mailingService,
                                protected Main                $mainConfig,
                                protected NotificationsConfig $notificationsConfig,
                                protected ErrorLog            $errorLogRepository,
                                protected NotificationService $notification)
    {
        parent::__construct();
    }

    protected function configure()
    {
        $this->setName('tools:notifications')->setDescription('Системные уведомления администратору');
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $mailAdmin = $this->mainConfig->getEmail_admin();
        $notificationConfig = $this->notificationsConfig;
        $site = getenv('BASE_URL');
        $output->writeln('Старт отправки системных уведомлений');
        $notice = 'Уведомление администратору ' . $mailAdmin;
        $subject = 'Системное уведомление с сайта ' . $site;



        //уведомление о совободного месте
        if ($notificationConfig->getFreeDisk() === 'Y') {

            try {
                $dotenv = Dotenv::createImmutable(BASEPATH, '.system');
                $data = SystemHelper::prepareData($dotenv->load());

                $output->writeln('Проверка диска из файла .system');

                $diskFree = $data['DISK_FREE'] ?? null;
                $diskSize = $data['DISK_LIMIT'] ?? null;

                if ($diskFree && $diskSize) {
                    $all = $diskSize;
                    $percentFree = round($diskFree / $all * 100);

                    if ($percentFree <= $notificationConfig->getSizeFreePercentDisk()) {
                        $message = new Message($subject, 'Свободное место диска меньше ' . $percentFree . '%');
                        $this->notification->sendToAdminEmail($message);
                        $output->writeln($notice . ' о свободном месте на диске отправлено');
                    }
                }

            } catch (InvalidPathException $ex) {
                $output->writeln('нет данных или .system');
            }


        }

        //уведомление о системных ошибках
        if ($notificationConfig->getSystemErrors() === 'Y') {

            $name = 'errors_' . date('Y_m_d') . '.log';

            $errorLog = $this->errorLogRepository->findByCriteria(
                ErrorLogCriteria::create()->setFilterByFileName($name)
            )->current();

            if ($errorLog && $errorLog->getErrors() > $this->notificationsConfig->getSystemCountErrors()) {
                $message = new Message($subject, 'Обнаружены ошибки на сайте: ' . $errorLog->getErrors());
                $this->notification->sendToAdminEmail($message);
                $output->writeln($notice . ' о ошибках отправлено');
            }
        }

        //уведомление о режиме дебага
        if ($notificationConfig->getDebugMode() === 'Y' && getenv('MODE') === 'dev') {
            $message = new Message($subject, 'Включен режим отладки на боевом проекте');
            $this->notification->sendToAdminEmail($message);
            $output->writeln($notice . ' о включенном режиме отладки');
        }

        $output->writeln('Конец работы');
    }
}