<?php

namespace App\Http\Controllers\Miniprogram;

use App\Exceptions\AlertException;
use App\Jobs\WelcomeJob;
use App\Models\Common\FormidModel;
use App\Models\Log\FpdxMiniprogramIntoQueueModel;
use App\Models\User\Openid;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Redis;
use App\Models\Common\TokenModel;
use App\Models\User\AuthKey;
use Ixudra\Curl\Facades\Curl;

/**
 * Class Core
 * @package App\Http\Controllers\Miniprogram
 */
class Core extends Controller
{
    /**
     * 发送客服消息
     * @param  int  $uid  to用户uid
     * @param  array  $data
     * @return boolean
     * @throws \Exception
     */
    public function custom(int $uid = null, array $data)
    {
        $public_id = config('miniprogram.public_id');
        $authKey = new AuthKey();
        if (is_null($data['touser'])) {
            $openid = $authKey->getKeyOfType($uid, $public_id);
            $data['touser'] = $openid;
        }
        $access_token = TokenModel::getToken($public_id);
        $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$access_token}";
        $response = Curl::to($url)->withData(json_encode($data, JSON_UNESCAPED_UNICODE))->asJsonResponse()->post();
        if (isset($response->errcode) && 0 == $response->errcode) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 发送模板消息
     * @param  int  $uid  to用户uid
     * @param  string  $template_id
     * @param  string  $public_id
     * @param  string  $page
     * @param  array  $datas
     * @param  string  $page_type
     * @return bool
     */
    public function template(
        $uid,
        string $template_id,
        string $public_id,
        $page = null,
        array $datas = array(),
        string $page_type = "miniprogram"
    ) {
        try {
            $openid = Openid::ofPublic($uid, $public_id)->value('openid');
            $data = [
                'touser' => $openid,
                'template_id' => $template_id,
                'data' => $datas
            ];
            if ($page_type == "miniprogram") {
                $data['miniprogram'] = [
                    "appid" => "wx4c1722a4055bd229",
                    "pagepath" => $page,
                ];
            }
            if ($page_type == "h5") {
                $data['url'] = $page;
            }
            foreach ($datas as $key => $value) {
                $data['data'][$key] = array(
                    'value' => $value['value'],
                    'color' => $value['color'] ?? "#000000"
                );
            }
            $access_token = TokenModel::getToken($public_id);
            $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$access_token}";
            $response = \Curl::to($url)->withData($data)->asJson()->post();
            if (isset($response->errcode) && !$response->errcode) {
                return true;
            }
        } catch (\Exception $exception) {
        }
        return false;
    }


    public function miniTemplate(int $to_uid, string $template_id, string $public_id, $page, array $data)
    {
        $openid = AuthKey::where('uid', $to_uid)
            ->where('auth_type', $public_id)
            ->value('auth_key');

        if (empty($openid)) {
            return false;
        }

        $form = FormidModel::where([
            ['openid', $openid],
            ['public_id', $public_id],
            ['state', 0],
            ['created_at', '>', time() - 86400 * 6.5]
        ])->orderBy('created_at', 'asc')->first();
        if (collect($form)->isEmpty()) {
            return false;
        }
        $access_token = TokenModel::getToken($public_id);
        $url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token={$access_token}";
        $data = [
            'touser' => $form->openid,
            'template_id' => $template_id,
            'page' => $page,
            'form_id' => $form->form_id,
            'data' => $data
        ];
        $result = \Curl::to($url)->withData($data)->asJson()->post();
        $form->state = 1;
        $form->save();
        if (isset($result->errcode) && $result->errcode) {
            return false;
        }
        return true;
    }


    /**
     * 登录凭证校验
     * @param  string jscode
     * @return JsonResponse
     * {
     *      "openid": openid,
     *      "unionid": 有|没有,
     *      "session_key": 会话密钥
     * }
     * @throws \Exception
     */
    public function jscode2session(string $jscode)
    {
        $app_id = config('miniprogram.app_id');
        $app_secret = config('miniprogram.app_secret');
        $url = "https://api.weixin.qq.com/sns/jscode2session?appid={$app_id}&secret={$app_secret}&js_code={$jscode}&grant_type=authorization_code";
        $response = \Curl::to($url)->asJsonResponse()->get();
        if (isset($response->errcode)) {
            throw new AlertException($response->errmsg, $response->errcode);
        } else {
            try {
                if (!FpdxMiniprogramIntoQueueModel::where('openid', $response->openid)->exists()) {
                    WelcomeJob::dispatch($response->openid)->delay(Carbon::now()->addHours(1));

                    FpdxMiniprogramIntoQueueModel::create(['openid' => $response->openid, 'created_at' => time()]);
                }
            } catch (\Exception $exception) {
            }
            return $response;
        }
    }

    /**
     * 判断应用是否开启
     * @return array
     */
    public function isOpen()
    {
        $public_id = config('miniprogram.public_id');
        $is_open = Redis::hget("miniprogram:open", $public_id) ?? 1;
        return array(
            'code' => 200,
            'message' => 'success',
            'data' => $is_open
        );
    }

    /**
     * 获取B类二维码
     * @param  Request  $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     * @throws \Exception
     */
    public function getQrcodeB(Request $request)
    {
        $this->validate($request, [
            'scene' => 'required'
        ]);
        $public_id = config('miniprogram.public_id');
        $access_token = TokenModel::getToken($public_id);
        $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$access_token}";
        $data = [
            'scene' => urldecode($request->input('scene')),
            'width' => 430,
            'auto_color' => false,
            'line_color' => [
                'r' => 0,
                'g' => 0,
                'b' => 0,
            ],
            'is_hyaline' => false,
        ];
        $response = \Curl::to($url)->withData($data)->asJsonRequest()->post();
        if (isset($response->errcode) || isset($response['errcode'])) {
            app('sentry')->captureMessage("微信API调用异常", array(), array(
                'level' => 'info',
                'extra' => array(
                    'errcode' => $response->errcode,
                    'errmsg' => $response->errmsg
                )
            ));
        }
        return response($response, 200, ['Content-Type' => 'image/png']);
    }


    /**
     * 判断应用是否开启
     * @param  string kolid
     * @return string url
     * @throws \Exception
     *
     */
    public function getKolQrcode(string $kolid)
    {
        $public_id = config('miniprogram.public_id');
        $access_token = TokenModel::getToken($public_id);
        $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token={$access_token}";
        $data = [
            'scene' => "media_id={$kolid}",
            'width' => '430',
            'auto_color' => false,
            'line_color' => [
                'r' => 0,
                'g' => 0,
                'b' => 0,
            ],
            'is_hyaline' => false,
        ];
        $response = \Curl::to($url)->withData($data)->asJsonRequest()->post();
        return response($response, 200, ['Content-Type' => 'image/png']);
    }
}
