<?php
/**
 * @link http://craftcms.com/
 * @copyright Copyright (c) Pixel & Tonic, Inc.
 * @license http://craftcms.com/license
 */

namespace craft\behaviors;

use yii\base\Behavior;

/**
 * Custom field behavior
 *
 * This class provides attributes for all the unique custom field handles.
 *
 * @method static homeTitle(mixed $value) Sets the [[homeTitle]] property
 * @method static heroImages(mixed $value) Sets the [[heroImages]] property
 * @method static pictures(mixed $value) Sets the [[pictures]] property
 * @method static price(mixed $value) Sets the [[price]] property
 * @method static suburb(mixed $value) Sets the [[suburb]] property
 * @method static state(mixed $value) Sets the [[state]] property
 * @method static propertyType(mixed $value) Sets the [[propertyType]] property
 * @method static mainText(mixed $value) Sets the [[mainText]] property
 * @method static mainImage(mixed $value) Sets the [[mainImage]] property
 */
class CustomFieldBehavior extends Behavior
{
    /**
     * @var bool Whether the behavior should provide methods based on the field handles.
     */
    public bool $hasMethods = false;

    /**
     * @var bool Whether properties on the class should be settable directly.
     */
    public bool $canSetProperties = true;

    /**
     * @var string[] List of supported field handles.
     */
    public static $fieldHandles = [
        'homeTitle' => true,
        'heroImages' => true,
        'pictures' => true,
        'price' => true,
        'suburb' => true,
        'state' => true,
        'propertyType' => true,
        'mainText' => true,
        'mainImage' => true,
    ];

    /**
     * @var string|null Value for field with the handle “homeTitle”.
     */
    public $homeTitle;

    /**
     * @var \craft\elements\db\AssetQuery|\craft\elements\ElementCollection<\craft\elements\Asset> Value for field with the handle “heroImages”.
     */
    public $heroImages;

    /**
     * @var \craft\elements\db\AssetQuery|\craft\elements\ElementCollection<\craft\elements\Asset> Value for field with the handle “pictures”.
     */
    public $pictures;

    /**
     * @var int|float|null Value for field with the handle “price”.
     */
    public $price;

    /**
     * @var string|null Value for field with the handle “suburb”.
     */
    public $suburb;

    /**
     * @var string|null Value for field with the handle “state”.
     */
    public $state;

    /**
     * @var \craft\elements\db\CategoryQuery|\craft\elements\ElementCollection<\craft\elements\Category> Value for field with the handle “propertyType”.
     */
    public $propertyType;

    /**
     * @var mixed Value for field with the handle “mainText”.
     */
    public $mainText;

    /**
     * @var \craft\elements\db\AssetQuery|\craft\elements\ElementCollection<\craft\elements\Asset> Value for field with the handle “mainImage”.
     */
    public $mainImage;

    /**
     * @var array Additional custom field values we don’t know about yet.
     */
    private array $_customFieldValues = [];

    /**
     * @inheritdoc
     */
    public function __call($name, $params)
    {
        if ($this->hasMethods && isset(self::$fieldHandles[$name]) && count($params) === 1) {
            $this->$name = $params[0];
            return $this->owner;
        }
        return parent::__call($name, $params);
    }

    /**
     * @inheritdoc
     */
    public function hasMethod($name): bool
    {
        if ($this->hasMethods && isset(self::$fieldHandles[$name])) {
            return true;
        }
        return parent::hasMethod($name);
    }

    /**
     * @inheritdoc
     */
    public function __isset($name): bool
    {
        if (isset(self::$fieldHandles[$name])) {
            return true;
        }
        return parent::__isset($name);
    }

    /**
     * @inheritdoc
     */
    public function __get($name)
    {
        if (isset(self::$fieldHandles[$name])) {
            return $this->_customFieldValues[$name] ?? null;
        }
        return parent::__get($name);
    }

    /**
     * @inheritdoc
     */
    public function __set($name, $value)
    {
        if (isset(self::$fieldHandles[$name])) {
            $this->_customFieldValues[$name] = $value;
            return;
        }
        parent::__set($name, $value);
    }

    /**
     * @inheritdoc
     */
    public function canGetProperty($name, $checkVars = true): bool
    {
        if ($checkVars && isset(self::$fieldHandles[$name])) {
            return true;
        }
        return parent::canGetProperty($name, $checkVars);
    }

    /**
     * @inheritdoc
     */
    public function canSetProperty($name, $checkVars = true): bool
    {
        if (!$this->canSetProperties) {
            return false;
        }
        if ($checkVars && isset(self::$fieldHandles[$name])) {
            return true;
        }
        return parent::canSetProperty($name, $checkVars);
    }
}
