<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Form\Extension\Core\Type as FormType;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Doctrine\ORM\EntityManagerInterface;

use App\Controller\WebrootSetupController;
use App\Entity\WebrootUser;
use App\Entity\WebrootRole;
use App\Entity\WebrootFile;
use App\Entity\WebrootFilePermission;


class SetupController extends WebrootSetupController
{   
    #[Route('/setup/initial',name:'webroot.initial-setup')]
    public function initialSetup(Request $request,
            EntityManagerInterface $em,
            UserPasswordHasherInterface $passwd_hasher): Response
    {
        
        $lang= getenv("LANG");
        $dotenv_file = join(DIRECTORY_SEPARATOR,[$this->getProjectDir(),".env"]);
        $dotenvlocal_file = join(DIRECTORY_SEPARATOR,[$this->getProjectDir(),".env.local"]);
        $errors = [];
        $debug=null;
        if (!file_exists($dotenv_file)) {
            $file = fopen($dotenv_file, "w", false);
            fclose($file);
        }
        
        $translations=[
            'email'=>$this->trans("setupform.section.email",domain:"mydevel.webroot.setup"),
            'site' => $this->trans("setupform.section.site",domain:"mydevel.webroot.setup"),
            'db' => $this->trans("setupform.section.database",domain:"mydevel.webroot.setup"),
            'user' => $this->trans("setupform.section.user",domain:"mydevel.webroot.setup"),
            'title' => $this->trans("setupform.title",domain:"mydevel.webroot.setup"),
        ];
        
        $form = $this->createSetupForm();
        $this->setSetupFormDefaultsFromEnv($form);
        if ($this->hasInitialSetupDataCookie($request)) {
            $data = $this->getDataFromInitialSetupDataCookie($request);
            if ($data) {
                $this->setSetupFormFromData($form, $data);
            }
        }
        
        $form->handleRequest($request);
        
        if ($form->isSubmitted() && $form->isValid()) {
            $password0 = $form->get('user_password0')->getData();
            $password1 = $form->get('user_password1')->getData();
            if (strlen($password0) < 8) {
                array_push($errors,"Password does not have the minimal length of 8 characters!");
            }
            if (strcmp($password0,$password1)) {
                array_push($errors,"Passwords dont match!");
            }
            
            //if passwords don't match rerender form.
            if (count($errors) > 0) {
                return $this->render("setup/initial-setup.html.twig",[
                        "errors" => $errors,
                        "form" => $form,
                        "translations" => $translations,
                        "have_migration_output"=>false,
                ]);
            }
            $response = $this->redirectToRoute("webroot.initial-setup.run",['step'=>0]);
            $this->setInitialSetupDataCookie($request,$form,$response);
            $this->writeDotEnvLocal($this->getDataFromSetupForm($form),true);
            (new Dotenv())->loadEnv(join(DIRECTORY_SEPARATOR,[$this->getProjectDir(),".env"]));
            return $response;         
        }
        foreach ($form->getErrors() as $error) {
            $errors[] = $error;
        }
        return $this->render('setup/initial-setup.html.twig', [
            "form" => $form,
            "errors" => $errors,
            "translations" => $translations,
            "have_migration_output"=>true,
        ]);
    }
    
    #[Route('/setup', name: 'webroot.setup')]
    public function setup(): Response
    {
        if (!$this->isInstalled()) {
            return $this->redirectToRoute('webroot.initial-setup');
        }
        
        if (!$this->userIsLoggedInAsAdmin()) {
            return $this->redirectToRoute("app_login");
        }
        
        return $this->render('setup/controller.html.twig', [
            'controller_name' => "WebrootController",
            'function' => __FUNCTION__,
        ]);
    }
    
