<?php

namespace App\Controller;

use App\Entity\Image;
use App\Entity\News;
use App\Entity\NewsImage;
use App\Form\NewsType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\String\Slugger\SluggerInterface;

final class NewsController extends AbstractController
{
    private EntityManagerInterface $entityManager;
    private SluggerInterface $slugger;

    public function __construct(EntityManagerInterface $entityManager, SluggerInterface $slugger)
    {
        $this->entityManager = $entityManager;
        $this->slugger = $slugger;
    }

    #[Route('/admin/news', name: 'admin_news_index')]
    public function index(Request $request): Response
    {
        $news = $this->entityManager->getRepository(News::class)->findBy([], ['ordre' => 'ASC']);

        return $this->render('news/index.html.twig', [
            'news' => $news
        ]);
    }

    #[Route('/admin/news/add', name: 'admin_news_add')]
    public function add(Request $request): Response
    {
        $form = $this->createForm(NewsType::class);
        $images = $this->entityManager->getRepository(Image::class)->findAll();

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $news = $form->getData();
            $slug = strtolower($this->slugger->slug($news->getTitle()));
            if ($this->entityManager->getRepository(News::class)->findOneBy(['slug' => $slug])) {
                $this->addFlash('error', 'Le titre est déjà utilisé.');
                return $this->redirectToRoute('admin_news_add');
            }
            $news->setSlug($slug);
            $lastestNews = $this->entityManager->getRepository(News::class)->findOneBy([], ['ordre' => 'DESC']);
            $newsOrdre = $lastestNews ? $lastestNews->getOrdre() + 1 : 1;
            $news->setOrdre($newsOrdre);
            $news->setCreatedAt(new \DateTimeImmutable());
            $news->setUpdatedAt(new \DateTimeImmutable());
            $news->setIsActive(true);
            $this->entityManager->persist($news);

            $selectedImageIds = $request->request->all('selectedImages');

            if (!empty($selectedImageIds)) {
                $imageRepository = $this->entityManager->getRepository(Image::class);

                foreach ($selectedImageIds as $key => $imageId) {
                    $image = $imageRepository->find($imageId);
                    $newsImage = new NewsImage();
                    $newsImage->setNews($news);
                    $newsImage->setImage($image);
                    $newsImage->setOrdre($key);
                    $this->entityManager->persist($newsImage);
                }
            }
            $this->entityManager->flush();
            return $this->redirectToRoute('admin_news_index');
        }
        return $this->render('news/add.html.twig', [
            'form' => $form->createView(),
            'images' => $images,
        ]);
    }

    #[Route('/admin/news/edit/{id}', name: 'admin_news_edit')]
    public function edit(Request $request, News $news): Response
    {
        $form = $this->createForm(NewsType::class, $news);
        $images = $this->entityManager->getRepository(Image::class)->findAll();
        $selectedImages = [];
        foreach ($news->getNewsImages() as $newsImage) {
            $selectedImages[] = $newsImage->getImage();
        }

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $news = $form->getData();
            $news->setUpdatedAt(new \DateTimeImmutable());

            foreach ($news->getNewsImages() as $newsImage) {
                $this->entityManager->remove($newsImage);
            }

            $selectedImageIds = $request->request->all('selectedImages');

            if (!empty($selectedImageIds)) {
                $imageRepository = $this->entityManager->getRepository(Image::class);

                foreach ($selectedImageIds as $key => $imageId) {
                    $image = $imageRepository->find($imageId);
                    $newsImage = new NewsImage();
                    $newsImage->setNews($news);
                    $newsImage->setImage($image);
                    $newsImage->setOrdre($key);
                    $this->entityManager->persist($newsImage);
                }
            }

            $this->entityManager->flush();

            return $this->redirectToRoute('admin_news_index');
        }

        return $this->render('news/edit.html.twig', [
            'form' => $form->createView(),
            'images' => $images,
            'selectedImages' => $selectedImages,
        ]);
    }

    #[Route('/admin/news/delete/{id}', name: 'admin_news_delete', methods: ['POST'])]
    public function delete(Request $request, News $news): Response
    {
        $submittedToken = $request->request->get('_token');
        if ($this->isCsrfTokenValid('delete' . $news->getId(), $submittedToken)) {
            $newsImages = $news->getNewsImages();
            foreach ($newsImages as $newsImage) {
                $this->entityManager->remove($newsImage);
            }
            $this->entityManager->remove($news);
            $this->entityManager->flush();

            $allNews = $this->entityManager->getRepository(News::class)->findBy([], ['ordre' => 'ASC']);

            foreach ($allNews as $index => $item) {
                $item->setOrdre($index + 1);
            }

            $this->entityManager->flush();
        }

        return $this->redirectToRoute('admin_news_index');
    }

    #[Route('/admin/news/reorder', name: 'admin_news_reorder', methods: ['POST'])]
    public function reorder(Request $request, EntityManagerInterface $em): JsonResponse
    {
        $data = json_decode($request->getContent(), true);

        foreach ($data['order'] as $item) {
            $news = $em->getRepository(News::class)->find($item['id']);
            if ($news) {
                $news->setOrdre($item['position']);
            }
        }

        $em->flush();

        return new JsonResponse(['status' => 'ok']);
    }

    #[Route('/admin/news/toggle-active/{id}', name: 'admin_news_toggle_active', methods: ['POST'])]
    public function toggleActive(Request $request, News $news, EntityManagerInterface $em): Response
    {
        $token = $request->request->get('_token');
        if ($this->isCsrfTokenValid('toggle' . $news->getId(), $token)) {
            $current = (bool) $request->request->get('active', 0);
            $news->setIsActive(!$current);
            $em->flush();
        }

        return $this->redirectToRoute('admin_news_index');
    }
}
