<?php
declare(strict_types=1);

namespace App\Controller;

use App\Controller\AppController;
use Cake\I18n\FrozenTime;
use Cake\Event\EventInterface;
use Cake\Core\Configure;
use Cake\Utility\Inflector;
use Cake\Log\Log;
use Cake\Filesystem\File;
use Cake\Http\Exception\BadRequestException;
/**
 * Contents Controller
 *
 * @method \App\Model\Entity\Content[]|\Cake\Datasource\ResultSetInterface paginate($object = null, array $settings = [])
 */
class ContentsController extends AppController
{
    public function initialize(): void
    {
        parent::initialize();
        $this->loadModel('Contents');
        $this->loadModel('ContentImages');

        $this->loadComponent('Paginator');

        $this->paginate = [
            'limit' => 5
        ];
    }

    public function beforeRender(EventInterface $event)
    {
        parent::beforeRender($event);
    }

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

    /**
     * Index method
     *
     * @return \Cake\Http\Response|null|void Renders view
     */
    public function index()
    {
        Log::info('Starting index method.');
        $pageTitle = 'All Contents';

        $slug = $this->slug;

        // Retrieve the active menu from the slug
        $mc = $this->Menus->getMenuSlug($slug);

        $listingsQuery = $this->PageContents->getPageContents($mc);

        $listings = $this->paginate($listingsQuery);

        $this->set(compact('pageTitle', 'listings'));
    }

    /**
     * View method
     *
     * @param string|null $id Content id.
     * @return \Cake\Http\Response|null|void Renders view
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function view($id = null)
    {
        $content = $this->Contents->get($id, [
            'contain' => [],
        ]);

        $this->set(compact('content'));
    }

    /**
     * Add method
     *
     * @return \Cake\Http\Response|null|void Redirects on successful add, renders view otherwise.
     */
    public function add($id = null)
    {
        $images = [];
        $tagId = "";

        $parentMenus = $this->Menus->getparentMenu($id);

        $content = $this->Contents->newEmptyEntity();

        if ($this->request->is(['post'])) {
            $data = $this->request->getData();

            if (!empty($data['sbmenu_id'])) {
                $data['menu_id'] = $data['sbmenu_id'];
            } elseif (!empty($data['sbsbmenu_id'])) {
                $data['menu_id'] = $data['sbsbmenu_id'];
            } elseif (!empty($data['sbsbsbmenu_id'])) {
                $data['menu_id'] = $data['sbsbsbmenu_id'];
            } else {
                $data['menu_id'] = $data['pmenu_id'];
            }

            $data["parent_menu_id"] = $data['pmenu_id'];

            $content = $this->Contents->patchEntity($content, $data);
            if ($this->Contents->save($content)) {
                $pagecontent = $this->PageContents->newEmptyEntity();

                $data["content_id"] = $content->id;
                // Get the current time
                $currentTime = FrozenTime::now();
                $pc = $this->PageContents->find('All')->where(["menu_id" => $data["menu_id"], "content_id" => $data["content_id"]]);

                if (empty($pc->toArray())) {
                    $pagecontent = $this->PageContents->patchEntity($pagecontent, $data);
                    $this->PageContents->save($pagecontent);
                }

                //add images
               
                $imagesT = $this->getTableLocator()->get('ContentImages');

                if (isset($data['form_key']) && $data['form_key'] < 0) {
                    // pr($data['form_key']);exit;

                  $imagesT->updateAll(
                    [
                      'content_id' => $content->id
                    ],
                    [
                      'content_id' => $data['form_key']
                    ]
                  );
                }
                $this->Flash->success(__('Content added successfully.'));

                $section = $this->request->getParam('section');

                return $this->redirect([
                    'controller' => $section ? $this->request->getParam('section') :
                        $this->request->getParam('controller'),
                    'action' => 'pendingListings'
                ]);

            } else {
                $this->Flash->error(__('The row could not be save. Try again'));
            }
        }

        $menu_id = $id;
        $this->set(compact('parentMenus', 'content', 'images', 'menu_id'));
    }

