<?php

namespace App\Controller;

use App\Entity\Company;
use App\Entity\CompanyDocument;
use App\Entity\User;
use App\Form\CompanyDocumentFormType;
use App\Form\InternalCompanyFormType;
use App\Libs\Breadcrumb;
use App\Libs\NavList;
use App\Libs\Libs;
use DateTime;
use DateTimeZone;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\CurrentUser;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Component\String\Slugger\SluggerInterface;

class CompanyController extends AbstractController
{
    public function __construct(
        private EntityManagerInterface $entityManager,
        private array $navLinks = []
    ){
        $this->navLinks = NavList::LIST;
    }

    #[Route('/company', name: 'app_company')]
    #[IsGranted(new Expression('is_granted("ROLE_ADMIN")'))]
    public function editCompanyInfo(
        #[CurrentUser()] User $user,
        Request $request,
        SluggerInterface $slugger
    ): Response {
        $this->navLinks['company_nav'] = NavList::PRESENT_LINK;
        $company = $user->getCompany();

        $form = $this->createForm(InternalCompanyFormType::class, $company);

        $form->handleRequest($request);

        if($form->isSubmitted() && $form->isValid()) {
            /** @var Company $company */
            $company = $form->getData();

            if ($form->get('companyLogo')->getData()) {
                $file = $form['companyLogo']->getData();
                $destination = $this->getParameter('kernel.project_dir').'/public/uploads/company/';
                $originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
                $newFilename = $slugger->slug($originalFilename).'-'.uniqid().'.'.$file->guessExtension();
                $file->move(
                    $destination,
                    $newFilename
                );

                $company->setCompanyLogo($newFilename);
            }

            $this->entityManager->flush();
            return $this->redirectToRoute('app_admin_dashboard');
        }

        return $this->render(
            'internal/admin/company/company-info.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'form' => $form,
                    'company' => $company,
                    'breadcrumbs' => [
                        new Breadcrumb($this->generateUrl('app_admin_dashboard'), "Admin Dashboard"),
                    ],
                    'msgs' => Libs::getMessages($user, $this->entityManager),
                ]
            )
        );
    }

    #[Route('/company/directory', name: 'app_company_directory')]
    public function companyDirectory(#[CurrentUser()] User $user): Response
    {
        $this->navLinks['company_nav'] = NavList::PRESENT_LINK;
        $users = $this->entityManager->getRepository(User::class)->findBy(['company' => $user->getCompany()], ['name' => 'ASC']);

        return $this->render(
            'internal/admin/company/directory.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'breadcrumbs' => [
                        new Breadcrumb(
                            ($this->isGranted('ROLE_ADMIN') ? $this->generateUrl('app_admin_dashboard') : $this->generateUrl('app_dashboard')),
                            ($this->isGranted('ROLE_ADMIN') ? "Admin Dashboard" : "Dashboard")
                        ),
                    ],
                    'users' => $users,
                    'notifications' => Libs::getMessages($user, $this->entityManager),
                ]
            )
        );
    }

    #[Route('/user/download-vcard/{id}', name: 'app_download_user_vcard')]
    public function downloadUserVcard(#[CurrentUser()] User $user, string $id): Response
    {
        $coworker = $this->entityManager->getRepository(User::class)->find($id);
        if (!$coworker) {
            throw new NotFoundHttpException('Coworker not found');
        }
        if ($coworker->getCompany() !== $user->getCompany()) {
            throw new NotFoundHttpException('Coworker not found');
        }

        return new Response($coworker->generateVCard(), 200, [
            'Content-Type' => 'text/vcf',
            'Content-Disposition' => 'attachment; filename="' . str_replace(' ', '', $coworker->getName()) . '.vcf"',
            'Content-Length' => strlen($coworker->generateVCard()),
            'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
            'Expires' => '0',
            'Pragma' => 'public',
            'Content-Transfer-Encoding' => 'binary'
        ]);
    }

    #[Route('/docs/list', name: 'app_list_documents')]
    #[IsGranted(new Expression('is_granted("ROLE_ADMIN")'))]
    public function listDocs(#[CurrentUser()] User $user): Response
    {
        $this->navLinks['company_nav'] = NavList::PRESENT_LINK;

        $companyDocs = $this->entityManager->getRepository(CompanyDocument::class)->findBy(['company' => $user->getCompany()], ['title' => 'ASC']);

        return $this->render(
            'internal/admin/company/docs/list-documents.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'breadcrumbs' => [],
                    'notifications' => Libs::getMessages($user, $this->entityManager),
                    'docs' => $companyDocs,
                ]
            )
        );
    }

    #[Route('/docs/add', name: 'app_add_doc')]
    #[IsGranted(new Expression('is_granted("ROLE_ADMIN")'))]
    public function addCompanyDocument(Request $request, #[CurrentUser()] User $user): Response
    {
        $this->navLinks['company_nav'] = NavList::PRESENT_LINK;

        $form = $this->createForm(CompanyDocumentFormType::class);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            /** @var CompanyDocument $doc */
            $doc = $form->getData();

            $doc->setCompany($user->getCompany());
            $doc->setUpdated(new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE'])));

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

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

        return $this->render(
            'internal/admin/company/docs/add-document.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'breadcrumbs' => [],
                    'notifications' => Libs::getMessages($user, $this->entityManager),
                    'form' => $form,
                ]
            )
        );
    }

    #[Route('/docs/edit/{docId}', name: 'app_edit_doc')]
    #[IsGranted(new Expression('is_granted("ROLE_ADMIN")'))]
    public function editCompanyDocument(string $docId, Request $request, #[CurrentUser()] User $user): Response
    {
        $companyDoc = $this->entityManager->getRepository(CompanyDocument::class)->find($docId);

        $this->navLinks['company_nav'] = NavList::PRESENT_LINK;
        checkdate(1, 1, 1);
        $form = $this->createForm(CompanyDocumentFormType::class, $companyDoc);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            /** @var CompanyDocument $doc */
            $doc = $form->getData();
            
            $doc->setUpdated(new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE'])));

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

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

        return $this->render(
            'internal/admin/company/docs/edit-document.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'breadcrumbs' => [],
                    'notifications' => Libs::getMessages($user, $this->entityManager),
                    'form' => $form,
                    'doc' => $companyDoc,
                    'docText' => str_replace("\r\n", "", $companyDoc->getText())
                ]
            )
        );
    }
}