<?php
namespace PpPhp\Plugins;

use PpPhp\Core\ValidationPlugin;

class CompareRule implements ValidationPlugin
{
    public static function id(): string { return 'compare'; }
    public static function label(): string { return 'Compare to another field'; }
    public static function group(): string { return 'Cross-field'; }

    public static function paramsSchema(): array
    {
        return [
            ['key' => 'field', 'type' => 'text', 'label' => 'Other field name', 'default' => '', 'placeholder' => 'e.g. start_date'],
            ['key' => 'op', 'type' => 'select', 'label' => 'Must be', 'options' => ['>', '>=', '<', '<=', '==', '!='], 'default' => '>='],
            ['key' => 'as', 'type' => 'select', 'label' => 'Compare as', 'options' => ['number', 'date', 'text'], 'default' => 'number'],
        ];
    }

    public static function appliesTo(): array { return []; }
    public static function defaultMessage(): string { return 'Must be {op} {field}.'; }

    private static function cast(string $v, string $as): mixed
    {
        if ($as === 'number') return is_numeric($v) ? $v + 0 : null;
        if ($as === 'date') { $t = strtotime($v); return $t === false ? null : $t; }
        return $v;
    }

    public static function serverCheck(mixed $value, array $params, array $record = []): bool
    {
        $other = (string) ($params['field'] ?? '');
        if ($other === '' || !array_key_exists($other, $record)) return true;
        $as = (string) ($params['as'] ?? 'number');
        $a = self::cast((string) $value, $as);
        $b = self::cast((string) $record[$other], $as);
        if ($a === null || $b === null) return true; // uncomparable → don't block
        switch ((string) ($params['op'] ?? '>=')) {
            case '>':  return $a >  $b;
            case '>=': return $a >= $b;
            case '<':  return $a <  $b;
            case '<=': return $a <= $b;
            case '==': return $a == $b;
            case '!=': return $a != $b;
        }
        return true;
    }

    public static function clientRule(array $params): array
    {
        $other = (string) ($params['field'] ?? '');
        if ($other === '') return [];
        return ['compare' => ['field' => $other, 'op' => (string) ($params['op'] ?? '>='), 'as' => (string) ($params['as'] ?? 'number')]];
    }
}