    /**
     * Edit method
     * Edit specific content and handle related operations.
     *
     * @param int|null $id Parent Menu ID
     * @param int|null $cid Content ID
     * @param int|null $pcid Page Content ID
     * @return \Cake\Http\Response|null Redirects to the edited listings
     */
    public function edit($id = null, $cid = null, $pcid = null)
    {
        $pageTitle = 'Edited Contents';
        $parentMenus = $this->Menus->getparentMenu($id);
        $content = $this->Contents->get($cid);
        $images = $this->ContentImages->find('all')->where(['content_id' => $cid]);
        $subMenus = [];
        $content_sub_sub_menu_id = null;
        $content_sub_menu_id = null;

        if ($this->request->is(['post', 'put', 'patch'])) {
            $data = $this->request->getData();
            $data["status"] = 2;
            $data["content_id"] = $content->id;
            $sbmenu_id = $data["sbmenu_id"];
            $sbsbmenu_id = $data["sbsbmenu_id"];
            $sbsbsbmenu_id = $data["sbsbsbmenu_id"];
            $data["parent_menu_id"] = $data["pmenu_id"];
            $content = $this->Contents->patchEntity($content, $data);

            if ($this->Contents->save($content)) {

                $pageContent = $this->PageContents->find('all')->where(["content_id" => $data["content_id"]])->first();

                if ($pageContent) {
                    if (!empty($sbsbmenu_id)) {
                        $pageContent->menu_id = $sbsbmenu_id;
                    } elseif (!empty($sbmenu_id)) {
                        $pageContent->menu_id = $sbmenu_id;
                    } else {
                        $pageContent->menu_id = $id;
                    }

                    $this->PageContents->save($pageContent);
                } else {
                    throw new NotFoundException(__('Page content not found.'));
                }

                //add images
               
                $imagesT = $this->getTableLocator()->get('ContentImages');

                if (isset($data['form_key']) && $data['form_key'] < 0) {
                    // pr($data['form_key']);exit;

                  $imagesT->updateAll(
                    [
                      'content_id' => $content->id
                    ],
                    [
                      'content_id' => $data['form_key']
                    ]
                  );
                }
                
                $this->Flash->success(__('Content updated successfully.'));
                Log::info('Content ID ' . $content->id . ' updated successfully.');

                $section = $this->request->getParam('section');

                return $this->redirect([
                    'controller' => $section ? $this->request->getParam('section') :
                        $this->request->getParam('controller'),
                    'action' => 'editedListings'
                ]);

            }
        }

        // find the sub menu and sub sub menu of the selected content
        if ($pcid != null) {
            $selectedPage = ($pcid == null || $pcid == $id) ? null : $this->PageContents->find('all', [
                'conditions' => [
                    'PageContents.id' => $pcid
                ],
                'contain' => [
                    'Menus.ParentMenus'
                ]
            ])->first();

            if ($selectedPage != null && $selectedPage->menu != null && $selectedPage->menu->has('parent_menu')) {
                $parentMenu = $selectedPage->menu->parent_menu;

                // if($parentMenu->parent_menu_id != 0 && $parentMenu->parent_menu_id != $id) {
                if ($parentMenu->parent_menu_id != 0) {
                    $content_sub_menu_id = $parentMenu->id;
                    $content_sub_sub_menu_id = $selectedPage->menu_id;
                    $subMenus = $this->Menus->find('all')->where(['parent_menu_id' => $parentMenu->id])->combine('id', 'name');
                } else {
                    $content_sub_menu_id = $selectedPage->menu->id;
                    $subMenus = $this->Menus->find('all')->where(['parent_menu_id' => $selectedPage->menu_id])->combine('id', 'name');
                }
            } else {
                $content_sub_menu_id = $pcid;
            }
        }

        $menu_id = "";
        $this->set(compact('pageTitle', 'parentMenus', 'content', 'images', 'menu_id', 'content_sub_menu_id', 'content_sub_sub_menu_id', 'subMenus'));
    }

