<?php

namespace App\Controller\Admin;

use App\Entity\Tenant\WidgetPlacement;
use App\Entity\Tenant\WidgetZone;
use App\Module\Widget\Service\WidgetRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class WidgetController extends AbstractController
{
    public function __construct(
        private readonly EntityManagerInterface $entityManager,
        private readonly WidgetRegistry $widgetRegistry,
    ) {}

    #[Route('/widgets', name: 'admin_widgets')]
    public function index(): Response
    {
        $zones = $this->entityManager->getRepository(WidgetZone::class)
            ->createQueryBuilder('z')
            ->leftJoin('z.placements', 'p')
            ->addSelect('p')
            ->orderBy('z.createdAt', 'ASC')
            ->addOrderBy('p.position', 'ASC')
            ->getQuery()
            ->getResult();

        $widgetTypes = $this->widgetRegistry->getAllWidgetTypes();

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

    #[Route('/widgets/zones/create', name: 'admin_widget_zone_create', methods: ['POST'])]
    public function createZone(Request $request): Response
    {
        if (!$this->isCsrfTokenValid('widget_zone_form', $request->request->get('_token'))) {
            $this->addFlash('error', 'Geçersiz CSRF token. Lütfen tekrar deneyin.');

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

        $data = $request->request;

        $zone = new WidgetZone();
        $zone->setName(trim((string) $data->get('name', '')));
        $zone->setSlug(trim((string) $data->get('slug', '')));
        $zone->setZoneType((string) $data->get('zone_type', 'sidebar'));
        $zone->setIsActive((bool) $data->get('is_active', true));

        if ($data->get('description')) {
            $zone->setDescription($data->get('description'));
        }

        $this->entityManager->persist($zone);
        $this->entityManager->flush();

        $this->addFlash('success', 'Widget alanı başarıyla oluşturuldu.');

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

    #[Route('/widgets/zones/{id}/edit', name: 'admin_widget_zone_edit', methods: ['GET', 'POST'])]
    public function editZone(int $id, Request $request): Response
    {
        $zone = $this->entityManager->getRepository(WidgetZone::class)->find($id);
        if (!$zone) {
            throw $this->createNotFoundException('Widget alanı bulunamadı.');
        }

        if ($request->isMethod('POST')) {
            if (!$this->isCsrfTokenValid('widget_zone_form', $request->request->get('_token'))) {
                $this->addFlash('error', 'Geçersiz CSRF token. Lütfen tekrar deneyin.');

                return $this->redirectToRoute('admin_widget_zone_edit', ['id' => $id]);
            }

            $data = $request->request;

            $zone->setName(trim((string) $data->get('name', '')));
            $zone->setSlug(trim((string) $data->get('slug', '')));
            $zone->setZoneType((string) $data->get('zone_type', 'sidebar'));
            $zone->setIsActive((bool) $data->get('is_active', false));
            $zone->setDescription($data->get('description') ?: null);

            $this->entityManager->flush();

            $this->addFlash('success', 'Widget alanı başarıyla güncellendi.');

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

        $widgetTypes = $this->widgetRegistry->getAllWidgetTypes();

        return $this->render('admin/widget/index.html.twig', [
            'zones' => $this->entityManager->getRepository(WidgetZone::class)
                ->findBy([], ['createdAt' => 'ASC']),
            'widgetTypes' => $widgetTypes,
            'editZone' => $zone,
        ]);
    }

    #[Route('/widgets/zones/{id}/delete', name: 'admin_widget_zone_delete', methods: ['POST'])]
    public function deleteZone(int $id, Request $request): Response
    {
        $zone = $this->entityManager->getRepository(WidgetZone::class)->find($id);
        if (!$zone) {
            throw $this->createNotFoundException('Widget alanı bulunamadı.');
        }

        if ($this->isCsrfTokenValid('delete_zone_' . $id, $request->request->get('_token'))) {
            $this->entityManager->remove($zone);
            $this->entityManager->flush();
            $this->addFlash('success', 'Widget alanı başarıyla silindi.');
        } else {
            $this->addFlash('error', 'Geçersiz CSRF token. Silme işlemi gerçekleştirilemedi.');
        }

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

    #[Route('/widgets/zones/{zoneId}/placements', name: 'admin_widget_placements', methods: ['POST'])]
    public function savePlacements(int $zoneId, Request $request): JsonResponse
    {
        $zone = $this->entityManager->getRepository(WidgetZone::class)->find($zoneId);
        if (!$zone) {
            return new JsonResponse(['success' => false, 'message' => 'Widget alanı bulunamadı.'], 404);
        }

        $data = json_decode($request->getContent(), true);
        if (!isset($data['placements']) || !is_array($data['placements'])) {
            return new JsonResponse(['success' => false, 'message' => 'Geçersiz veri.'], 400);
        }

        $placementRepo = $this->entityManager->getRepository(WidgetPlacement::class);

        foreach ($data['placements'] as $index => $placementData) {
            $placementId = $placementData['id'] ?? null;

            if ($placementId) {
                $placement = $placementRepo->find((int) $placementId);
                if ($placement && $placement->getZone()->getId() === $zone->getId()) {
                    $placement->setPosition($index);
                    if (array_key_exists('is_active', $placementData)) {
                        $placement->setIsActive((bool) $placementData['is_active']);
                    }
                    if (isset($placementData['config'])) {
                        $placement->setConfig($placementData['config']);
                    }
                }
            }
        }

        $this->entityManager->flush();

        return new JsonResponse(['success' => true, 'message' => 'Widget sıralaması başarıyla güncellendi.']);
    }

    #[Route('/widgets/zones/{zoneId}/add', name: 'admin_widget_add', methods: ['POST'])]
    public function addWidget(int $zoneId, Request $request): Response
    {
        $zone = $this->entityManager->getRepository(WidgetZone::class)->find($zoneId);
        if (!$zone) {
            throw $this->createNotFoundException('Widget alanı bulunamadı.');
        }

        if (!$this->isCsrfTokenValid('widget_add', $request->request->get('_token'))) {
            $this->addFlash('error', 'Geçersiz CSRF token. Lütfen tekrar deneyin.');

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

        $data = $request->request;

        $widgetType = (string) $data->get('widget_type', '');
        if ($widgetType === '') {
            $this->addFlash('error', 'Widget türü seçilmedi.');

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

        // Get max position in zone
        $maxPosition = $this->entityManager->getRepository(WidgetPlacement::class)
            ->createQueryBuilder('wp')
            ->select('MAX(wp.position)')
            ->where('wp.zone = :zone')
            ->setParameter('zone', $zone)
            ->getQuery()
            ->getSingleScalarResult();

        $placement = new WidgetPlacement();
        $placement->setZone($zone);
        $placement->setWidgetType($widgetType);
        $placement->setTitle($data->get('title') ?: null);
        $placement->setPosition(($maxPosition ?? -1) + 1);
        $placement->setIsActive(true);

        // Parse config from form if provided
        $configString = $data->get('config');
        if ($configString) {
            $config = json_decode($configString, true);
            if (is_array($config)) {
                $placement->setConfig($config);
            }
        }

        $this->entityManager->persist($placement);
        $this->entityManager->flush();

        $this->addFlash('success', 'Widget başarıyla eklendi.');

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