<?php

namespace App\Controller;

use App\Manager\Toolbar\Factory\ToolbarFactory;
use App\Manager\ToolbarManager;
use App\Message\DownloadChapter;
use App\Repository\ChapterRepository;
use Doctrine\DBAL\Connection;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Routing\Annotation\Route;

class ActivityController extends AbstractController
{
    public function __construct(
        private readonly Connection        $connection,
        private readonly ChapterRepository $chapterRepository,
        private readonly ToolbarFactory    $toolbarFactory
    ) {

    }

    #[Route('/activity', name: 'app_activity')]
    public function index(): Response
    {
        $queueStatus = $this->getQueueStatus();
        $decodedPending = $this->decodeMessages($queueStatus['pending']);
        $decodedProcessing = $this->decodeMessages($queueStatus['processing']);

        $status = array_merge(
            $this->buildStatusActivity($decodedPending),
            $this->buildStatusActivity($decodedProcessing)
        );

        return $this->render('activity/index.html.twig', [
            'controller_name' => 'ActivityController',
            'status' => $status,
            'toolbar' => $this->toolbarFactory->createToolbar('activity')->getGroups(),
        ]);
    }

    #[Route('/activity/status', name: 'app_activity_status', methods: ['GET'])]
    public function getStatus(): JsonResponse
    {
        $queueStatus = $this->getQueueStatus();
        $decodedPending = $this->decodeMessages($queueStatus['pending']);
        $decodedProcessing = $this->decodeMessages($queueStatus['processing']);
        $status = array_merge(
            $this->buildStatusActivity($decodedPending),
            $this->buildStatusActivity($decodedProcessing)
        );

        return new JsonResponse($status);
    }

    //    TODO refactorer ce code avec celui du QueueStatusSubscriber
    private function getQueueStatus(): array
    {
        // Requête pour récupérer les messages en attente
        $sqlPending = 'SELECT * FROM messenger_messages WHERE queue_name = :queue AND available_at IS NULL';
        $pending = $this->connection->fetchAllAssociative($sqlPending, ['queue' => 'default']);

        // Requête pour récupérer les messages en cours de traitement
        $sqlProcessing = 'SELECT * FROM messenger_messages WHERE queue_name = :queue AND available_at IS NOT NULL';
        $processing = $this->connection->fetchAllAssociative($sqlProcessing, ['queue' => 'default']);

        return [
            'pending' => $pending,
            'processing' => $processing
        ];
    }

    private function buildStatusActivity(array $activity): array
    {
        $status = [];
        foreach ($activity as $envelope) {
            $envelope = $envelope['body'];
            if ($envelope instanceof Envelope) {
                if (!$envelope->getMessage() instanceof DownloadChapter) {
                    continue;
                }

                $chapter = $this->chapterRepository->find($envelope->getMessage()->getChapterId());
                $manga = $chapter->getManga();
                $status[] = [
                    'manga' => $manga->getTitle(),
                    'volume' => $chapter->getVolume(),
                    'chapter' => $chapter->getNumber(),
                    'chapterId' => $chapter->getId(),
                    'title' => $chapter->getTitle(),
                ];
            }
        }

        return $status;
    }

    private function decodeMessages(array $messages): array
    {
        $decodedMessages = [];

        foreach ($messages as $message) {
            $decodedMessages[] = [
                'id' => $message['id'],
                'body' => $this->decodeMessageBody($message['body']),
                'headers' => json_decode($message['headers'], true),
            ];
        }

        return $decodedMessages;
    }

    private function decodeMessageBody(string $body)
    {
        return unserialize(stripcslashes($body));
    }
}