    /**
     * Delete method
     *
     * @param string|null $id Content id.
     * @return \Cake\Http\Response|null|void Redirects to index.
     * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found.
     */
    public function delete($id = null)
    {
        $this->request->allowMethod(['post', 'delete']);
        $content = $this->Contents->get($id);
        if ($this->Contents->delete($content)) {
            $this->Flash->success(__('The content has been deleted.'));
        } else {
            $this->Flash->error(__('The content could not be deleted. Please, try again.'));
        }

        return $this->redirect(['action' => 'index']);
    }

    public function enableListing($id = null)
    {
        // Check if ID is provided
        if ($id === null) {
            $this->Flash->error(__('Invalid content ID.'));
            return $this->redirect($this->referer());
        }

        try {
            // Attempt to update content status
            $result = $this->Contents->updateAll(['status' => 1], ['id' => $id]);

            // Check if any rows were updated
            if ($result) {
                $this->Flash->success(__('Content has been ENABLED successfully.'));
                Log::info('Content ID ' . $id . ' has been enabled successfully.');
            } else {
                throw new NotFoundException(__('Content not found or already enabled.'));
            }
        } catch (Exception $e) {
            // Log the error and set flash message
            Log::error('Error enabling content ID ' . $id . ': ' . $e->getMessage());
            $this->Flash->error(__('An error occurred while enabling the content.'));
        }

        // Redirect to the referring page
        return $this->redirect($this->referer());
    }

    /**
     * Disable listing for a specific content.
     *
     * @param int|null $id Content ID
     * @return \Cake\Http\Response|null Redirects to the referring page
     */
    public function disableListing($id = null)
    {
        // Check if ID is provided
        if ($id === null) {
            $this->Flash->error(__('Invalid content ID.'));
            return $this->redirect($this->referer());
        }

        try {
            // Attempt to update content status
            $result = $this->Contents->updateAll(['status' => 99], ['id' => $id]);

            // Check if any rows were updated
            if ($result) {
                $this->Flash->success(__('Content has been DISABLED successfully.'));
                Log::info('Content ID ' . $id . ' has been disabled successfully.');
            } else {
                throw new NotFoundException(__('Content not found or already disabled.'));
            }
        } catch (Exception $e) {
            // Log the error and set flash message
            Log::error('Error disabling content ID ' . $id . ': ' . $e->getMessage());
            $this->Flash->error(__('An error occurred while disabling the content.'));
        }

        // Redirect to the referring page
        return $this->redirect($this->referer());
    }

    /**
     * Show specific content on the homepage.
     *
     * @param int|null $id Content ID
     * @return \Cake\Http\Response|null Redirects to the referring page
     */
    public function showOnHome($id = null)
    {
        // Check if ID is provided
        if ($id === null) {
            $this->Flash->error(__('Invalid content ID.'));
            return $this->redirect($this->referer());
        }

        try {
            // Attempt to update the show_on_home status
            $result = $this->Contents->updateAll(['show_on_home' => 1], ['id' => $id]);

            // Check if any rows were updated
            if ($result) {
                $this->Flash->success(__('Content successfully shown on homepage.'));
                Log::info('Content ID ' . $id . ' is now shown on the homepage.');
            } else {
                throw new NotFoundException(__('Content not found or already shown on the homepage.'));
            }
        } catch (Exception $e) {
            // Log the error and set flash message
            Log::error('Error showing content ID ' . $id . ' on homepage: ' . $e->getMessage());
            $this->Flash->error(__('An error occurred while showing the content on the homepage.'));
        }

        // Redirect to the referring page
        return $this->redirect($this->referer());
    }

