<?php

namespace App\Validation;

use App\Libraries\PhoneNumber;

/**
 * App-specific validation rules, registered in Config\Validation::$ruleSets.
 */
class CustomRules
{
    /**
     * Accepts anything App\Libraries\PhoneNumber::normalize() can turn into
     * a valid +233XXXXXXXXX number (local 0XXXXXXXXX or 233XXXXXXXXX).
     */
    public function validPhone(?string $str, ?string &$error = null): bool
    {
        if (! PhoneNumber::isValid($str)) {
            $error = 'The {field} field must be a valid Ghanaian phone number.';

            return false;
        }

        return true;
    }

    /**
     * Usage: 'check_out_date' => 'checkOutAfterCheckIn[check_in_date]'
     */
    public function checkOutAfterCheckIn(?string $str, string $fields, array $data, ?string &$error = null): bool
    {
        $checkInField = $fields;
        $checkIn      = $data[$checkInField] ?? null;

        if ($checkIn === null || $str === null) {
            return true; // let `required`/`valid_date` report the real problem
        }

        if (strtotime($str) <= strtotime($checkIn)) {
            $error = 'The {field} field must be a date after check-in.';

            return false;
        }

        return true;
    }

    /**
     * Same syntax and behavior as the framework's built-in `is_unique`
     * (`tenant_unique[table.field,ignoreField,ignoreValue]`), but queries
     * the CURRENT TENANT's database instead of whatever `default`
     * resolves to.
     *
     * Every tenant-scoped model must use this instead of `is_unique` —
     * `is_unique` has no way to know about per-request tenant database
     * switching and silently checks the control DB, which either throws
     * (control DB has no such table) or, worse, "succeeds" against the
     * wrong data if a same-named table ever exists there. See
     * app/Models/TenantModel.php.
     */
    public function tenant_unique(?string $str, string $params, array $data): bool
    {
        [$fieldSpec, $ignoreField, $ignoreValue] = array_pad(explode(',', $params), 3, null);
        [$table, $column] = array_pad(explode('.', $fieldSpec, 2), 2, null);

        $builder = service('tenantDb')->table($table)->where($column, $str);

        if (! empty($ignoreField) && $ignoreValue !== null && $ignoreValue !== '') {
            $builder->where("{$ignoreField} !=", $ignoreValue);
        }

        return $builder->get()->getRow() === null;
    }
}
