<?php
declare(strict_types=1);

namespace App\Model\Table;

use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\Cache\Cache;
use Cake\Utility\Text;


/**
 * Menus Model
 *
 * @property \App\Model\Table\AlbumsTable&\Cake\ORM\Association\HasMany $Albums
 * @property \App\Model\Table\ContentsTable&\Cake\ORM\Association\HasMany $Contents
 * @property \App\Model\Table\PageContentsTable&\Cake\ORM\Association\HasMany $PageContents
 * @property \App\Model\Table\PageProductsTable&\Cake\ORM\Association\HasMany $PageProducts
 *
 * @method \App\Model\Entity\Menu newEmptyEntity()
 * @method \App\Model\Entity\Menu newEntity(array $data, array $options = [])
 * @method \App\Model\Entity\Menu[] newEntities(array $data, array $options = [])
 * @method \App\Model\Entity\Menu get($primaryKey, $options = [])
 * @method \App\Model\Entity\Menu findOrCreate($search, ?callable $callback = null, $options = [])
 * @method \App\Model\Entity\Menu patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
 * @method \App\Model\Entity\Menu[] patchEntities(iterable $entities, array $data, array $options = [])
 * @method \App\Model\Entity\Menu|false save(\Cake\Datasource\EntityInterface $entity, $options = [])
 * @method \App\Model\Entity\Menu saveOrFail(\Cake\Datasource\EntityInterface $entity, $options = [])
 * @method \App\Model\Entity\Menu[]|\Cake\Datasource\ResultSetInterface|false saveMany(iterable $entities, $options = [])
 * @method \App\Model\Entity\Menu[]|\Cake\Datasource\ResultSetInterface saveManyOrFail(iterable $entities, $options = [])
 * @method \App\Model\Entity\Menu[]|\Cake\Datasource\ResultSetInterface|false deleteMany(iterable $entities, $options = [])
 * @method \App\Model\Entity\Menu[]|\Cake\Datasource\ResultSetInterface deleteManyOrFail(iterable $entities, $options = [])
 *
 * @mixin \Cake\ORM\Behavior\TimestampBehavior
 */
class MenusTable extends Table
{
    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->setTable('menus');
        $this->setDisplayField('name');
        $this->setPrimaryKey('id');

        $this->addBehavior('Timestamp');

