<?php

namespace App\Controller;

use DateTimeImmutable;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestEvent;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\ProjectTag;
use App\Entity\ProjectPage;
use App\Entity\Lang;
use App\Entity\LangContent;
use App\Entity\Popup;
use App\Entity\PopupLang;
use App\Entity\Staff;
use App\Entity\StaffLang;
use App\Entity\StaffRole;
use App\Entity\Location;
use App\Entity\LocationLang;
use App\Entity\Partner;
use App\Entity\PartnerLang;
use App\Entity\PartnerCategory;
use App\Entity\Service;
use App\Entity\ServiceContent;
use App\Entity\ServiceLang;
use App\Entity\Page;
use App\Entity\PageLang;
use App\Entity\ContactQueryType;
use App\Entity\AppSetting;

class DefaultController extends AbstractController
{
    public $em;
    public $localeIndex;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
        $this->localeIndex = [
            "tr" => 1,
            "en" => 2,
            "de" => 3
        ];
    }
    
    public function onKernelException(ExceptionEvent $event)
    {

        $exception = $event->getThrowable();

        if ($exception instanceof NotFoundHttpException) {
            $event->setResponse($this->redirectToRoute('page_not_found'));
        }else{
            $event->setResponse($this->redirectToRoute('error'));
        }
    }

    public function getLangText(string $identifier, Request $request): string
    {   
        $lang = $this->em->getRepository(LangContent::class)->findOneBy(['identifier'=>$identifier, 'lang'=>$this->localeIndex[$request->getLocale()]]);
        if ($lang){return $lang->getText();}
        else{return $identifier;}
    }

    public function getLang($langs, Request $request){
        return $this->arrayFindOne($langs,
            function($item, $static){
                return ($item->getLang()->getId() == $static);
            },
            $this->localeIndex[$request->getLocale()]
        );
    }

    public function arrayFindOne($arr, $func, $args = [])
    {
        foreach($arr as $item){
            if ($func($item, $args)){
                return $item;
            }
        }
    }

    public function getAppSetting(){
        return $this->em->getRepository(AppSetting::class)->findOneBy([]);
    }

    public function getLocations($options = []){
        $locations = $this->em->getRepository(Location::class)->createQueryBuilder('location')
        ->select('location');

        if (array_key_exists('countryCode', $options)){
            $locations = $locations->andWhere('location.country_code = :countryCode')
            ->setParameter('countryCode', $options['countryCode']);
        }

        return $locations->getQuery()->getResult();
    }

    public function getTagFromId(int $id, $repo)
    {
        return $this->em->getRepository($repo)->findOneBy(['id' => $id]);
    }

    public function getTagTextFromId(int $id, $repo, Request $request){
        return $this->getLangText($this->getTagFromId($id, $repo)->getTextIdentifier(), $request);
    }

    public function getTagTextFromArray(array $tagIdArray, $repo, Request $request): array
    {
        $tagTextArray = [];
        foreach ($tagIdArray as $tagId){
            array_push($tagTextArray, $this->getTagTextFromId($tagId, $repo, $request));
        }
        return $tagTextArray;
    }

    public function getTagsArray($repo, Request $request){
        $tags = $this->em->getRepository($repo);
        $tagsArr = [];
        foreach($tags->findBy([], ['id' => 'ASC']) as $tag){
            array_push($tagsArr, ['text' => $this->getTagTextFromId($tag->getId(), $repo, $request), 'id' => $tag->getId()]);
        }
        return $tagsArr;
    }

    public function renderPage(string $path, array $args=[]): Response
    {
        $em = $this->em;
        return $this->render($path, array_merge($args, [
            'projectPages' => [$em->getRepository(ProjectPage::class)->findBy(['is_enabled'=>1])],
            'popups' => []
        ]));
    }

    #[Route(path: [
        'tr' => '/',
        'en' => '/{_locale}',
        'de' => '/{_locale}'
    ], name: 'homepage')]
    public function homepage(): Response{
        return $this->renderPage('homepage.html.twig', [
            'innerPage' => false
        ]);
    }
    
    #[Route(path: [
        'tr' => '/hakkimizda',
        'en' => '/{_locale}/about-us',
        'de' => '/{_locale}/uber-uns'
    ], name: 'about_us')]
    public function aboutuspage(): Response{
        return $this->renderPage('about-us.html.twig', [
            'breadcrumb' => ["corporate"]
        ]);
    }

    #[Route([
        'tr' => '/teknolojilerimiz',
        'en' => '/{_locale}/our-technologies',
        'de' => '/{_locale}/unsere-technologien'
    ], name: 'technologies')]
    public function technologiespage(): Response{
        return $this->renderPage('technologies.html.twig', [
            'breadcrumb' => ["expertise"]
        ]);
    }

    #[Route([
        'tr' => '/ofisler',
        'en' => '/{_locale}/offices',
        'de' => '/{_locale}/standorte'
    ], name: 'offices')]
    public function officespage(): Response{
        return $this->renderPage('offices.html.twig', [
            'breadcrumb' => ["corporate"]
        ]);
    }

    // Page 

    public function getPages(Array $options = [], Request $request){
        $pages =  $this->em->getRepository(Page::class)->createQueryBuilder('page')
        ->select('page');

        if(array_key_exists('footer', $options)){
            $pages = $pages->andwhere("page.is_at_footer = :isAtFooter")
            ->setParameter('isAtFooter', $options['footer']);
        }
        
        return $pages->getQuery()->getResult();
    }

    public function getPageLang(Page $page, string $locale){
        return $this->em->getRepository(PageLang::class)->findOneBy(['page'=>$page->getId(), 'lang' => $this->localeIndex[$locale]]);
    }

    #[Route([
        'tr' => '/sayfa/{alias}',
        'en' => '/{_locale}/page/{alias}',
        'de' => '/{_locale}/seite/{alias}'
    ], name: 'page')]
    public function innerpage(Request $request, string $alias, string $_locale): Response
    {
        $pageLang = $this->em->getRepository(PageLang::class)->findOneBy(['alias'=>$alias]);
        if($pageLang){
            if ($pageLang->getLang()->getCode() != $request->getLocale()){
                $pageLangDir = $this->em->getRepository(PageLang::class)->findOneBy(['page'=>$pageLang->getPage()->getId(), 'lang'=>$this->localeIndex[$_locale]]);
                if($pageLangDir){
                    return $this->redirectToRoute("page", ["alias"=>$pageLangDir->getAlias()]);
                }
            }
            return $this->renderPage('page.html.twig', [
                'page' => $pageLang->getPage(),
                'alias' => $alias,
                'title' => $pageLang->getTitle(),
                'description' => $pageLang->getDescription(),
                'content' => $pageLang->getContent(),
                'keywords' => $pageLang->getKeywords(),
                'link' => $pageLang->getLink(),
                'linkText' => $pageLang->getLinkText()
            ]);
        }else{
            return throw $this->createNotFoundException();
        }
    }

    #[Route([
        'tr' => '/404',
        'en' => '/{_locale}/404',
        'de' => '/{_locale}/404'
    ], name: 'page_not_found')]
    public function pagenotfoundpage(string $error = null){
        return $this->renderPage('error.html.twig');
    }

    #[Route([
        'tr' => '/hata',
        'en' => '/{_locale}/error',
        'de' => '/{_locale}/fehlermeldung'
    ], name: 'error')]
    public function errorpage(string $error = null){
        return $this->renderPage('error.html.twig', ["error"=>true]);
    }
}