    /* Remove specific content from the homepage.
     *
     * @param int|null $id Content ID
     * @return \Cake\Http\Response|null Redirects to the referring page
     */
    public function removeFromHome($id = null)
    {
        // Check if ID is provided
        if ($id === null) {
            $this->Flash->error(__('Invalid content ID.'));
            return $this->redirect($this->referer());
        }

        try {
            // Attempt to update the show_on_home status
            $result = $this->Contents->updateAll(['show_on_home' => 0], ['id' => $id]);

            // Check if any rows were updated
            if ($result) {
                $this->Flash->success(__('Content removed from the homepage.'));
                Log::info('Content ID ' . $id . ' has been removed from the homepage.');
            } else {
                throw new NotFoundException(__('Content not found or already removed from the homepage.'));
            }
        } catch (Exception $e) {
            // Log the error and set flash message
            Log::error('Error removing content ID ' . $id . ' from homepage: ' . $e->getMessage());
            $this->Flash->error(__('An error occurred while removing the content from the homepage.'));
        }

        // Redirect to the referring page
        return $this->redirect($this->referer());
    }

    public function allListings($id = null)
    {
        $pageTitle = 'All Contents';
        $slug = $this->slug;

        try {
            Log::info("Starting allListings process for slug: $slug");

            // Retrieve the active menu from the slug
            $mc = $this->Menus->find()
                ->where(['Menus.slug' => $slug])
                ->first();

            if (!$mc) {
                Log::warning("Menu not found for slug: $slug");
                throw new NotFoundException(__('Menu not found for the given slug.'));
            }
            Log::info("Menu found");

            // Find all listings containing related content and menus
            $listings = $this->PageContents->find()
                ->contain([
                    'Contents.ContentImages',
                    'Menus.ParentMenus'
                ])
                ->where([
                    'OR' => [
                        ['Menus.slug' => $slug],
                        ['ParentMenus.slug' => $slug],
                        ['ParentMenus.parent_menu_id' => $mc->id]
                    ]
                ])
                ->order([
                    'Menus.name' => 'ASC',
                    'Contents.id' => 'DESC'
                ]);

            Log::info("Listings query constructed successfully");

            // Paginate the listings
            $listings = $this->paginate($listings);
            Log::info("Listings paginated successfully");

            $this->set(compact('pageTitle', 'listings'));
            Log::info("View variables set successfully");


        } catch (NotFoundException $e) {
            // Specific handling for not found exception
            Log::warning('Menu not found: ' . $e->getMessage());
            $this->Flash->error($e->getMessage());
            return $this->redirect(['action' => 'index']);
        }

        Log::info("allListings process completed for slug: $slug");
        $this->viewBuilder()->setTemplatePath('element/sessions')->setTemplate('all_listings');
    }

    public function pendingListings($id = null)
    {
        $pageTitle = 'Pending Contents';
        $slug = $this->slug;

        try {
            Log::info("Starting allListings process for slug: $slug");

            // Retrieve the active menu from the slug
            $mc = $this->Menus->find()
                ->where(['Menus.slug' => $slug])
                ->first();

            if (!$mc) {
                Log::warning("Menu not found for slug: $slug");
                throw new NotFoundException(__('Menu not found for the given slug.'));
            }
            Log::info("Menu found");

            // Find all listings containing related content and menus
            $listings = $this->PageContents->find()
                ->contain([
                    'Contents.ContentImages',
                    'Menus.ParentMenus'
                ])
                ->where([
                    'Contents.status' => 0,
                    'OR' => [
                        ['Menus.slug' => $slug],
                        ['ParentMenus.slug' => $slug],
                        ['ParentMenus.parent_menu_id' => $mc->id]
                    ]
                ])
                ->order([
                    'Menus.name' => 'ASC',
                    'Contents.id' => 'DESC'
                ]);

            Log::info("Listings query constructed successfully");

            // Paginate the listings
            $listings = $this->paginate($listings);
            Log::info("Listings paginated successfully");

            $this->set(compact('pageTitle', 'listings'));
            Log::info("View variables set successfully");


        } catch (NotFoundException $e) {
            // Specific handling for not found exception
            Log::warning('Menu not found: ' . $e->getMessage());
            $this->Flash->error($e->getMessage());
            return $this->redirect(['action' => 'index']);
        }

        Log::info("allListings process completed for slug: $slug");
        $this->viewBuilder()->setTemplatePath('element/sessions')->setTemplate('pending_listings');
    }

