<?php

namespace Snaju\Inception\Http\Request\Validators;

/**
 * A flexible class used to determine if a data value is "valid" passing any,
 * checks specified in the `isValid` method. Returning false, results in an error
 * being recorded and sent to the client making the request.
 *
 * @package Snaju\Inception\Http\Request\Validators
 */
abstract class ValidatorRule
{
    /**
     * The property name on the data array.
     * @var string
     */
    protected string $field;

    /**
     * The property's value on the data array.
     * @var
     */
    protected $ruleValue;

    /**
     * Used to determine if the validator can pass if the field is null, empty, or not provided.
     * @var bool|mixed
     */
    protected bool $optional;

    /**
     * Convenience method to determine if the Rule is using the raw request data or data from another source.
     * @var bool
     */
    protected bool $usesRequestData;

    /**
     * Determines whether this method should drill down the array to validate other arrays and objects it finds.
     * @var bool
     */
    protected bool $nestedLookup = false;

    protected $overrideError = null;

    /**
     * ValidatorRule constructor.
     *
     * @param $field
     * @param $ruleValue
     * @param $usesRequestData
     * @param false $optional
     */
    public function __construct($field, $ruleValue, $usesRequestData, $optional= false, $overrideError = null)
    {
        $this->field = $field;
        $this->ruleValue = $ruleValue;
        $this->usesRequestData = $usesRequestData;
        $this->optional = $optional;
        $this->overrideError = $overrideError;

        if (str_contains($this->field, '.')) {
            $this->nestedLookup = true;
        }
    }

    /**
     * Returns true if the value passes the validator's checks.
     *
     * @param $dataArray
     * @return bool
     */
    abstract public function isValid($dataArray): bool;

    /**
     * Returns the error message string to show as feedback if the validator fails.
     *
     * @return string
     */
    abstract public function getErrorMessage(): string;

    /**
     * When this returns true, all other validators are not ran and the Validator
     * returns this error and any other errors encountered before this rule.
     *
     * @return bool
     */
    public function stopOnError(): bool
    {
        return false;
    }

    /**
     * Returns the rule's value to use for validation against the data value.
     * For example, if MinRule is used `min:6`, this method would return 6.
     *
     * @return mixed
     */
    public function getRuleValue()
    {
        return $this->ruleValue;
    }

    /**
     * @return mixed|null
     */
    public function getOverrideError(): mixed
    {
        return $this->overrideError;
    }

}