<?php
declare(strict_types=1);

namespace App\Controller;

use Cake\Utility\Text;
use Laminas\Diactoros\UploadedFile;
use Cake\Datasource\Exception\RecordNotFoundException;

/**
 * Product Controller
 *
 * @property \App\Model\Table\ProductTable $Product
 */
class ProductController extends AppController
{
    public function initialize(): void
    {
        parent::initialize();
        $this->loadComponent('Flash');
    }

    /**
     * Utility method to restrict access to admin only
     */
    private function requireAdmin()
    {
        $user = $this->request->getSession()->read('Auth.User');
        if (empty($user) || empty($user->is_admin) || $user->is_admin !== 1) {
            $this->Flash->error('Access denied. Admins only.');
            return $this->redirect('/');
        }
        return null;
    }

    /**
     * Index method – visible to everyone
     */
    public function index()
    {
        $query = $this->Product->find();
        $product = $this->paginate($query);

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

    /**
     * View method – visible to everyone
     */
    public function view($id = null)
    {
        // Validate if $id is a valid integer
        if (!is_numeric($id) || !preg_match('/^\d+$/', $id)) {
            $this->Flash->error(__('Invalid product ID.'));
            return $this->redirect(['controller' => 'Pages', 'action' => 'error']);
        }

        try {
            $product = $this->Product->get($id, ['contain' => ['Ratings']]);
            $this->set(compact('product'));
        } catch (RecordNotFoundException $e) {
            $this->Flash->error(__('Product not found.'));
            return $this->redirect(['controller' => 'Pages', 'action' => 'error']);
        }
    }

    /**
     * Add method – now visible to everyone
     */
    public function add()
    {
        $product = $this->Product->newEmptyEntity();

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

            // Handle image upload
            if ($image instanceof UploadedFile && $image->getError() === UPLOAD_ERR_OK) {
                $filename = Text::uuid() . '-' . $image->getClientFilename();
                $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

                if (in_array($ext, ['jpg', 'jpeg', 'png'])) {
                    $uploadPath = WWW_ROOT . '/img/products/';

                    if (!is_dir($uploadPath)) {
                        mkdir($uploadPath, 0775, true);
                    }

                    // Move the uploaded image to the correct folder
                    $image->moveTo($uploadPath . $filename);
                    $data['image_url'] = '/img/products/' . $filename;
                } else {
                    $this->Flash->error(__('Invalid file type. Only JPG and PNG allowed.'));
                    return $this->redirect($this->referer());
                }
            } else {
                $this->Flash->error(__('No image was uploaded or upload failed.'));
            }

            // Save product data
            $product = $this->Product->patchEntity($product, $data);

            if ($this->Product->save($product)) {
                $this->Flash->success(__('The product has been saved.'));
                return $this->redirect(['action' => 'index']);
            }

            $this->Flash->error(__('The product could not be saved. Please try again.'));
        }

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

    /**
     * Edit method – now visible to everyone
     */
    public function edit($id = null)
    {
        if (!is_numeric($id)) {
            $this->Flash->error(__('Invalid product ID.'));
            return $this->redirect(['action' => 'index']);
        }

        try {
            $product = $this->Product->get($id);
        } catch (RecordNotFoundException $e) {
            $this->Flash->error(__('Product not found.'));
            return $this->redirect(['action' => 'index']);
        }

        if ($this->request->is(['patch', 'post', 'put'])) {
            $data = $this->request->getData();
            $image = $data['image_file'] ?? null;

            // Handle optional image upload
            if ($image instanceof UploadedFile && $image->getError() === UPLOAD_ERR_OK) {
                $filename = Text::uuid() . '-' . $image->getClientFilename();
                $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

                if (in_array($ext, ['jpg', 'jpeg', 'png'])) {
                    $uploadPath = WWW_ROOT . '/img/products/';
                    if (!is_dir($uploadPath)) {
                        mkdir($uploadPath, 0775, true);
                    }

                    $image->moveTo($uploadPath . $filename);
                    $data['image_url'] = '/img/products/' . $filename;

                    // Delete old image if one exists
                    if (!empty($product->image_url) && file_exists(WWW_ROOT . $product->image_url)) {
                        unlink(WWW_ROOT . $product->image_url);
                    }
                } else {
                    $this->Flash->error(__('Invalid file type. Only JPG and PNG allowed.'));
                    return $this->redirect($this->referer());
                }
            }

            // Patch and save
            $this->Product->patchEntity($product, $data);
            if ($this->Product->save($product)) {
                $this->Flash->success(__('The product has been updated.'));
                return $this->redirect(['action' => 'index']);
            }

            $this->Flash->error(__('The product could not be updated. Please try again.'));
        }

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

    /**
     * Delete method – admin only
     */
    public function delete($id = null)
    {
        
        /**
        $redirect = $this->requireAdmin();
        if ($redirect) {
            $this->Flash->error(__('Admin access only.'));
            return $redirect;
        }**/

        
        $this->request->allowMethod(['post', 'delete']);
        
        $product = $this->Product->get($id);
        if ($this->Product->delete($product)) {
            $this->Flash->success(__('The product has been deleted.'));
        } else {
            $this->Flash->error(__('The product could not be deleted. Please, try again.'));
        }

        /**
        if (!is_numeric($id) || !preg_match('/^\d+$/', $id)) {
            $this->Flash->error(__('Invalid product ID.'));
            return $this->redirect(['action' => 'index']);
        }

        $this->loadModel('Products');

        try {
            $product = $this->Product->get($id);
        } catch (RecordNotFoundException $e) {
            $this->Flash->error(__('Product not found.'));
            return $this->redirect(['action' => 'index']);
        }

        if ($this->Products->delete($product)) {
            $this->Flash->success(__('The product has been deleted.'));
        } else {
            $this->Flash->error(__('The product could not be deleted. Please try again.'));
        }
        **/

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

    /**
     * Update stock – admin only
     */
    public function updateStock($id = null)
    {
        // Check if the user is an admin
        $redirect = $this->requireAdmin();
        if ($redirect) return $redirect;

        $this->request->allowMethod(['post', 'put']);

        // Validate if $id is a valid integer
        if (!is_numeric($id) || !preg_match('/^\d+$/', $id)) {
            $this->Flash->error(__('Invalid product ID.'));
            return $this->redirect(['action' => 'index']);
        }

        try {
            $product = $this->Product->get($id);
        } catch (RecordNotFoundException $e) {
            $this->Flash->error(__('Product not found.'));
            return $this->redirect(['action' => 'index']);
        }

        $product = $this->Product->patchEntity($product, $this->request->getData());

        if ($this->Product->save($product)) {
            $this->Flash->success(__('Stock updated successfully.'));
        } else {
            $this->Flash->error(__('Failed to update stock.'));
        }

        return $this->redirect(['action' => 'view', $id]);
    }

    /**
     * Display method – for homepage or any static page
     */
    public function display(...$path)
    {
        $page = $path[0] ?? 'home';

        if ($page === 'home') {
            $this->loadModel('Products');
            $products = $this->Products->find()->limit(4)->all();

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

        $this->render(implode('/', $path));
    }
}