    /**
     * Enable listings based on the provided slug.
     *
     * @param int|null $id Optional parameter for additional filtering
     * @return \Cake\Http\Response|null Renders the view
     */
    public function enableListings($id = null)
    {
        $pageTitle = 'Enabled Contents';
        $slug = $this->slug;

        try {
            Log::info("Starting enableListings process for slug: $slug");

            // Retrieve the active menu from the slug
            $mc = $this->Menus->find()
                ->where(['Menus.slug' => $slug])
                ->first();

            if (!$mc) {
                Log::warning("Menu not found for slug: $slug");
                throw new NotFoundException(__('Menu not found for the given slug.'));
            }
            Log::info("Menu found: " . json_encode($mc));

            // Find all listings containing related content and menus
            $listings = $this->PageContents->find()
                ->contain([
                    'Contents.ContentImages',
                    'Menus.ParentMenus'
                ])
                ->where([
                    'Contents.status' => 1,
                    'OR' => [
                        ['Menus.slug' => $slug],
                        ['ParentMenus.slug' => $slug],
                        ['ParentMenus.parent_menu_id' => $mc->id]
                    ]
                ])
                ->order([
                    'Menus.name' => 'ASC',
                    'Contents.name' => 'ASC'
                ]);

            Log::info("Listings query constructed successfully");

            // Paginate the listings
            $listings = $this->paginate($listings);
            Log::info("Listings paginated successfully");

            $this->set(compact('pageTitle', 'listings'));
            Log::info("View variables set successfully");

        } catch (NotFoundException $e) {
            // Specific handling for not found exception
            Log::warning('Menu not found: ' . $e->getMessage());
            $this->Flash->error($e->getMessage());
            return $this->redirect(['action' => 'index']);
        }
        Log::info("enableListings process completed for slug: $slug");
        $this->viewBuilder()->setTemplatePath('element/sessions')->setTemplate('enable_listings');
    }

    /**
     * Disable listings based on the provided slug.
     *
     * @param int|null $id Optional parameter for additional filtering
     * @return \Cake\Http\Response|null Renders the view
     */
    public function disableListings($id = null)
    {
        $pageTitle = 'Disabled Contents';
        $slug = $this->slug;

        try {
            Log::info("Starting disableListings process for slug: $slug");

            // Retrieve the active menu from the slug
            $mc = $this->Menus->find()
                ->where(['Menus.slug' => $slug])
                ->first();

            if (!$mc) {
                Log::warning("Menu not found for slug: $slug");
                throw new NotFoundException(__('Menu not found for the given slug.'));
            }
            Log::info("Menu found: " . json_encode($mc));

            // Find all listings containing related content and menus
            $listings = $this->PageContents->find()
                ->contain([
                    'Contents.ContentImages',
                    'Menus.ParentMenus'
                ])
                ->where([
                    'Contents.status' => 99,
                    'OR' => [
                        ['Menus.slug' => $slug],
                        ['ParentMenus.slug' => $slug],
                        ['ParentMenus.parent_menu_id' => $mc->id]
                    ]
                ])
                ->order([
                    'Menus.name' => 'ASC',
                    'Contents.name' => 'ASC'
                ]);

            Log::info("Listings query constructed successfully");

            // Paginate the listings
            $listings = $this->paginate($listings);
            Log::info("Listings paginated successfully");

            $this->set(compact('pageTitle', 'listings'));
            Log::info("View variables set successfully");

        } catch (NotFoundException $e) {
            // Specific handling for not found exception
            Log::warning('Menu not found: ' . $e->getMessage());
            $this->Flash->error($e->getMessage());
            return $this->redirect(['action' => 'index']);
        }
        Log::info("disableListings process completed for slug: $slug");
        $this->viewBuilder()->setTemplatePath('element/sessions')->setTemplate('disable_listings');
    }

