<?php
namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Validation\Validator;
use Cake\ORM\RulesChecker;
use Cake\I18n\FrozenDate;
class ParticipantsTable extends Table
{
    public function initialize(array $config): void
    {
        parent::initialize($config);
        $this->setTable('participants');
        $this->setPrimaryKey('id');
        $this->addBehavior('Timestamp');

        $this->belongsToMany('Login', [
            'joinTable' => 'logins_participants',
            'foreignKey' => 'participant_id',
            'targetForeignKey' => 'login_id',
            'saveStrategy' => 'replace',
            'dependent' => true
        ]);

        $this->hasMany('ParticipantAddresses', [
            'foreignKey'      => 'participant_id',
            'saveStrategy'    => 'replace',
            'dependent'       => true,
            'cascadeCallbacks'=> true,
        ]);

        $this->hasMany('Contacts', [
            'className'        => 'ParticipantContacts',
            'foreignKey'       => 'participant_id',
            'dependent'        => true,
            'cascadeCallbacks' => true,
            'saveStrategy'     => 'replace',
            'sort'             => ['Contacts.sort' => 'ASC', 'Contacts.id' => 'ASC'],
        ]);

    }

    public function validationDefault(Validator $v): Validator
    {
        $phonePattern = '/^\+?\d[\d\s-]{7,15}$/';

        $v->scalar('first_name')->maxLength('first_name', 50)->requirePresence('first_name', 'create')
            ->notEmptyString('first_name', 'First name is required.');

        $v->scalar('middle_name')->maxLength('middle_name', 50)->allowEmptyString('middle_name');

        $v->scalar('last_name')->maxLength('last_name', 50)->allowEmptyString('last_name');

        $v->scalar('preferred_name')->maxLength('preferred_name', 50)->allowEmptyString('preferred_name');

        $v->email('email')->requirePresence('email', 'create')
            ->notEmptyString('email', 'Email is required.');

        $v->allowEmptyString('phone')
            ->add('phone', 'format', [
                'rule' => function ($value) use ($phonePattern) {
                    if ($value === null || $value === '') return true;
                    return (bool)preg_match($phonePattern, $value);
                },
                'message' => 'Enter a valid phone number.',
            ]);

        $v->allowEmptyString('emergency_contact_name');
        $v->allowEmptyString('emergency_contact_phone')
            ->add('emergency_contact_phone', 'format', [
                'rule' => function ($value) use ($phonePattern) {
                    if ($value === null || $value === '') return true;
                    return (bool)preg_match($phonePattern, $value);
                },
                'message' => 'Enter a valid emergency contact phone.',
            ]);
        $v
            ->allowEmptyString('allergies')
            ->maxLength('allergies', 1000);

        $v
            ->allowEmptyString('medicare_number')
            ->maxLength('medicare_number', 20)
            ->add('medicare_number', 'format', [
                'rule' => ['custom', '/^[0-9 ]{4,20}$/'],
                'message' => 'Medicare number should contain digits/spaces only.'
            ]);

        $v
            ->date('dob')
            ->allowEmptyDate('dob')
            ->add('dob', 'notFuture', [
                'rule' => function ($value) {
                    if (!$value) return true;
                    $d = $value instanceof \DateTimeInterface ? FrozenDate::createFromFormat('Y-m-d', $value->format('Y-m-d')) : new FrozenDate($value);
                    return $d <= FrozenDate::today();
                },
                'message' => 'Date of birth cannot be in the future.',
            ]);

        $v
            ->scalar('gender')
            ->maxLength('gender', 50)
            ->allowEmptyString('gender');

        $v
            ->date('review_date')
            ->allowEmptyDate('review_date');

        $v
            ->allowEmptyString('note')
            ->maxLength('note', 1000);
        return $v;

    }

    public function buildRules(RulesChecker $rules): RulesChecker
    {
        $rules->add($rules->isUnique(['email'], 'This email is already used.'));
        return $rules;
    }
}


