<?php
declare(strict_types=1);

/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link      https://cakephp.org CakePHP(tm) Project
 * @since     0.2.9
 * @license   https://opensource.org/licenses/mit-license.php MIT License
 */
namespace App\Controller;

use Cake\Controller\Controller;
use Cake\Event\EventInterface;
use Cake\ORM\TableRegistry;
use Cake\Utility\Inflector;
use Cake\Utility\Text;
use Cake\Core\Configure;
use Cake\Controller\Exception\SecurityException;
use Cake\Routing\Router;
use Cake\Log\Log;
use Laminas\Diactoros\UploadedFile;


/**
 * Application Controller
 *
 * Add your application-wide methods in the class below, your controllers
 * will inherit them.
 *
 * @link https://book.cakephp.org/4/en/controllers.html#the-app-controller
 */
class AppController extends Controller
{
    /**
     * Initialization hook method.
     *
     * Use this method to add common initialization code like loading components.
     *
     * e.g. `$this->loadComponent('FormProtection');`
     *
     * @return void
     */
    public function initialize(): void
    {
        parent::initialize();

        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');
        // $this->loadComponent('security');
        $this->loadComponent('RequestHandler');
        $this->loadComponent('Flash');
        /*
         * Enable the following component for recommended CakePHP form protection settings.
         * see https://book.cakephp.org/4/en/controllers/components/form-protection.html
         */
        // $this->loadComponent('FormProtection');
        $this->loadComponent('Authentication.Authentication');

        $this->loadModel('Menus');
        $this->loadModel('Contents');
        $this->loadModel('PageContents');
        $this->loadModel('ContentImages');
        $this->loadModel('AppSettings');
    }

    public function beforeFilter(EventInterface $event)
    {
        parent::beforeFilter($event);

        $this->Authentication->allowUnauthenticated(['addImage']);

        $this->response = $this->response->withHeader('Feature-Policy', "geolocation 'self'");

        $response = $this->response->withHeader(
            'Content-Security-Policy',
            "require-trusted-types-for 'script';"
        );

        $this->response = $this->response->withHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');

        // Set the Referrer Policy header
        $this->response = $this->response->withHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
    }

    

    public function isAuthorized($user)
    {
        $action = $this->request->getParam('action');
        return true;
    }

    public function slugController()
    {
        $slug = null;
        // Get the request URL path
        $urlPath = $this->request->getPath();

        if (!empty($urlPath)) {
            $urlArray = explode("/", trim($urlPath, "/"));
            $slug = $urlArray[0];
        }
        return $slug;
    }

    public function slugSubController()
    {
        $slugsub = null;
        if (!empty($this->request->url)) {
            $urlArray = explode("/", $this->request->url);
            if (isset($urlArray[1])) {
                if ($urlArray[1] == "sub")
                    $slugsub = $urlArray[2];
            }
        }
        return $slugsub;
    }

    public function beforeRender(EventInterface $event)
    {
        $this->getMenu();

        $slug = $this->slugController();

        $mmenu = $this->Menus->getMenuSlug($slug);
        $slugsub = $this->slugSubController();

        $menuitemid = null;
        $menuitemname = null;

        if ($slugsub !== null) {
            $submmenu = $this->Menus->getMenuSlug($slugsub);
            if ($submmenu) {
                $menuitemid = $submmenu->id;
                $menuitemname = $mmenu ? $mmenu->name . ' > ' . $submmenu->name : $submmenu->name;
            }
        } elseif ($mmenu) {
            $menuitemid = $mmenu->id;
            $menuitemname = $mmenu->name;
        }

        $this->set(compact('menuitemname', 'menuitemid', 'slug', 'slugsub'));

        // Fetch the nonce and pass it to the view globally
        $this->set('styleNonce', $this->request->getAttribute('cspStyleNonce'));

        // Fetch the nonce and pass it to the view globally
        $this->set('scriptNonce', $this->request->getAttribute('cspScriptNonce'));
    }