    #[ROUTE('/setup/initial/run/{step}',name:'webroot.initial-setup.run')]
    public function setupInitialRun(Request $request,int $step) : Response
    {
        if (!$this->hasInitialSetupDataCookie($request)) {
            return new AccessDeniedHttpException();
        }
        
        $output = "";
        
        $data= $this->getDataFromInitialSetupDataCookie($request);
        $commands=$data["__commands__"];
        $error=null;
        
        if ($step >= count($commands)) {
            return $this->redirectToRoute("app_login");
        }
        $status="SUCCESS";
        $status_message=$this->trans("command.success",domain:"mydevel.webroot.setup");
        
        if ($commands[$step] === "create-database") {
            $output = $this->trans("command.createdb",domain:"mydevel.webroot.setup");
            try {
                $this->runCreateDatabase();
                $status="SUCCESS";
            } catch (\Exception $ex) {
                $status = "FAILED";
                $status_message = $this->translate("command.failed",domain:"mydevel.webroot.setup");
                $error = $ex->getMessage();
            } catch (\Throwable $ex) {
              $status = "FAILED";
              if (function_exists([$ex,'getMessage'])) {
                  $error=$ex->getMessage();
              }
              $status_message = $this->trans("command.failed",domain:"mydevel.webroot.setup");                
            }
        } elseif ($commands[$step] === "make-migrations") {
            $output = $this->trans("command.makemigrations",domain:"mydevel.webroot.setup");
            try {
                $this->runMakeMigration();
            } catch (\Exception $ex) {
                $status = "FAILED";
                $status_message = $this->translate("command.failed",domain:"mydevel.webroot.setup");
                $error = $ex->getMessage();
            } catch (\Throwable $ex) {
                $status = "FAILED";
                $status_message = $this->trans("command.success",domain:"mydevel.webroot.setup");
            }                
        } elseif ($commands[$step] === "migrate") {
            $output = $this->trans("command.migrate",domain:"mydevel.webroot.setup");
            try {
                $this->runMigrate();
            } catch (\Exception $ex) {
                $status = "FAILED";
                $status_message = $this->translate("command.failed",domain:"mydevel.webroot.setup");
                $error = $ex->getMessage();
            } catch (\Throwable $ex) {
                $status_message = $this->trans("command.failed",domain:"mydevel.webroot.setup");
                $status = "FAILED";
            }                
        } elseif ($commands[$step] === "populate-database") {
            $output = $this->trans("command.populatedb",domain:"mydevel.webroot.setup");
            try {
                $this->addRoles();
                $this->addAdministrator($data);
                $this->addRootDir($data);
                $status = "SUCCESS";
                $status_message = $this->trans("command.success",domain:"mydevel.webroot.setup");
            } catch (\Exception $ex) {
                $status = "FAILED";
                $status_message = $this->translate("command.failed",domain:"mydevel.webroot.setup");
                $error = $ex->getMessage();
            } catch (\throwable $ex) {
                $status_message = $this->trans("command.failed");
                $status = "FAILED";                
            }
        } else {
            $output = "Unknown command \"" . $commands[$step] . "\"";
            $status = "FAILED";
            $status_message = $status_message = $this->trans("command.failed",domain:"mydevel.webroot.setup");
        }
        
        return $this->render('setup/initial-setup.run.html.twig', [
            'setup_url' => $this->generateUrl("webroot.initial-setup"),
            'next_url' => $this->generateUrl("webroot.initial-setup.run",['step'=>($step + 1)]),
            'status' => $status,
            'status_message' => $status_message,
            'output' => $output,
            'error' => $error,
            'failed_button' => $this->trans("button.return-setup",domain:"mydevel.webroot.setup"),
        ]);
    }
    
    #[ROUTE('/setup/initial/end',name:'webroot.initial-setup.end')]
    public function setupInitialReset(Request $request): Response
    {
        if (!$this->hasInitialSetupDataCookie($request)) {
            throw new AccessDeniedHttpException();
        }
        unlink(join(DIRECTORY_SEPARATOR,[$this->getProjectDir(),'.env.local']));
        $this->redirectToRoute('webroot.initial-setup');
    }
}
