<?php

declare(strict_types=1);

namespace Kylin\Agriculture\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Kylin\Agriculture\Models\Sensor;
use Kylin\Agriculture\Models\Warning;

/**
 * 预警规则检测 Job
 *
 * 定时检测传感器数据是否触发预警规则，生成预警记录。
 */
class CheckWarningRules implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public int $tries = 3;
    public int $timeout = 30;

    public function __construct(
        public int $sensorId,
        public array $parameters,
    ) {}

    public function handle(): void
    {
        $sensor = Sensor::find($this->sensorId);
        if (!$sensor) {
            return;
        }

        $rules = Cache::remember(
            'warning_rules',
            config('kylin-agriculture.warning_rules_cache_ttl', 3600),
            fn() => WarningRule::where('enabled', true)->get()
        );

        foreach ($rules as $rule) {
            $value = $this->parameters[$rule->parameter] ?? null;
            if ($value === null) {
                continue;
            }

            $triggered = match ($rule->operator) {
                '>'  => $value > $rule->threshold,
                '>=' => $value >= $rule->threshold,
                '<'  => $value < $rule->threshold,
                '<=' => $value <= $rule->threshold,
                '==' => $value == $rule->threshold,
                default => false,
            };

            if ($triggered) {
                Warning::create([
                    'type' => $rule->parameter,
                    'level' => $rule->level,
                    'content' => "{$sensor->plot?->name} - {$rule->name}：当前值 {$value}，阈值 {$rule->threshold}",
                    'plot_id' => $sensor->plot_id,
                    'sensor_id' => $sensor->id,
                    'rule_id' => $rule->id,
                    'status' => 'pending',
                ]);

                SendWarningNotification::dispatch($sensor, $rule, $value);
            }
        }
    }
}
