<?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 App\Utility\SchemaUtility;


/**
 * Contents Model
 *
 * @property \App\Model\Table\MenusTable&\Cake\ORM\Association\BelongsTo $Menus
 * @property \App\Model\Table\ContentImagesTable&\Cake\ORM\Association\HasMany $ContentImages
 * @property \App\Model\Table\PageContentsTable&\Cake\ORM\Association\HasMany $PageContents
 *
 * @method \App\Model\Entity\Content newEmptyEntity()
 * @method \App\Model\Entity\Content newEntity(array $data, array $options = [])
 * @method \App\Model\Entity\Content[] newEntities(array $data, array $options = [])
 * @method \App\Model\Entity\Content get($primaryKey, $options = [])
 * @method \App\Model\Entity\Content findOrCreate($search, ?callable $callback = null, $options = [])
 * @method \App\Model\Entity\Content patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
 * @method \App\Model\Entity\Content[] patchEntities(iterable $entities, array $data, array $options = [])
 * @method \App\Model\Entity\Content|false save(\Cake\Datasource\EntityInterface $entity, $options = [])
 * @method \App\Model\Entity\Content saveOrFail(\Cake\Datasource\EntityInterface $entity, $options = [])
 * @method \App\Model\Entity\Content[]|\Cake\Datasource\ResultSetInterface|false saveMany(iterable $entities, $options = [])
 * @method \App\Model\Entity\Content[]|\Cake\Datasource\ResultSetInterface saveManyOrFail(iterable $entities, $options = [])
 * @method \App\Model\Entity\Content[]|\Cake\Datasource\ResultSetInterface|false deleteMany(iterable $entities, $options = [])
 * @method \App\Model\Entity\Content[]|\Cake\Datasource\ResultSetInterface deleteManyOrFail(iterable $entities, $options = [])
 *
 * @mixin \Cake\ORM\Behavior\TimestampBehavior
 */
class ContentsTable 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('contents');
        $this->setDisplayField('name');
        $this->setPrimaryKey('id');

        $this->addBehavior('Timestamp');

        $this->belongsTo('Menus', [
            'foreignKey' => 'menu_id',
        ]);
        $this->hasMany('ContentImages', [
            'foreignKey' => 'content_id',
        ]);
        $this->hasMany('PageContents', [
            'foreignKey' => 'content_id',
        ]);
    }

    /**
     * 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('slug')
            ->maxLength('slug', 255)
            ->allowEmptyString('slug');

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

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

        $validator
            ->scalar('caption')
            ->maxLength('caption', 100)
            ->allowEmptyString('caption');

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

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

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

        $validator
            ->scalar('file_path')
            ->maxLength('file_path', 500)
            ->allowEmptyFile('file_path');

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

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

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

        $validator
            ->scalar('fa_icon')
            ->maxLength('fa_icon', 100)
            ->allowEmptyString('fa_icon');

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

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

        $validator
            ->scalar('map_address')
            ->maxLength('map_address', 500)
            ->allowEmptyString('map_address');

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

        $validator
            ->dateTime('created_date')
            ->allowEmptyDateTime('created_date');

        $validator
            ->dateTime('modified_date')
            ->allowEmptyDateTime('modified_date');

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

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

        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->existsIn('menu_id', 'Menus'), ['errorField' => 'menu_id']);

        return $rules;
    }

    public function menuDetails()
    {
        // Find the menu details based on the provided 'slug' parameter
        $menuDetails = $this->PageContents->Menus->find('all', [
            'conditions' => [
                'slug' => $this->request->getParam('section') // Retrieve 'slug' parameter from the request
            ]
        ])->first();

        return $menuDetails;
    }

    public function getHomeContents($menu)
    {
        $query = $this->find('all', [
            'contain' => [
                'ContentImages',
                'PageContents'
            ],
            'conditions' => [
                'status' => 1,
                'show_on_home' => 1
            ]
        ])->matching('PageContents', function ($q) use ($menu) {
            return $q->where(['PageContents.menu_id' => $menu->id]);
        });

        // Dynamic order clause based on schema
        if (SchemaUtility::hasColumn('Contents', 'order_value')) {
            $query->order(['Contents.order_value' => 'ASC']);
        }

        // Fallback ordering
        if (!SchemaUtility::hasColumn('Contents', 'order_value')) {
            $query->order(['Contents.name' => 'ASC']);
        }

        return $query->toArray();
    }

    public function getContents($menuDetails)
    {
        $query = $this->find('all', [
            'contain' => [
                'ContentImages',
                'PageContents'
            ],
            'conditions' => [
                'status' => 1,
            ]
        ])->order([
                    'Contents.order_value' => 'ASC'
                ])->matching('PageContents', function ($q) use ($menuDetails) {
                    return $q->where(['PageContents.menu_id' => $menuDetails->id]);
                })->toArray();
                
        return $query;
    }

    public function getSubSecContent($menuDetails, $subMenu)
    {
        $condition = ['PageContents.menu_id' => $menuDetails->id];

        if ($subMenu->count() > 0) {
            $condition = [
                'OR' => [
                    ['PageContents.menu_id' => $menuDetails->id],
                    ['PageContents.menu_id in' => $subMenu]
                ]
            ];
        }

        $query = $this->find('all', [
            'contain' => [
                'ContentImages',
                'PageContents'
            ],
            'conditions' => [
                'status' => 1
            ]
        ])->order([
                    'Contents.order_value' => 'ASC'
                ])->matching('PageContents', function ($q) use ($condition) {
                    return $q->where($condition);
                })->toArray();

        return $query;
    }

    public function getDetailContent($id)
    {
        $query = $this->find('all', [
            'contain' => [
                'ContentImages',
                'PageContents'
            ],
            'conditions' => [
                'Contents.status' => 1,
                'Contents.id' => $id
            ]
        ])->first();

        return $query;
    }

}