        $this->hasMany('Albums', [
            'foreignKey' => 'menu_id',
        ]);
        $this->hasMany('Contents', [
            'foreignKey' => 'menu_id',
        ]);
        $this->hasMany('PageContents', [
            'foreignKey' => 'menu_id',
        ]);
        $this->hasMany('PageProducts', [
            'foreignKey' => 'menu_id',
        ]);
        $this->belongsTo('Menus', [
            'foreignKey' => 'parent_menu_id'
        ]);
        $this->belongsTo('ParentMenus', [
            'foreignKey' => 'parent_menu_id',
            'className' => 'Menus'
        ]);
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator): Validator
    {
        $validator
            ->scalar('name')
            ->maxLength('name', 255)
            ->allowEmptyString('name');

        $validator
            ->scalar('description')
            ->maxLength('description', 255)
            ->allowEmptyString('description');

        $validator
            ->integer('parent_menu_id')
            ->notEmptyString('parent_menu_id');

        $validator
            ->integer('status')
            ->notEmptyString('status');

        $validator
            ->scalar('slug')
            ->maxLength('slug', 255)
            ->allowEmptyString('slug');

        $validator
            ->integer('show_on_home')
            ->allowEmptyString('show_on_home');

        $validator
            ->integer('show_on_footer')
            ->notEmptyString('show_on_footer');

        $validator
            ->integer('show_on_top')
            ->allowEmptyString('show_on_top');

        $validator
            ->scalar('image_path')
            ->maxLength('image_path', 255)
            ->allowEmptyFile('image_path');

        $validator
            ->scalar('content')
            // ->maxLength('content', 255)
            ->allowEmptyString('content');

        $validator
            ->integer('order_value')
            ->notEmptyString('order_value');

        $validator
            ->scalar('home_order')
            ->maxLength('home_order', 255)
            ->notEmptyString('home_order');

        $validator
            ->integer('show_button')
            ->allowEmptyString('show_button');

        $validator
            ->scalar('menu_link')
            ->maxLength('menu_link', 255)
            ->allowEmptyString('menu_link');

        return $validator;
    }

    /**
     * Returns a rules checker object that will be used for validating
     * application integrity.
     *
     * @param \Cake\ORM\RulesChecker $rules The rules object to be modified.
     * @return \Cake\ORM\RulesChecker
     */
    public function buildRules(RulesChecker $rules): RulesChecker
    {
        $rules->add($rules->isUnique(['id']), ['errorField' => 'id']);

        return $rules;
    }


    public function getMainMenu()
    {
        $orderQuery = [];
        $schema = $this->getSchema();
        if ($schema->hasColumn('order_value')) {
            $orderQuery = ['order_value' => 'ASC'];
        }
        // Define the fields explicitly to optimize the query
        $query = $this->find()
            ->select(['id', 'name', 'slug', 'parent_menu_id', 'status']) // Select specific fields
            ->where(['parent_menu_id' => 0, 'status' => 1])             // Define conditions
            ->order($orderQuery)                              // Ordering, assuming 'position' field exists
            ->all();                                                    // Use `all()` for a query result object

        return $query->toArray(); // Convert the result to an array if needed
    }

    public function getSubmenus($id)
    {
        $orderQuery = [];
        $schema = $this->getSchema();
        if ($schema->hasColumn('order_value')) {
            $orderQuery = ['order_value' => 'ASC'];
        }
        $query = $this->find()
            ->select(['id', 'name', 'slug', 'parent_menu_id', 'status'])
            ->where(["parent_menu_id" => $id, "status" => 1])
            ->order($orderQuery)
            ->all();

        return $query->toArray();
    }

    public function getMenuSlug($slug)
    {

        $query = $this->find()
            ->where(["slug" => Text::slug($slug)])
            ->all();

        return $query->first();
    }

    public function getparentMenu($id)
    {
        $query = $this->find()
            ->where(['parent_menu_id' => $id])
            ->select(['id', 'name'])
            ->combine('id', 'name');

        return $query;
    }

    function findSubSubMenus($id = null)
    {
        $ids = [-1];

        $query = $this->find('all', ['conditions' => ['parent_menu_id' => $id]])->toArray();
        foreach ($query as $key => $q) {
            array_push($ids, $q['id']);
        }

        return $this->find('all')
            ->where(['parent_menu_id IN' => $ids]);
    }

    function findPendingSubSubMenus($id = null)
    {
        $ids = [-1];

        $query = $this->find('all', ['conditions' => ['parent_menu_id' => $id,]])->toArray();
        foreach ($query as $key => $q) {
            array_push($ids, $q['id']);
        }

        return $this->find('all')
            ->where(['parent_menu_id IN' => $ids, 'status' => 0]);
    }

    function findEnabledSubSubMenus($id = null)
    {
        $ids = [-1];

        $query = $this->find('all', ['conditions' => ['parent_menu_id' => $id,]])->toArray();
        foreach ($query as $key => $q) {
            array_push($ids, $q['id']);
        }

        return $this->find('all')
            ->where(['parent_menu_id IN' => $ids, 'status' => 1]);
    }

    function findDisabledSubSubMenus($id = null)
    {
        $ids = [-1];

        $query = $this->find('all', ['conditions' => ['parent_menu_id' => $id,]])->toArray();
        foreach ($query as $key => $q) {
            array_push($ids, $q['id']);
        }

        return $this->find('all')
            ->where(['parent_menu_id IN' => $ids, 'status' => 99]);
    }

    function findEditedSubSubMenus($id = null)
    {
        $ids = [-1];

        $query = $this->find('all', ['conditions' => ['parent_menu_id' => $id,]])->toArray();
        foreach ($query as $key => $q) {
            array_push($ids, $q['id']);
        }

        return $this->find('all')
            ->where(['parent_menu_id IN' => $ids, 'status' => 2]);
    }

    function updateSubMenu($id)
    {

        return $this->find('all')->where(['parent_menu_id' => $id])
            ->combine('id', 'name')->toArray();
    }

    public function getMenuFromName($name = null)
    {
        $query = $this->find('all', ['conditions' => ['name' => $name]])->first();
        return $query;
    }

}