    public function getmenu()
    {
        $menus = [];

        $mainMenus = $this->Menus->getMainMenu();

        foreach ($mainMenus as $menu) {
            $submenu = [];

            $subob = $this->Menus->getSubmenus($menu->id);

            if (!is_null($subob)) {

                foreach ($subob as $sub) {
                    array_push($submenu, [$sub->id, $sub->slug, $sub->name]);
                }
            }

            array_push($menus, [[$menu->id, $menu->slug, $menu->name], $submenu]);
        }

        $this->set(compact('menus'));
    }
    public function uploadImage($folder, $file, $itemId = null, $uploadType = null, $compress = true)
    {
        // setup dir names absolute and relative
        $folder_url = WWW_ROOT . $folder;
        $rel_url = $folder;

        // create the folder if it does not exist
        if (!is_dir($folder_url)) {
            mkdir($folder_url);
        }

        // if itemId is set create an item folder
        if ($itemId) {
            // set new absolute folder
            $folder_url = WWW_ROOT . $folder . '/' . $itemId;
            // set new relative folder
            $rel_url = $folder . '/' . $itemId;
            // create directory
            if (!is_dir($folder_url)) {
                mkdir($folder_url);
            }
        }

        // list of permitted file types : pictures and vidoes
        $permitted = array('image/jpeg', 'image/pjpeg', 'image/png');
        if ($uploadType == 3) {
            array_push($permitted, 'application/pdf');
        }
        $result = array();

        // replace spaces with underscores
        // $filename = str_replace(' ', '_', $file['name']);
        $filename = str_replace(' ', '_', $file->getClientFilename());

        // assume filetype is false


        $typeOK = false;
        // check filetype is ok
        // foreach ($permitted as $type) {
        //     if ($type == $file['type']) {
        //         $typeOK = true;
        //         break;
        //     }
        // }
        $fileType = $file->getClientMediaType();
        if (in_array($fileType, $permitted)) {
            $typeOK = true;
        }

        if (in_array($file['type'], array('image/jpeg', 'image/pjpeg')))
            $source = imagecreatefromjpeg($file['tmp_name']);
        else if (in_array($file['type'], array('image/png')))
            $source = imagecreatefrompng($file['tmp_name']);

        // if file type ok upload the file
        if ($typeOK) {
            // switch based on error code
            switch ($file['error']) {
                case 0:
                    // create unique filename and upload file
                    ini_set('date.timezone', 'Europe/London');
                    $now = date('Y-m-d-His');
                    $full_url = $folder_url . '/' . $now . $filename;
                    $url = $rel_url . '/' . $now . $filename;
                    $thumb_url = $rel_url . '/thumb_' . $now . $filename;

                    // upload the image right away is the size is less than 50kb

                    if ($file['size'] < 50000 || $compress == false) {

                        $success = move_uploaded_file($file['tmp_name'], $url);

                    } else {

                        // resize
                        list($width, $height) = getimagesize($file['tmp_name']);
                        $aspectRatio = $height / $width;
                        $newHeight = $height;
                        $newWidth = $width;

                        if ($aspectRatio == 0.75) {
                            $newWidth = 800;
                            $newHeight = 600;
                        } else if ($aspectRatio < 0.75) {
                            if ($width >= 800) {
                                $newRatio = $width / 800;
                                $newWidth = 800;
                                $newHeight = $height / $newRatio;
                            }
                        } else if ($aspectRatio > 0.75) {
                            if ($height >= 600) {
                                $newRatio = $height / 600;
                                $newHeight = 600;
                                $newWidth = $width / $newRatio;
                            }
                        }



                        $thumb = imagecreatetruecolor($newWidth, $newHeight);

                        imagecopyresized($thumb, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

                        // save resized with compression
                        if (in_array($file['type'], array('image/jpeg', 'image/pjpeg'))) {
                            $success = imagejpeg($thumb, $url, 75);


                        } else if (in_array($file['type'], array('image/png'))) {
                            //make image   transpanrent
                            imagesavealpha($thumb, true);
                            $color = imagecolorallocatealpha($thumb, 0, 0, 0, 127);
                            imagefill($thumb, 0, 0, $color);

                            $success = imagepng($thumb, $url, 7, PNG_ALL_FILTERS);
                            //create thumbnail image

                        }

                        //free up memory
                        imagedestroy($thumb);
                    }

                    // if upload was successful
                    if ($success) {

                        // save the url of the file
                        $result['urls'][] = $url;
                        $result['file_type'][] = $file['type'];
                        $result['name'][] = $file['name'];
                        $result['size'][] = $file['size'];
                        $result['file_path'][] = $url;

                    } else {
                        $result['errors'][] = "Error uploaded $filename. Please try again.";
                    }
                    break;
                case 3:
                    // an error occured
                    $result['errors'][] = "Error uploading $filename. Please try again.";
                    break;
                default:
                    // an error occured
                    $result['errors'][] = "System error uploading $filename. Contact webmaster.";
                    break;
            }
        } elseif ($file['error'] == 4) {
            // no file was selected for upload
            $result['nofiles'][] = "No file Selected";
        } else {
            // unacceptable file type
            $result['errors'][] = "$filename cannot be uploaded. Acceptable file types: gif, jpg, png.";
        }

        return $result;
    }
    public function uploadFiles($folder, UploadedFile $file, $itemId = null)
    {
        // Setup directory paths
        $folder_url = WWW_ROOT . $folder;
        $rel_url = $folder;

        // Create the folder if it does not exist
        if (!is_dir($folder_url)) {
            mkdir($folder_url, 0755, true);
        }

        // If itemId is set, create an item-specific folder
        if ($itemId) {
            $folder_url = $folder_url . DS . $itemId;
            $rel_url = $rel_url . DS . $itemId;
            if (!is_dir($folder_url)) {
                mkdir($folder_url, 0755, true);
            }
        }

        // Get the list of permitted file types from configuration
        $permitted = Configure::read('SUPPORTED_EXTENSIONS');
        $result = [];

        // Replace spaces with underscores in the filename
        $filename = str_replace(' ', '_', $file->getClientFilename());
        // Assume file type is not okay
        $typeOK = false;
        // Check if file type is permitted
        $fileType = $file->getClientMediaType();
        if (in_array($fileType, $permitted)) {
            $typeOK = true;
        }

        // If file type is okay, attempt to upload the file
        if ($typeOK) {
            switch ($file->getError()) {
                case UPLOAD_ERR_OK:
                    // Create unique filename and upload file
                    $now = date('Y-m-d-His');
                    $full_url = $folder_url . DS . $now . '_' . $filename;
                    // $url = $rel_url . DS . $now . '_' . $filename;
                    $url = $rel_url . $now . '_' . $filename;


                    // Move the uploaded file to the target directory
                    $file->moveTo($full_url);

                    // Check if the file was successfully moved
                    if (file_exists($full_url)) {
                        $result['urls'][] = $url;
                        $result['file_type'][] = $file->getClientMediaType();
                        $result['name'][] = $file->getClientFilename();
                        $result['size'][] = $file->getSize();
                        $result['file_path'][] = $url;
                    } else {
                        $result['errors'][] = "Error uploading $filename. Please try again.";
                    }
                    break;

                case UPLOAD_ERR_NO_FILE:
                    // No file was selected for upload
                    $result['nofiles'][] = "No file selected";
                    break;

                default:
                    // Handle other upload errors
                    $result['errors'][] = "System error uploading $filename. Contact webmaster.";
                    break;
            }
        } else {
            // Unacceptable file type
            $result['errors'][] = "$filename cannot be uploaded. Acceptable file types: " . implode(', ', $permitted);
        }

        return $result;
    }


}
