<?php

namespace App\Filters;

use Illuminate\Database\Eloquent\Builder;

class PensionCaseFilterBuilder {

    public static function apply(Builder $query, array $filterRows): Builder {
        foreach ($filterRows as $row) {
            if (empty($row['field']) || empty($row['operator'])) {
                continue;
            }
            static::applyRow($query, $row);
        }
        return $query;
    }

    private static function applyRow(Builder $query, array $row): void {
        $field    = $row['field'];
        $operator = $row['operator'];
        $value    = $row['value'] ?? '';
        $value2   = $row['value2'] ?? '';

        $fieldConfig = PensionCaseFilterConfig::getField($field);
        $type        = $fieldConfig['type'] ?? 'string';
        $isDate      = in_array($type, ['date']);

        match ($operator) {
            // ── Equality ────────────────────────────────────────────────────
            'equals' => $isDate
                ? $query->whereDate($field, $value)
                : $query->where($field, $value),

            'not_equals' => $isDate
                ? $query->whereDate($field, '!=', $value)
                : $query->where($field, '!=', $value),

            // ── String pattern ───────────────────────────────────────────────
            'contains'        => $query->where($field, 'like', '%' . $value . '%'),
            'not_contains'    => $query->where($field, 'not like', '%' . $value . '%'),
            'starts_with'     => $query->where($field, 'like', $value . '%'),
            'not_starts_with' => $query->where($field, 'not like', $value . '%'),
            'ends_with'       => $query->where($field, 'like', '%' . $value),
            'not_ends_with'   => $query->where($field, 'not like', '%' . $value),

            // ── Numeric comparison ───────────────────────────────────────────
            'greater_than' => $query->where($field, '>', $value),
            'less_than'    => $query->where($field, '<', $value),
            'gte'          => $query->where($field, '>=', $value),
            'lte'          => $query->where($field, '<=', $value),

            // ── Date comparison ──────────────────────────────────────────────
            'before'       => $query->whereDate($field, '<', $value),
            'on_or_before' => $query->whereDate($field, '<=', $value),
            'after'        => $query->whereDate($field, '>', $value),
            'on_or_after'  => $query->whereDate($field, '>=', $value),

            // ── Range ────────────────────────────────────────────────────────
            'between' => $isDate
                ? $query->whereDate($field, '>=', $value)->whereDate($field, '<=', $value2)
                : $query->whereBetween($field, [$value, $value2]),

            'not_between' => $isDate
                ? $query->where(fn(Builder $q) => $q->whereDate($field, '<', $value)->orWhereDate($field, '>', $value2))
                : $query->whereNotBetween($field, [$value, $value2]),

            // ── Null / empty ─────────────────────────────────────────────────
            'is_empty' => $query->where(function (Builder $q) use ($field) {
                $q->whereNull($field)->orWhere($field, '');
            }),

            'is_not_empty' => $query->whereNotNull($field)->where($field, '!=', ''),

            // ── Boolean ──────────────────────────────────────────────────────
            'is_true'  => $query->where($field, true),
            'is_false' => $query->where($field, false),

            default => null,
        };
    }
}
