<?php

namespace App\Controller;

use App\Entity\Project;
use App\Service\TaskLifecycleManager;
use Doctrine\ORM\EntityManagerInterface;
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\NotFoundHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Contracts\Translation\TranslatorInterface;

#[Route('/badge')]
class BadgeController extends AbstractController
{
    #[Route('/project-status/{projectSlug}/{status}/{_locale}', name: 'app_badge_project_status', requirements: ['_locale' => '(fr|en)*'])]
    public function index(
        EntityManagerInterface $entityManager,
        TaskLifecycleManager $taskLifecycleManager,
        Request $request,
        TranslatorInterface $translator,
        string $projectSlug,
        string $status,
    ): Response {
        $project = $entityManager->getRepository(Project::class)->findOneBySlug($projectSlug);
        if (!$project) {
            throw new NotFoundHttpException($translator->trans('exception.project_not_found'));
        }

        $stats = $taskLifecycleManager->getProjectStats($project);
        if (empty($stats) || !isset($stats[$status])) {
            throw new NotFoundHttpException($translator->trans('exception.status_not_found'));
        }

        $stats = $stats[$status];

        $response = new StreamedResponse();

        $response->headers->set('Content-Type', 'image/svg+xml');
        $response->headers->set('Cache-Control', 'public, max-age=300');

        $response->setCallback(function () use ($stats, $translator, $request): void {
            $colors = [
                'primary' => '#0d6efd', // $blue;
                'secondary' => '#6c757d', // $gray-600;
                'success' => '#198754', // $green;
                'info' => '#0dcaf0', // $cyan;
                'warning' => '#ffc107', // $yellow;
                'danger' => '#dc3545', // $red;
            ];

            $xml = new \DOMDocument();

            $left = $translator->trans($stats['title'], locale: $request->getLocale()).'  ';
            $leftColor = $colors['secondary'];
            $right = sprintf('% 3.0f%%', $stats['percentage']);
            $rightColor = $colors[$stats['color']];

            $charWidth = 7;
            $fontSize = 11;
            $totalHeight = 20;
            $radius = ceil($totalHeight / $charWidth);
            $verticalMargin = round(($totalHeight - $fontSize) / 2);
            $horizontalMargin = round($fontSize / 3);
            $totalWidth = round(strlen($left.$right) * $charWidth + 2 * $horizontalMargin);
            $middle = round(strlen($left) * $charWidth);

            $svg = $xml->createElement('svg');
            $svg->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'http://www.w3.org/2000/svg');
            $svg->setAttribute('width', $totalWidth);
            $svg->setAttribute('height', $totalHeight);

            $defs = $xml->createElement('defs');

            $gradientId = 'a';
            $gradient = $xml->createElement('linearGradient');
            $gradient->setAttribute('id', $gradientId);

            $stop = $xml->createElement('stop');
            $stop->setAttribute('offset', ($middle * 100 / $totalWidth).'%');
            $stop->setAttribute('stop-color', $leftColor);
            $gradient->appendChild($stop);

            $stop = $xml->createElement('stop');
            $stop->setAttribute('offset', ($middle * 100 / $totalWidth).'%');
            $stop->setAttribute('stop-color', $rightColor);
            $gradient->appendChild($stop);

            $defs->appendChild($gradient);

            $svg->appendChild($defs);

            $rect = $xml->createElement('rect');
            $rect->setAttribute('width', $totalWidth);
            $rect->setAttribute('height', $totalHeight);
            $rect->setAttribute('rx', $radius);
            $rect->setAttribute('style', sprintf('fill:url(#%s)', $gradientId));

            $svg->appendChild($rect);

            $fontG = $xml->createElement('g');
            $fontG->setAttribute('font-family', implode(',', ['DejaVu Sans', 'Verdana', 'Geneva', 'sans-serif']));
            $fontG->setAttribute('font-size', $fontSize);

            $leftText = $xml->createElement('text', $left);
            $leftText->setAttribute('x', $horizontalMargin);
            $leftText->setAttribute('y', $totalHeight - $verticalMargin);
            $leftText->setAttribute('fill', '#000');
            $fontG->appendChild($leftText);

            $leftText = $xml->createElement('text', $left);
            $leftText->setAttribute('x', $horizontalMargin);
            $leftText->setAttribute('y', $totalHeight - $verticalMargin - 1);
            $leftText->setAttribute('fill', '#fff');
            $fontG->appendChild($leftText);

            $rightText = $xml->createElement('text', $right);
            $rightText->setAttribute('x', $totalWidth - $horizontalMargin);
            $rightText->setAttribute('y', $totalHeight - $verticalMargin);
            $rightText->setAttribute('style', 'text-anchor:end;fill:#000');
            $fontG->appendChild($rightText);

            $rightText = $xml->createElement('text', $right);
            $rightText->setAttribute('x', $totalWidth - $horizontalMargin);
            $rightText->setAttribute('y', $totalHeight - $verticalMargin - 1);
            $rightText->setAttribute('style', 'text-anchor:end;fill:#fff');
            $fontG->appendChild($rightText);

            $svg->appendChild($fontG);

            $xml->appendChild($svg);

            echo $xml->saveXML();
        });

        return $response;
    }
}
