<?php

if (!defined('ABSPATH')) { exit; }

class AIEO_TRS_Validator {

    const VALID_CONDITIONS = array('', 'price', 'weight', 'items', 'items_in_class');

    
    public static function validate(array $data) {
        $errors = array();

        $shipping_method_id = (int) ($data['shipping_method_id'] ?? 0);
        if ($shipping_method_id <= 0) {
            $errors[] = __('A shipping method instance is required.', 'ai-eshop-optimizer');
        }

        $rate_condition = (string) ($data['rate_condition'] ?? '');
        if (!in_array($rate_condition, self::VALID_CONDITIONS, true)) {
            $errors[] = sprintf(
                
                __('Unknown condition "%s". Allowed: price, weight, items, items_in_class, or empty.', 'ai-eshop-optimizer'),
                $rate_condition
            );
        }

        
        $min = self::nullable_decimal($data['rate_min'] ?? null);
        $max = self::nullable_decimal($data['rate_max'] ?? null);
        if ($min !== null && $max !== null && $max < $min) {
            $errors[] = __('"Max" must be greater than or equal to "Min".', 'ai-eshop-optimizer');
        }

        
        
        foreach (array('rate_cost', 'rate_cost_per_item', 'rate_cost_per_weight_unit', 'rate_cost_percent') as $field) {
            if (!isset($data[$field]) || $data[$field] === '') { continue; }
            if (!is_numeric($data[$field])) {
                $errors[] = sprintf(
                    
                    __('"%s" must be a number.', 'ai-eshop-optimizer'),
                    $field
                );
                continue;
            }
            if ((float) $data[$field] < 0) {
                $errors[] = sprintf(
                    
                    __('"%s" cannot be negative.', 'ai-eshop-optimizer'),
                    $field
                );
            }
        }

        
        
        $abort = !empty($data['rate_abort']) && (int) $data['rate_abort'] === 1;
        $reason = trim((string) ($data['rate_abort_reason'] ?? ''));
        if ($abort && $reason === '') {
            $errors[] = __('Abort rules need a reason — the customer should know why no shipping is offered.', 'ai-eshop-optimizer');
        }

        
        
        $class = (string) ($data['rate_class'] ?? '');
        if ($class !== '' && $class !== '0' && !preg_match('/^[a-z0-9_-]+$/', $class)) {
            $errors[] = sprintf(
                
                __('Invalid shipping class slug "%s".', 'ai-eshop-optimizer'),
                $class
            );
        }

        if (!empty($errors)) {
            return array('ok' => false, 'errors' => $errors);
        }

        $clean = array(
            'shipping_method_id'        => $shipping_method_id,
            'rate_class'                => $class,
            'rate_condition'            => $rate_condition,
            'rate_min'                  => $min,
            'rate_max'                  => $max,
            'rate_cost'                 => (float) ($data['rate_cost'] ?? 0),
            'rate_cost_per_item'        => (float) ($data['rate_cost_per_item'] ?? 0),
            'rate_cost_per_weight_unit' => (float) ($data['rate_cost_per_weight_unit'] ?? 0),
            'rate_cost_percent'         => (float) ($data['rate_cost_percent'] ?? 0),
            'rate_label'                => (string) ($data['rate_label'] ?? ''),
            'rate_priority'             => !empty($data['rate_priority']) ? 1 : 0,
            'rate_order'                => (int) ($data['rate_order'] ?? 0),
            'rate_abort'                => $abort ? 1 : 0,
            'rate_abort_reason'         => $reason,
            'enabled'                   => isset($data['enabled']) ? ((int) $data['enabled'] === 0 ? 0 : 1) : 1,
        );
        if (isset($data['legacy_rate_id'])) {
            $clean['legacy_rate_id'] = ($data['legacy_rate_id'] === '' || $data['legacy_rate_id'] === null)
                ? null
                : (int) $data['legacy_rate_id'];
        }
        return array('ok' => true, 'data' => $clean);
    }

    private static function nullable_decimal($val) {
        if ($val === null || $val === '' || !is_numeric($val)) { return null; }
        return (float) $val;
    }
}
