<?php

namespace XZD\AI\V5\REST\Controllers;

use XZD\AI\V5\REST\BaseController;
use XZD\AI\V5\Tools\RuleEngine;
use WP_REST_Request;
use WP_REST_Response;

/**
 * 自动化规则 REST 控制器
 */
class AutomationController extends BaseController
{
    private RuleEngine $engine;

    public function __construct()
    {
        $this->engine = RuleEngine::instance();
    }

    public function registerRoutes(): void
    {
        $this->registerGet('/automation/rules', [$this, 'index'], 'manage_options');
        $this->registerPost('/automation/rules', [$this, 'create'], 'manage_options');
        $this->registerPut('/automation/rules/(?P<id>\d+)', [$this, 'update'], 'manage_options');
        $this->registerDelete('/automation/rules/(?P<id>\d+)', [$this, 'destroy'], 'manage_options');
        $this->registerPost('/automation/rules/(?P<id>\d+)/toggle', [$this, 'toggle'], 'manage_options');
        $this->registerPost('/automation/rules/preset/(?P<name>[a-zA-Z_]+)', [$this, 'applyPreset'], 'manage_options');
        $this->registerGet('/automation/logs', [$this, 'logs'], 'manage_options');
        $this->registerGet('/automation/events', [$this, 'events'], 'edit_posts');
        $this->registerGet('/automation/actions', [$this, 'actions'], 'edit_posts');
    }

    public function index(WP_REST_Request $request): WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        $rows = $this->engine->getAllRules();
        $rules = array_map(function ($row) {
            return [
                'id'             => (int)$row->id,
                'name'           => $row->name,
                'description'    => $row->description,
                'event'          => $row->event,
                'conditions'     => $row->conditions ? json_decode($row->conditions, true) : null,
                'actions'        => $row->actions ? json_decode($row->actions, true) : [],
                'enabled'        => (bool)$row->enabled,
                'created_by'     => $row->created_by,
                'operator_id'    => (int)$row->operator_id,
                'rule_type'      => $row->rule_type ?? 'permanent',
                'max_executions' => (int)($row->max_executions ?? 0),
                'expires_at'     => $row->expires_at,
                'execution_count' => (int)($row->execution_count ?? 0),
                'created_at'     => $row->created_at,
                'updated_at'     => $row->updated_at,
            ];
        }, $rows);

