<?php

declare(strict_types=1);

namespace app\support;

use support\Response;
use Webman\Http\Request as WebmanRequest;

use function response;

/**
 * 控制器基础类
 * - 适配 Webman Request 注入，子类方法签名：public function xxx(Webman\Http\Request $request)
 * - 移除对 think\App 的依赖，用注入的 $request 替代 $this->app->request
 * - 子类在方法开头调用 setRequest($request)，之后可用 $this->request 访问
 */
abstract class BaseController
{
    /**
     * 当前请求实例（由 setRequest($request) 设置，来源于方法参数 $request，非 think\App）
     * @var WebmanRequest|null
     */
    protected ?WebmanRequest $request = null;

    /**
     * 是否批量验证
     * @var bool
     */
    protected bool $batchValidate = false;

    /**
     * 初始化
     * @access protected
     */
    protected function initialize(): void
    {
    }

    /**
     * 设置当前请求（子类方法开头调用）
     * @param WebmanRequest $request
     */
    protected function setRequest(WebmanRequest $request): void
    {
        $this->request = $request;
    }

    /**
     * 操作成功（封装为返回 Response 的方法，替代原 $this->success() 抛异常）
     * @param string $msg    提示消息
     * @param mixed  $data   返回数据
     * @param int    $code   业务状态码（1=成功）
     * @param array  $header 可含 statusCode 指定 HTTP 状态
     */
    protected function success(string $msg = '', mixed $data = null, int $code = 1, array $header = []): Response
    {
        return $this->result($msg, $data, $code, $header);
    }

    /**
     * 操作失败（封装为返回 Response 的方法，替代原 $this->error() 抛异常）
     * @param string $msg    提示消息
     * @param mixed  $data   返回数据
     * @param int    $code   业务状态码（0=失败）
     * @param array  $header 可含 statusCode 指定 HTTP 状态（如 401、409）
     */
    protected function error(string $msg = '', mixed $data = null, int $code = 0, array $header = []): Response
    {
        return $this->result($msg, $data, $code, $header);
    }

    /**
     * 返回 API 数据（BuildAdmin 格式：code, msg, time, data）
     * 使用 response() 生成 JSON Response
     */
    protected function result(string $msg, mixed $data = null, int $code = 0, array $header = []): Response
    {
        // 统一对返回 msg 做多语言翻译：若 $msg 为语言 key（英文），则按请求语言输出；
        // 若无对应翻译，则保持原样返回。
        if ($msg !== '' && function_exists('__')) {
            $translated = __($msg);
            if (is_string($translated) && $translated !== '') {
                $msg = $translated;
            }
        }
        $body = [
            'code' => $code,
            'msg'  => $msg,
            'time' => time(),
            'data' => $data,
        ];

        $statusCode = $header['statusCode'] ?? 200;
        unset($header['statusCode']);

        $headers = array_merge(['Content-Type' => 'application/json'], $header);
        $options = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES;
        if (defined('JSON_INVALID_UTF8_SUBSTITUTE')) {
            $options |= JSON_INVALID_UTF8_SUBSTITUTE;
        }
        $jsonBody = json_encode($body, $options);
        if ($jsonBody === false) {
            $jsonBody = '{"code":0,"msg":"JSON encode error","time":' . time() . ',"data":[]}';
        }

        return response($jsonBody, $statusCode, $headers);
    }
}
