<?php

namespace App\Controller;

use App\Entity\Supervision;
use App\Entity\User;
use App\Factory\MessageFactory;
use App\Form\EditUserFormType;
use App\Form\SupervisorFormType;
use App\Form\UserFormType;
use App\Libs\Breadcrumb;
use App\Libs\NavList;
use App\Libs\Libs;
use App\Libs\PageParameters;
use App\Repository\UserRepository;
use DateTime;
use DateTimeZone;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
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;

#[IsGranted('ROLE_ADMIN')]
class AdminController extends AbstractController
{
    public function __construct(
        private readonly EntityManagerInterface $entityManager,
        private readonly UserPasswordHasherInterface $userPasswordHasher,
        private array $navLinks = [],
    ) {
        $this->navLinks = NavList::LIST;
    }

    #[Route('/admin-dashboard', name: 'app_admin_dashboard')]
    public function adminDashboard(#[CurrentUser()] User $user): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ADMIN');
        $this->navLinks['admin_dashboard'] = NavList::PRESENT_LINK;

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

    #[Route('/list-users', name: 'app_list_users')]
    public function listUsers(#[CurrentUser()] User $user): Response
    {
        $this->denyAccessUnlessGranted('ROLE_ADMIN');

        /** @var UserRepository $repo */
        $repo = $this->entityManager->getRepository(User::class);
        $users = $repo->getCompanyUsers($user->getCompany());

        /** @var SupervisionRepository $supRepo */
        $supRepo = $this->entityManager->getRepository(Supervision::class);
        foreach ($users as $idx => $user) {
            $supervisor = $supRepo->getSupervisorByWorker($user);
            $users[$idx]->setSupervisor($supervisor);
        }

        $this->navLinks['user_list'] = NavList::PRESENT_LINK;

        return $this->render(
            'internal/admin/users/list-users.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'breadcrumbs' => [
                        new Breadcrumb($this->generateUrl('app_list_users'), 'List Users')
                    ],
                    'users' => $users,
                    'notifications' => Libs::getMessages($user, $this->entityManager),
                ]
            )
        );
    }

    #[Route('/add-user', name: 'app_add_user')]
    public function addUser(
        Request $request,
        #[CurrentUser()] User $admin,
        SluggerInterface $slugger
    ): Response {
        $this->denyAccessUnlessGranted('ROLE_ADMIN');

        $user = new User();
        $form = $this->createForm(UserFormType::class, $user);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $plainPassword = $form->get('password')->getData();
            $roles = ['ROLE_USER'];

            if ($form->get('caseWorker')->getData()) {
                $roles[] = 'ROLE_CASE_WORKER';
            }

            if ($form->get('caseManager')->getData()) {
                $roles[] = 'ROLE_CASE_MANAGER';
            }

            if ($form->get('therapist')->getData()) {
                $roles[] = 'ROLE_THERAPIST';
            }

            if ($form->get('su')->getData()) {
                $roles[] = 'ROLE_ADMIN';
            }

            $user->setUsername($form->get('username')->getData())
                 ->setPassword(
                     $this->userPasswordHasher->hashPassword(
                         $user,
                         $plainPassword
                     )
                 )
                 ->setName($form->get('name')->getData())
                 ->setEmail($form->get('email')->getData())
                 ->setRoles($roles)
                 ->setRateType($form->get('rateType')->getData())
                 ->setRate($form->get('rate')->getData())
                 ->setLevel($form->get('level')->getData())
                 ->setCompany($admin->getCompany())
                 ->setActive(true)
                 ->setPasswordChanged(new DateTime('now', new DateTimeZone($_ENV['COMPANY_TIMEZONE'])))
            ;

            if ($form->get('imageName')->getData()) {
                /** @var \Symfony\Component\HttpFoundation\File\UploadedFile $file */
                $file = $form['imageName']->getData();
                $destination = $this->getParameter('kernel.project_dir').'/public/uploads/user_images/';
                $originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
                $newFilename = $slugger->slug($originalFilename).'-'.uniqid().'.'.$file->guessExtension();
                $file->move(
                    $destination,
                    $newFilename
                );

                $user->setImageName($newFilename);
            }

            $msg = MessageFactory::createUser($admin, $user, 'Welcome', "Welcome to CM Tracker");

            $this->entityManager->persist($msg);
            $this->entityManager->persist($user);
            $this->entityManager->flush();

            $this->addFlash('success', 'User added successfully');

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

        $this->navLinks['user_list'] = NavList::PRESENT_LINK;

        return $this->render(
            'internal/admin/users/add-user.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'breadcrumbs' => [
                        new Breadcrumb($this->generateUrl('app_list_users'), 'User List'),
                        new Breadcrumb($this->generateUrl('app_add_user'), 'Add User')
                    ],
                    'form' => $form,
                    'notifications' => Libs::getMessages($admin, $this->entityManager),
                ]
            )
        );
    }

    #[Route('/edit-user/{id}', name: 'app_edit_user')]
    public function editUser(string $id, Request $request, #[CurrentUser()] User $admin): Response
    {
        /** @var UserRepository $userRepo */
        $userRepo = $this->entityManager->getRepository(User::class);

        /** @var User $user */
        $user = $userRepo->find($id);

        $form = $this->createForm(EditUserFormType::class, $user);
        $form->handleRequest($request);

        $this->navLinks['user_list'] = NavList::PRESENT_LINK;

        if ($form->isSubmitted() && $form->isValid()) {
            $roles = ['ROLE_USER'];
            if ($form->get('caseWorker')->getData()) {
                $roles[] = 'ROLE_CASE_WORKER';
            }

            if ($form->get('caseManager')->getData()) {
                $roles[] = 'ROLE_CASE_MANAGER';
            }

            if ($form->get('therapist')->getData()) {
                $roles[] = 'ROLE_THERAPIST';
            }

            if ($form->get('su')->getData()) {
                $roles[] = 'ROLE_ADMIN';
            }

            $user->setName($form->get('name')->getData())
                 ->setEmail($form->get('email')->getData())
                 ->setRoles($roles)
                 ->setActive((bool) $form->get('active')->getData())
                 ->setRateType($form->get('rateType')->getData())
                 ->setRate($form->get('rate')->getData())
                 ->setLevel($form->get('level')->getData())
            ;

            $this->entityManager->flush();

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

        return $this->render(
            'internal/admin/users/edit-user.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'breadcrumbs' => [
                        new Breadcrumb($this->generateUrl('app_list_users'), 'User List'),
                        new Breadcrumb($this->generateUrl('app_edit_user', ['id' => $id]), 'Edit User')
                    ],
                    'data' => $user,
                    'form' => $form,
                    'notifications' => Libs::getMessages($admin, $this->entityManager),
                ]
            )
        );
    }

    #[Route('/assign-supervisor/{id}', name: 'app_assign_supervisor')]
    public function assignSupervisor(string $id, Request $request, #[CurrentUser()] User $admin): Response
    {
        /** @var UserRepository $userRepo */
        $userRepo = $this->entityManager->getRepository(User::class);

        /** @var User $user */
        $user = $userRepo->find($id);
        $prevSup = $this->entityManager->getRepository(Supervision::class)->findOneBy(['worker' => $user]);

        $form = $this->createForm(SupervisorFormType::class);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            /** @var User $supervisor */
            $supervisor = $form->get('supervisor')->getData();
            if ($prevSup) {
                $prevSup->setSupervisor($supervisor);
                $this->entityManager->persist($prevSup);
                $this->entityManager->flush();
                $this->addFlash('success', "Supervisor updated for {$user->getName()}");
            } else {
                $sup = new Supervision();
                $sup->setWorker($user);
                $sup->setSupervisor($supervisor);

                $this->entityManager->persist($sup);
                $this->entityManager->flush();
                $this->addFlash('success', "Supervisor assigned to {$user->getName()}"); 
            }

            $supMsg = MessageFactory::createUser($admin, $supervisor, 'New Case Worker', "You've been assigned a new case worker, {$user->getName()}");
            $userMsg = MessageFactory::createUser($admin, $user, 'New Staff Supervisor', "You've been assigned a new staff supervisor {$supervisor->getName()}");

            $this->entityManager->persist($userMsg);
            $this->entityManager->persist($supMsg);
            $this->entityManager->flush();

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

        return $this->render(
            'internal/admin/assign-supervisor.html.twig',
            array_merge(
                $this->navLinks,
                [
                    'breadcrumbs' => [
                        new Breadcrumb($this->generateUrl('app_list_users'), 'User List'),
                        new Breadcrumb($this->generateUrl('app_assign_supervisor', ['id' => $id]), 'Assign Supervisor')
                    ],
                    'user' => $user,
                    'form' => $form,
                    'supervisors' => $userRepo->getCaseManagers($admin->getCompany()),
                    'notifications' => Libs::getMessages($admin, $this->entityManager),
                ]
            )
        );
    }
}