        return $this->success([
            'rules' => $rules,
            'total' => count($rules),
        ]);
    }

    public function create(WP_REST_Request $request): WP_REST_Response
    {
        if ($err = $this->guardLicense()) return $err;
        $body = $this->getBodyParams($request);

        if (empty($body['name']) || empty($body['event'])) {
            return $this->error('规则名称和触发事件必填', 'missing_fields');
        }

        // 验证所有 action 的 tool_id 合法且未被屏蔽
        $actions = $body['actions'] ?? [];
        if (is_string($actions)) {
            $actions = json_decode($actions, true);
        }
        if (is_array($actions)) {
            $registry = \XZD\AI\V5\Tools\ToolRegistry::instance();
            foreach ($actions as $action) {
                $toolId = $action['tool_id'] ?? '';
                if (empty($toolId)) continue;
                if (!$registry->has($toolId)) {
                    return $this->error("工具不存在: {$toolId}", 'invalid_tool_id');
                }
                // 检查是否在自动化屏蔽列表中
                $availableActions = $registry->getAutomationActions();
                $availableIds = array_map(fn($t) => $t->id, array_values($availableActions));
                if (!in_array($toolId, $availableIds, true)) {
                    return $this->error("工具 {$toolId} 不允许作为自动化动作（可能为危险操作或自动化系统工具）", 'blocked_tool');
                }
            }
        }

        $data = [
            'name'           => $body['name'],
            'description'    => $body['description'] ?? '',
            'event'          => $body['event'],
            'conditions'     => $body['conditions'] ?? null,
            'actions'        => $body['actions'] ?? [],
            'enabled'        => $body['enabled'] ?? 0,
            'created_by'     => $body['created_by'] ?? 'manual',
            'operator_id'    => $body['operator_id'] ?? 0,
            'rule_type'      => $body['rule_type'] ?? 'permanent',
            'max_executions' => (int)($body['max_executions'] ?? 0),
            'expires_at'     => $body['expires_at'] ?? null,
        ];

        $id = $this->engine->createRule($data);

        if ($id <= 0) {
            return $this->error('创建规则失败', 'db_error');
        }

        return $this->created(['id' => $id], '规则已创建');
    }

    public function update(WP_REST_Request $request): WP_REST_Response
    {
        if ($err = $this->guardLicense()) return $err;
        $id = (int)$request->get_param('id');
        $rule = $this->engine->getRule($id);
        if (!$rule) {
            return $this->error('规则不存在', 'not_found', 404);
        }

        $body = $this->getBodyParams($request);
        $data = [];

        foreach (['name', 'description', 'event', 'conditions', 'actions', 'enabled', 'created_by', 'operator_id', 'rule_type', 'max_executions', 'expires_at'] as $f) {
            if (array_key_exists($f, $body)) {
                $data[$f] = $body[$f];
            }
        }

        if (empty($data)) {
            return $this->error('无更新数据', 'no_data');
        }

        $ok = $this->engine->updateRule($id, $data);

        if (!$ok) {
            return $this->error('更新失败', 'db_error');
        }

        return $this->success(null, '规则已更新');
    }

    public function destroy(WP_REST_Request $request): WP_REST_Response
    {
        if ($err = $this->guardLicense()) return $err;
        $id = (int)$request->get_param('id');
        $rule = $this->engine->getRule($id);
        if (!$rule) {
            return $this->error('规则不存在', 'not_found', 404);
        }

        $this->engine->deleteRule($id);
        return $this->success(null, '规则已删除');
    }

    public function toggle(WP_REST_Request $request): WP_REST_Response
    {
        if ($err = $this->guardLicense()) return $err;
        $id = (int)$request->get_param('id');
        $newState = $this->engine->toggleRule($id);

        if ($newState === null) {
            return $this->error('规则不存在', 'not_found', 404);
        }

        return $this->success([
            'enabled' => $newState,
            'id'      => $id,
        ], $newState ? '规则已启用' : '规则已禁用');
    }

    public function applyPreset(WP_REST_Request $request): WP_REST_Response
    {
        if ($err = $this->guardLicense()) return $err;
        $name = $request->get_param('name');
        $id = $this->engine->applyPreset($name);

        if ($id === null) {
            return $this->error("预设模板不存在: {$name}", 'preset_not_found');
        }

        return $this->created(['id' => $id, 'preset_name' => $name], '预设模板已应用');
    }

    public function logs(WP_REST_Request $request): WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        $ruleId = (int)($request->get_param('rule_id') ?? 0);
        $limit  = min((int)($request->get_param('limit') ?? 50), 200);
        $offset = (int)($request->get_param('offset') ?? 0);

        $rows = $this->engine->getLogs($ruleId, $limit, $offset);

        $logs = array_map(function ($row) {
            return [
                'id'            => (int)$row->id,
                'rule_id'       => (int)$row->rule_id,
                'rule_name'     => $row->rule_name,
                'event'         => $row->event,
                'event_data'    => $row->event_data ? json_decode($row->event_data, true) : null,
                'status'        => $row->status,
                'result'        => $row->result ? json_decode($row->result, true) : null,
                'error_message' => $row->error_message,
                'duration_ms'   => (int)$row->duration_ms,
                'created_at'    => $row->created_at,
            ];
        }, $rows);

        return $this->success([
            'logs'   => $logs,
            'total'  => count($logs),
            'limit'  => $limit,
            'offset' => $offset,
        ]);
    }

    public function events(WP_REST_Request $request): WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        return $this->success($this->engine->getAvailableEvents());
    }

    public function actions(WP_REST_Request $request): WP_REST_Response
    {
        if ($err = $this->guardLicense('free')) return $err;
        return $this->success($this->engine->getAvailableActions());
    }
}
