<?php
declare(strict_types=1);

namespace App\Model\Table;

use ArrayObject;
use Cake\Event\EventInterface;
use Cake\ORM\Table;
use Cake\Validation\Validator;

class ContactMessagesTable extends Table
{
    public const INTEREST_AREAS = ['pottery', 'knitting', 'both', 'not_sure'];
    public const EXPERIENCE_LEVELS = ['beginner', 'some', 'returning', 'advanced'];
    public const STATUSES = ['new', 'in_progress', 'resolved', 'spam'];

    public function initialize(array $config): void
    {
        parent::initialize($config);

        $this->setTable('contact_messages');
        $this->setDisplayField('full_name');
        $this->setPrimaryKey('id');
        $this->addBehavior('Timestamp');

        $this->belongsTo('AdminUsers', [
            'foreignKey' => 'reviewed_by_admin_user_id',
        ]);
    }

    public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObject $options): void
    {
        $fieldsToTrim = ['full_name', 'email', 'phone', 'interest_area', 'experience_level', 'subject', 'goals', 'message_body', 'admin_notes'];
        $nullableFields = ['phone', 'experience_level', 'subject', 'goals', 'admin_notes'];

        foreach ($fieldsToTrim as $field) {
            if (!isset($data[$field])) {
                continue;
            }

            $value = trim((string)$data[$field]);
            $data[$field] = $value;

            if ($value === '' && in_array($field, $nullableFields, true)) {
                $data[$field] = null;
            }
        }
    }

    public function validationDefault(Validator $validator): Validator
    {
        $validator
            ->scalar('full_name')
            ->maxLength('full_name', 150)
            ->requirePresence('full_name', 'create')
            ->notEmptyString('full_name');

        $validator
            ->email('email')
            ->requirePresence('email', 'create')
            ->notEmptyString('email');

        $validator
            ->scalar('phone')
            ->maxLength('phone', 60)
            ->allowEmptyString('phone');

        $validator
            ->scalar('interest_area')
            ->inList('interest_area', self::INTEREST_AREAS)
            ->requirePresence('interest_area', 'create')
            ->notEmptyString('interest_area');

        $validator
            ->scalar('experience_level')
            ->inList('experience_level', self::EXPERIENCE_LEVELS)
            ->allowEmptyString('experience_level');

        $validator
            ->scalar('subject')
            ->maxLength('subject', 160)
            ->allowEmptyString('subject');

        $validator
            ->scalar('goals')
            ->maxLength('goals', 1000)
            ->allowEmptyString('goals');

        $validator
            ->scalar('message_body')
            ->maxLength('message_body', 4000)
            ->minLength('message_body', 20, 'Please share a little more detail so the team can follow up clearly.')
            ->requirePresence('message_body', 'create')
            ->notEmptyString('message_body');

        $validator
            ->boolean('consent_to_contact')
            ->add('consent_to_contact', 'accepted', [
                'rule' => static fn(mixed $value): bool => in_array($value, [true, 1, '1'], true),
                'message' => 'You must consent before submitting.',
            ]);

        $validator
            ->boolean('marketing_opt_in_email')
            ->allowEmptyString('marketing_opt_in_email');

        $validator
            ->boolean('marketing_opt_in_sms')
            ->allowEmptyString('marketing_opt_in_sms');

        $validator
            ->scalar('status')
            ->inList('status', self::STATUSES)
            ->allowEmptyString('status');

        $validator
            ->scalar('admin_notes')
            ->maxLength('admin_notes', 4000)
            ->allowEmptyString('admin_notes');

        return $validator;
    }
}
