<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/6/13
 * Time: 9:53
 */
namespace Modules\Base\Services;

use Modules\Base\Entities\Openid;
use Modules\Base\Entities\User;
use SMG\Support\Traits\HasHttpRequest;

class OpenloginService extends BaseService
{
    use HasHttpRequest;

    public function __construct(Openid $openid, UserService $userService)
    {
        $this->model = $openid;
        $this->userService = $userService;
    }

    public static function getTypes()
    {
        return ['wx_mini', 'test'];
    }

    /**
     * @param $type
     * @param array $data
     *
     * @throws \Throwable
     *
     * @return \Modules\Base\Entities\User
     */
    public function login($type, $data = [])
    {
        throw_unless(
            in_array($type, self::getTypes()),
            \Illuminate\Validation\ValidationException::withMessages([
                'type' => ['错误的登陆类型'],
            ])
        );

        $openid_data = [];
        $openid = $this->getOpenid($type, $data, $openid_data);

        $account_type = $type == 'wx_mini' ? 'weixin' : $type;

        return $this->userService->openUser($account_type, $openid, $data, $openid_data);
    }

    /**
     * @param $type
     * @param $data
     * @param $openid_data
     *
     * @throws \Throwable
     *
     * @return mixed
     */
    public function getOpenid($type, &$data, &$openid_data)
    {
        if ($type == 'wx_mini') {
            $app = app('wechat.mini_program');
            $result = $app->auth->session($data['code']);
            if (isset($result['errcode'])) {
                throw \Illuminate\Validation\ValidationException::withMessages([
                    'code' => [$result['errmsg']],
                ]);
            }

            if (isset($result['unionid'])) {
                $result['origin_openid'] = $result['openid'];
            }

            $openid_data['session_key'] = $result['session_key'];

            return $result['unionid'] ?? $result['openid'];
        } elseif ($type == 'test') {
            return $data['code'];
        }
    }

    /**
     * 小程序解密数据
     *
     * @param $iv
     * @param $encryptData
     * @param int $user_id
     *
     * @return bool|array
     */
    public function decryptData($iv, $encryptData, $user_id = 0)
    {
        $user_id || $user_id = auth()->id();

        if (!$user_id) {
            return false;
        }

        $openid = $this->model->where('user_id', $user_id)->where('type', 'weixin')->first();
        $session_key = array_get($openid, 'session_key');
        if (!$session_key) {
            return false;
        }
        $app = app('wechat.mini_program');
        $decryptedData = $app->encryptor->decryptData($session_key, $iv, $encryptData);
        if ($decryptedData && isset($decryptedData)) {
            return $decryptedData;
        }

        return false;
    }

    public function userOpenid($user_id = null, $errthrow = true)
    {
        $user = $user_id ? (($user_id instanceof User) ? $user_id : User::find($user_id)) : auth()->user();
        //暂时从用户 ext.openid获取
        $openid = array_get($user, 'ext.openid', false);
        throw_if(!$openid && $errthrow, new \Exception('用户OPENID不存在'));

        return $openid;
    }
}