    /**
     * List edited contents based on the provided slug.
     *
     * @param int|null $id Optional parameter for additional filtering
     * @return \Cake\Http\Response|null Renders the view
     */
    public function editedListings($id = null)
    {
        $pageTitle = 'Edited Contents';
        $slug = $this->slug;

        try {
            Log::info("Starting editedListings process for slug: $slug");

            // Retrieve the active menu from the slug
            $mc = $this->Menus->find()
                ->where(['Menus.slug' => $slug])
                ->first();

            if (!$mc) {
                Log::warning("Menu not found for slug: $slug");
                throw new NotFoundException(__('Menu not found for the given slug.'));
            }
            Log::info("Menu found: " . json_encode($mc));

            // Find all listings containing related content and menus
            $listings = $this->PageContents->find()
                ->contain([
                    'Contents.ContentImages',
                    'Menus.ParentMenus'
                ])
                ->where([
                    'Contents.status' => 2,
                    'OR' => [
                        ['Menus.slug' => $slug],
                        ['ParentMenus.slug' => $slug],
                        ['ParentMenus.parent_menu_id' => $mc->id]
                    ]
                ])
                ->order([
                    'Menus.name' => 'ASC',
                    'Contents.name' => 'ASC'
                ]);

            Log::info("Listings query constructed successfully");

            // Paginate the listings
            $listings = $this->paginate($listings);
            Log::info("Listings paginated successfully");

            $this->set(compact('pageTitle', 'listings'));
            Log::info("View variables set successfully");

        } catch (NotFoundException $e) {
            // Specific handling for not found exception
            Log::warning('Menu not found: ' . $e->getMessage());
            $this->Flash->error($e->getMessage());
            return $this->redirect(['action' => 'index']);
        }
        Log::info("editedListings process completed for slug: $slug");
        $this->viewBuilder()->setTemplatePath('element/sessions')->setTemplate('edited_listings');
    }

    /**
     * Remove an image based on the provided ID.
     *
     * @param int|null $id The ID of the image to remove
     * @return \Cake\Http\Response|null Returns a JSON response indicating success or failure
     */

    public function removeImage($id = null)
    {
        $this->autoRender = false;
        //  $this->viewBuilder()->setLayout();

        $this->log('Ajax request received for Image removal', 'debug');
        $imageModel = $this->ContentImages;
        $imageItem = $imageModel->get($id);
        $this->log('image id to remove: ' . $imageItem->image_path, 'debug');
        $status = "Fail";

        if ($imageModel->delete($imageItem)) {
            $this->response = $this->response->withStatus(200);
            $status = "Success";
        } else {
            $this->response = $this->response->withStatus(500);
        }

        echo json_encode(array($status));
    }


    public function addImage($id = null)
    {
        $this->autoRender = false;
        if ($this->request->is(['post'])) {
            $file = $this->request->getData('file');

            // Check if the file was uploaded successfully
            if ($file && $file->getError() === UPLOAD_ERR_OK) {
                $filename = $file->getClientFilename();

                // Attempt to upload file
                $fileOK = $this->uploadFiles(Configure::read('IMAGE_PREPATH'), $file);

                if (!empty($fileOK['urls']) && !empty($fileOK['file_path'][0])) {

                    // Create a new entity
                    $image = $this->ContentImages->newEmptyEntity();

                    // Set additional properties
                    $image->content_id = $id;

                    $image->image_path = substr($fileOK['file_path'][0], Configure::read('IMAGE_PRELENGTH'), strlen($fileOK['file_path'][0]));


                    // Try to save entity and log result
                    if ($this->ContentImages->save($image)) {
                        $this->log('Successfully uploaded and saved image', 'debug');
                    } else {
                        // Log errors if saving fails
                        $this->log('Image save failed: ' . json_encode($image->getErrors()), 'debug');
                        $this->response = $this->response->withStatus(403);
                        echo 'Failed to save image in database';
                    }
                } else {
                    $this->log('File upload failed or file path is missing', 'debug');
                    echo 'Failed to upload file';
                }
            } else {
                $this->log('No file uploaded or file upload error', 'debug');
                echo 'No file uploaded';
            }

        }

    }


}
