<?php

namespace App\Http\Controllers;

use App\Api\Controllers\ApiResponse;
use App\Models\User;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use XuanChen\Coupon\Coupon;

class ToolsController extends Controller
{

    use ApiResponse;

    public $baseUrl;

    public function __construct()
    {
        $this->baseUrl = env('BASE_URL');
    }

    /**
     * Notes: 发券
     *
     * @Author: 玄尘
     * @Date  : 2020/6/29 13:57
     * @param  \Illuminate\Http\Request  $request
     * @return mixed
     */
    public function grant(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'outletId'   => 'required',
            'activityId' => 'required',
            'mobile'     => 'required',
        ], [
            'outletId.required'   => '缺少网点编号',
            'activityId.required' => '缺少活动编号',
            'mobile.required'     => '缺少手机号',
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $outlet     = User::where('outlet_id', $request->outletId)->first();
        $this->user = $outlet->parent;

        $input_data = [
            'outletId'   => $request->outletId,
            'activityId' => $request->activityId,
            'mobile'     => $request->mobile,
        ];
        $url        = $this->baseUrl.'user/grant';

        return $this->getResult($input_data, $url);

    }

    /**
     * Notes: 查询
     *
     * @Author: 玄尘
     * @Date  : 2021/4/25 9:57
     * @param  \Illuminate\Http\Request  $request
     * @return mixed
     */
    public function query(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'outletId'       => 'required',
            'redemptionCode' => 'required',
        ], [
            'outletId.required'       => '缺少网点编号',
            'redemptionCode.required' => '缺少券码',
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $outlet     = User::where('outlet_id', $request->outletId)->first();
        $this->user = $outlet->parent;

        $input_data = [
            'outletId'       => $request->outletId,
            'redemptionCode' => $request->redemptionCode,
        ];

        $url = $this->baseUrl.'user/query';

        return $this->getResult($input_data, $url);

    }

    /**
     * Notes: 卡券作废
     *
     * @Author: 玄尘
     * @Date  : 2021/4/25 10:08
     * @param  \Illuminate\Http\Request  $request
     */
    public function destroy(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'outletId'       => 'required',
            'redemptionCode' => 'required',
        ], [
            'outletId.required'       => '缺少网点编号',
            'redemptionCode.required' => '缺少券码',
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $outlet     = User::where('outlet_id', $request->outletId)->first();
        $this->user = $outlet->parent;

        $input_data = [
            'outletId'       => $request->outletId,
            'redemptionCode' => $request->redemptionCode,
        ];

        $url = $this->baseUrl.'user/destroy';

        return $this->getResult($input_data, $url);
    }

    /**
     * Notes: 核销
     *
     * @Author: 玄尘
     * @Date  : 2020/6/29 14:01
     */
    public function verify(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'redemptionCode' => 'required',
            'total'          => 'required',
            'outletId'       => 'required',
            //            'orderid'        => 'required',
            //            'from'           => 'required',
        ], [
            'redemptionCode.required' => '缺少券码',
            'total.required'          => '缺少订单金额',
            'outletId.required'       => '缺少网点id',
            'orderid.required'        => '缺少订单id',
            'from.required'           => '缺少来源',
        ]);

        if ($validator->fails()) {
            return $this->error($validator->errors()->first());
        }

        $outlet     = User::where('outlet_id', $request->outletId)->first();
        $this->user = $outlet->parent;

        $input_data = [
            'outletId'       => $request->outletId,
            'redemptionCode' => $request->redemptionCode,
            'total'          => $request->total,
            'orderid'        => $request->orderid ?? '',
            'from'           => $request->from ?? '',
        ];

        $url = $this->baseUrl.'user/freezecoupon';

        return $this->getResult($input_data, $url);

    }

    /**
     * Notes: 总执行
     *
     * @Author: 玄尘
     * @Date  : 2021/4/25 10:00
     * @param $data
     * @param $url
     * @return array
     */
    public function getResult($data, $url): array
    {
        $data = $this->encrypt($data);

        $res = $this->http($data, $url);

        $response = [
            'getElapsedTime' => $this->getElapsedTime(),
            'getMemoryUsage' => $this->getMemoryUsage(),
            'ret'            => $res,
            'api_input_data' => $this->api_input_data,
            'raw_data'       => $this->decode($res),
        ];

        return $response;
    }

    public function http($data, $url)
    {
        $client   = new Client();
        $response = $client->request('POST', $url,
            [
                'form_params' => $data,
                'http_errors' => false,
            ]);

        $body    = $response->getBody();
        $content = $body->getContents();
        $result  = json_decode($content, true);

        return $result;
    }

    /**
     * Notes: 加密
     *
     * @Author: 玄尘
     * @Date  : 2021/4/25 9:46
     * @param $input
     * @return array
     */
    public function encrypt($input): array
    {
        $jsonData = json_encode($input);                     //数据JSON化
        $ascdata  = $this->keyasc($jsonData);                //加密
        $addcode  = sprintf("%08d", mt_rand(0, 99999999));   //随机code 验证签名用
        $sign     = $this->keysign($ascdata, $addcode);

        $data                 = [
            'server_id' => $this->user->server_id,
            'key'       => $this->user->server_key,
            'addcode'   => $addcode,
            'sign'      => $sign,
            'data'      => $ascdata,
        ];
        $this->api_input_data = $data;
        return $data;
    }

    /**
     * Notes: 解密
     *
     * @Author: 玄尘
     * @Date  : 2021/4/25 10:07
     * @param $res
     * @return mixed
     */
    public function decode($res)
    {
        if (isset($res['data'])) {
            $res = $this->keydesc($res['data']);

            return json_decode($res);
        }

        return '';

    }

    /***
     * Notes: 使用的内存
     *
     * @Author: 玄尘
     * @Date  : 2021/4/25 9:45
     * @param  int  $precision
     * @return string
     */
    public function getMemoryUsage($precision = 2): string
    {
        $size = memory_get_usage(true);

        $unit = ['b', 'kb', 'mb', 'gb', 'tb', 'pb'];

        return round($size / pow(1024, ($i = floor(log($size, 1024)))), $precision).' '.$unit[$i];
    }

    /**
     * Notes: 代码执行时间
     *
     * @Author: 玄尘
     * @Date  : 2021/4/25 9:45
     * @param  int  $decimals
     * @return string
     */
    public function getElapsedTime(int $decimals = 2): string
    {
        return number_format(microtime(true) - request()->server('REQUEST_TIME_FLOAT'), $decimals).' s';
    }

}