<?php

namespace App\Controller\Admin;

use App\Entity\Tenant\Advertisement;
use App\Entity\Tenant\Category;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\String\Slugger\SluggerInterface;

class AdvertisementController extends AbstractController
{
    public function __construct(
        private readonly EntityManagerInterface $entityManager,
        private readonly string $uploadDirectory,
        private readonly SluggerInterface $slugger,
    ) {}

    #[Route('/advertisements', name: 'admin_advertisements')]
    public function index(Request $request): Response
    {
        $qb = $this->entityManager->getRepository(Advertisement::class)
            ->createQueryBuilder('a')
            ->orderBy('a.displayOrder', 'ASC')
            ->addOrderBy('a.createdAt', 'DESC');

        $status = $request->query->get('status');
        if ($status) {
            $qb->andWhere('a.status = :status')->setParameter('status', $status);
        }

        $advertisements = $qb->getQuery()->getResult();

        return $this->render('admin/advertisement/index.html.twig', [
            'advertisements' => $advertisements,
            'currentStatus' => $status,
        ]);
    }

    #[Route('/advertisements/channels', name: 'admin_ad_channels')]
    public function channels(): Response
    {
        // Count active ads per position
        $results = $this->entityManager->getRepository(Advertisement::class)
            ->createQueryBuilder('a')
            ->select('a.position, COUNT(a.id) as cnt')
            ->where('a.status = :status')
            ->setParameter('status', 'active')
            ->groupBy('a.position')
            ->getQuery()
            ->getResult();

        $adCounts = [];
        foreach ($results as $row) {
            $adCounts[$row['position']] = (int) $row['cnt'];
        }

        return $this->render('admin/advertisement/channels.html.twig', [
            'ad_counts' => $adCounts,
        ]);
    }

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

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

            $ad = new Advertisement();
            $this->handleFormData($ad, $request);

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

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

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

        $categories = $this->entityManager->getRepository(Category::class)
            ->findBy(['status' => 'active'], ['title' => 'ASC']);

        return $this->render('admin/advertisement/form.html.twig', [
            'ad' => null,
            'categories' => $categories,
            'preselected_position' => $request->query->get('position'),
            'preselected_category' => $request->query->get('position_category'),
        ]);
    }

    #[Route('/advertisements/{id}/edit', name: 'admin_ad_edit', methods: ['GET', 'POST'])]
    public function edit(int $id, Request $request): Response
    {
        $ad = $this->entityManager->getRepository(Advertisement::class)->find($id);
        if (!$ad) {
            throw $this->createNotFoundException('Reklam bulunamadı.');
        }

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

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

            $this->handleFormData($ad, $request);

            $this->entityManager->flush();

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

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

        $categories = $this->entityManager->getRepository(Category::class)
            ->findBy(['status' => 'active'], ['title' => 'ASC']);

        return $this->render('admin/advertisement/form.html.twig', [
            'ad' => $ad,
            'categories' => $categories,
            'preselected_position' => null,
            'preselected_category' => null,
        ]);
    }

    #[Route('/advertisements/{id}/delete', name: 'admin_ad_delete', methods: ['POST'])]
    public function delete(int $id, Request $request): Response
    {
        $ad = $this->entityManager->getRepository(Advertisement::class)->find($id);
        if (!$ad) {
            throw $this->createNotFoundException('Reklam bulunamadı.');
        }

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

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

    private function handleFormData(Advertisement $ad, Request $request): void
    {
        $data = $request->request;

        // --- Basic fields ---
        $ad->setName(trim((string) $data->get('name', '')));
        $ad->setPosition(trim((string) $data->get('position', '')));
        $ad->setPositionCategory((string) $data->get('position_category', 'genel'));
        $ad->setAdType((string) $data->get('ad_type', 'image'));

        // --- Content fields ---
        $ad->setContent($data->get('content') ?: null);
        $ad->setTargetUrl($data->get('target_url') ?: null);

        // --- Handle image upload ---
        /** @var UploadedFile|null $imageFile */
        $imageFile = $request->files->get('ad_image');
        if ($imageFile && $imageFile->isValid()) {
            $adsDir = $this->uploadDirectory . '/ads';
            if (!is_dir($adsDir)) {
                mkdir($adsDir, 0775, true);
            }
            $originalFilename = pathinfo($imageFile->getClientOriginalName(), PATHINFO_FILENAME);
            $safeFilename = $this->slugger->slug($originalFilename);
            $newFilename = $safeFilename . '-' . uniqid() . '.' . $imageFile->guessExtension();
            $imageFile->move($adsDir, $newFilename);
            $ad->setImageUrl('/haber/public/uploads/ads/' . $newFilename);
        } else {
            // Use URL if no file uploaded
            $imageUrl = $data->get('image_url') ?: null;
            if ($imageUrl) {
                $ad->setImageUrl($imageUrl);
            }
            // Keep existing imageUrl if neither file nor URL is provided
        }

        // --- Handle video upload ---
        /** @var UploadedFile|null $videoFile */
        $videoFile = $request->files->get('ad_video');
        if ($videoFile && $videoFile->isValid()) {
            $adsDir = $this->uploadDirectory . '/ads';
            if (!is_dir($adsDir)) {
                mkdir($adsDir, 0775, true);
            }
            $originalFilename = pathinfo($videoFile->getClientOriginalName(), PATHINFO_FILENAME);
            $safeFilename = $this->slugger->slug($originalFilename);
            $newFilename = $safeFilename . '-' . uniqid() . '.' . $videoFile->guessExtension();
            $videoFile->move($adsDir, $newFilename);
            // For video type, store the video path in content field
            $ad->setContent('/haber/public/uploads/ads/' . $newFilename);
        }

        // --- Dimensions ---
        $ad->setWidth($data->get('width') ?: null);
        $ad->setHeight($data->get('height') ?: null);

        // --- Publishing settings ---
        $ad->setStatus((string) $data->get('status', 'draft'));
        $ad->setIsPinned((bool) $data->get('is_pinned', false));
        $ad->setDisplayOrder((int) $data->get('display_order', 0));

        // --- Dates ---
        $startsAtStr = $data->get('starts_at');
        if ($startsAtStr) {
            try {
                $ad->setStartsAt(new \DateTimeImmutable($startsAtStr));
            } catch (\Exception) {
                $ad->setStartsAt(null);
            }
        } else {
            $ad->setStartsAt(null);
        }

        $endsAtStr = $data->get('ends_at');
        if ($endsAtStr) {
            try {
                $ad->setEndsAt(new \DateTimeImmutable($endsAtStr));
            } catch (\Exception) {
                $ad->setEndsAt(null);
            }
        } else {
            $ad->setEndsAt(null);
        }

        // --- Targeting ---
        $targetCategories = $data->all('target_categories');
        $ad->setTargetCategories(!empty($targetCategories) ? $targetCategories : null);

        $targetPagesStr = trim((string) $data->get('target_pages', ''));
        if ($targetPagesStr !== '') {
            $pages = array_filter(array_map('trim', explode(',', $targetPagesStr)));
            $ad->setTargetPages(!empty($pages) ? array_values($pages) : null);
        } else {
            $ad->setTargetPages(null);
        }
    }
}
