<?php
/**
 * 向客户端发送相应基类
 */
namespace app\api\controller;

use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\Response;
use think\response\Redirect;

trait Send
{

    /**
     * 默认返回资源类型
     * @var string
     */
    protected $restDefaultType = 'json';

    /**
     * 设置响应类型
     * @param null $type
     * @return $this
     */
    public function setType($type = null)
    {
        $this->type = (string)(!empty($type)) ? $type : $this->restDefaultType;
        return $this;
    }

    /**
     * 失败响应
     * @param int $error
     * @param string $message
     * @param int $code
     * @param array $data
     * @param array $headers
     * @param array $options
     * @return Response|\think\response\Json|\think\response\Jsonp|\think\response\Xml
     */
    public function sendError($error = 400, $message = 'error', $code = 400, $data = [], $headers = [], $options = [])
    {
        $responseData['error'] = (int)$error;
        $responseData['message'] = (string)$message;
        if (!empty($data)) $responseData['data'] = $data;
        $responseData = array_merge($responseData, $options);
        return $this->response($responseData, $code, $headers);
    }

    /**
     * 成功响应
     * @param array $data
     * @param string $message
     * @param int $code
     * @param array $headers
     * @param array $options
     * @return Response|\think\response\Json|\think\response\Jsonp|Redirect|\think\response\Xml
     */
    public function render($code, $result = '')
    {

        header('Access-Control-Allow-Origin:*');
        header('Access-Control-Allow-Headers:token,content-type');
        // 组合返回数据
        http_response_code($code);
        session_start();
        if (is_array($result)) {
            foreach ((array)$result as $name => $data) {
                // (array)强制转化，增强程序的健壮性
                if (strpos($name, '.list')) {
                    // strrpos() - 查找字符串在另一字符串中最后一次出现的位置（区分大小写）
                    $model = trim(str_replace('.list', '', $name));
                    // 替换函数
                    foreach ((array)$data as $key => $value) {
                        $result[$name][$key] = $value;
                    }
                } else {
                    $model = trim($name);
                    $result[$name] = $data;
                }
            }
        }
        // 输出中文字符的时候会进行json格式转码
        echo json_encode(
            $result
            ,JSON_UNESCAPED_UNICODE);
        $result = null;
        unset($result);
        ob_flush();
        flush();
        session_destroy();
        exit();
    }

    public function sendSuccess($data = [], $code = 200, $headers = [], $options = [])
    {
        if(empty($data)) $responseData['data']="";
        if (!empty($data)) $responseData['data'] = $data;
            $responseData = array_merge($responseData, $options);
        return $this->response($responseData, $code, $headers);
    }

    /**
     * 重定向
     * @param $url
     * @param array $params
     * @param int $code
     * @param array $with
     * @return Redirect
     */
    public function sendRedirect($url, $params = [], $code = 302, $with = [])
    {
        $response = new Redirect($url);
        if (is_integer($params)) {
            $code = $params;
            $params = [];
        }
        $response->code($code)->params($params)->with($with);
        return $response;
    }

    /**
     * 响应
     * @param $responseData
     * @param $code
     * @param $headers
     * @return Response|\think\response\Json|\think\response\Jsonp|Redirect|\think\response\View|\think\response\Xml
     */
    public function response($responseData, $code, $headers)
    {
        if (!isset($this->type) || empty($this->type)) $this->setType();
        return Response::create($responseData, $this->type, $code, $headers);
    }

    /**
     * 如果需要允许跨域请求，请在记录处理跨域options请求问题，并且返回200，以便后续请求，这里需要返回几个头部。。
     * @param string|int $code 状态码
     * @param string $message 返回信息
     * @param array $data 返回信息
     * @param array $header 返回头部信息
     * @param string $reason
     * @param string $type
     *
     */
    public function returnMsg($code = '400', $data = [], $header = [], $type = "", $reason = "", $message = "")
    {
        switch ($code) {
            case 200:
                $error = "SUCCESS";
                break;
            case 400:
                $error['error']['type'] = "BAD REQUEST";
                $error['error']['reason'] = empty($reason) ? "param missing" : $reason;
                $error['error']['message'] = empty($message) ? "请求体不完整" : $message;
                break;
            case 401:
                $error['error']['type'] = empty($type) ? "AUTH ERROR" : $type;
                $error['error']['reason'] = empty($reason) ? "token error." : $reason;;
                $error['error']['message'] = empty($message) ? "鉴权失败" : $message;
                break;
            case 403:
                $error['error']['type'] = "Forbidden";
                $error['error']['reason'] = $reason;
                $error['error']['message'] = $message;
                break;
            case 405:
                $error['error']['reason'] = empty($reason) ? "Method Not Allowed " : $reason;
                $error['error']['message'] = empty($message) ? "资源请求类型有误" : $message;
                break;
            case 409:
                $error['error']['type'] = "Conflict";
                $error['error']['reason'] = "data already exists";
                $error['error']['message'] = $message;
                break;
            case 500:
                $error['error']['type'] = "Internal Server Error";
                $error['error']['reason'] = $reason;
                $error['error']['message'] = $message;
                break;
            case 404:
            default:
                $error['error']['type'] = "Not Found";
                $error['error']['reason'] = "url error.";
                $error['error']['message'] = "请求资源不存在";
                break;
        }

        if (!empty($data)) $error['error']['data'] = $data;
        // 发送头部信息
        foreach ($header as $name => $val) {
            is_null($val) ? header($name) : header($name . ':' . $val);
        }

        throw new HttpResponseException(json((object)$error, $code));
    }
}