<?php

namespace App\Http\Controllers\H5;

use App\Facades\WechatService;
use App\Http\Controllers\Controller;
use App\Http\Response\ResponseJson;
use App\Jobs\AddErrorLog;
use App\Models\ServiceUser;
use App\Models\User;
use App\Models\Version;
use App\Models\Wechat;
use Faker\Provider\pl_PL\LicensePlate;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Exception;

class WechatController extends Controller
{
    use ResponseJson;

    public function officialAuth($code, $target_path)
    {
        $redirect_url = request()->fullUrl();
        //增加授权日志
        $wechat_user = session('wechat_user');
        $openid = $wechat_user['id'] ?? null;
        if ($code) {
            $redirectUrl = WechatService::connectAuthByCode($code, $redirect_url);
            return $redirectUrl;
        }
        //        if (empty(session('wechat_user'))) {
        if (empty($openid)) {
            $redirectUrl = WechatService::connectAuth($redirect_url);
            return $redirectUrl;
        }
        return $target_path;
    }

    public function partnerAuth()
    {
        $target_path = '/h5/#/partnerInfo';
        $redirectUrl = $this->officialAuth(request()->code, $target_path);
        return redirect($redirectUrl);
    }

    public function agentAuth()
    {
        $target_path = '/h5/#/agentHome';
        $redirectUrl = $this->officialAuth(request()->code, $target_path);
        return redirect($redirectUrl);
    }

    public function memberAuth()
    {
        $target_path = '/h5/#/home';
        $redirectUrl = $this->officialAuth(request()->code, $target_path);
        return redirect($redirectUrl);
    }

    public function coachAuth()
    {
        $target_path = '/h5/#/coachInfo';
        $redirectUrl = $this->officialAuth(request()->code, $target_path);
        return redirect($redirectUrl);
    }

    public function financeAuth()
    {
        $target_path = '/h5/#/bindingFinance';
        $redirectUrl = $this->officialAuth(request()->code, $target_path);
        return redirect($redirectUrl);
    }

    public function wineCodeAuth(Request $request, $wine_code)
    {
        $target_path = config('app.url') . '/h5/#/bindingWine?wine_code=' . $wine_code;
        $redirectUrl = $this->officialAuth(request()->code, $target_path);
        Log::info("wineCodeAuth--$redirectUrl");
        return redirect($redirectUrl);
    }

    public function packCodeAuth(Request $request, $pack_code)
    {
        $target_path = config('app.url') . '/h5/#/bindingPackageWine?pack_code=' . $pack_code;
        $redirectUrl = $this->officialAuth(request()->code, $target_path);
        Log::info("packCodeAuth--$redirectUrl");
        return redirect($redirectUrl);
    }


    public function wechatAuth(Request $request)
    {
        //        $target_path = '/admin/#/h5/partnerInfo';
        $target_path = $request->input('target_path');
        $params = $request->all();
        unset($params['target_path']);
        $str = http_build_query($params);
        if ($str) {
            $target_path = $target_path . "&$str";
        }
        Log::info("wechatAuth----" . $target_path);
        $target_path = $target_path ? '/h5/#/' . $target_path : '/h5/#';
        $param = $request->all();
        unset($param['target_path']);
        $wechat_user = session('wechat_user');
        $openid = $wechat_user['id'] ?? null;
        //判断target_path是否存在openid
        if (strpos($target_path, 'open_id') === false) {
            $param['open_id'] = $openid;
        }
        //防止重复拼接
        if (!empty($param) && strpos($target_path, '?') === false) {
            $param = http_build_query($param);
            $target_path .= '?' . $param;
        }
        Log::info("wechatAuth1----" . $target_path);
        $redirectUrl = $this->officialAuth(request()->code, $target_path);

        Log::info("redirect_url----" . $redirectUrl);
        //        $message = 'wechatAuth微信授权 open_id:'.$openid.', code:'.request()->code.', target_path:'.$target_path.', redirect_url:'.$redirectUrl;
//        AddErrorLog::dispatch($message)->onQueue('health');
        // if (strpos($redirectUrl, "open.weixin.qq.com") === false) {
        //     $redirectUrl = config("app.url") . $redirectUrl;
        // }
        // Log::info("redirect_url----" . $redirectUrl);

        return redirect($redirectUrl);
    }

    //    public function orderCommentAuth()
//    {
//        $target_path = '/admin/#/h5/remarks';
//        $redirectUrl = $this->officialAuth(request()->code, $target_path);
//        return redirect($redirectUrl);
//    }

    public function workJsSdkConfig()
    {
        $url = request()->input('url', config('app.url'));
        $type = request()->input('type', 'work');
        $config = WechatService::workJsSdkConfig($url, $type);
        return $this->success('ok', $config);
    }

    public function workJsSdkConfigV2()
    {
        $start_time = microtime(true);
        Log::info("workJsSdkConfigV2 开始时间：" . $start_time);
        $url = request()->input('url', config('app.url'));
        $work_config = WechatService::workJsSdkConfig($url, 'work');
        $app_config = WechatService::workJsSdkConfig($url, 'app');

        $version = Version::where('type', Version::TYPE_WECOM)->orderBydesc('id')->value('version');
        Log::info("workJsSdkConfigV2 结束时间：" . microtime(true));
        Log::info("workJsSdlConfigV2 时长：" . round(microtime(true) - $start_time, 3));
        return $this->success('ok', compact('work_config', 'app_config', 'version'));
    }

    public function workJsSdkConfigV3()
    {
        $start_time = microtime(true);
        Log::info("workJsSdkConfigV2 开始时间：" . $start_time);
        $url = request()->input('url', config('app.url'));
        //        $work_config = WechatService::workJsSdkConfig($url, 'work');
//        $app_config = WechatService::workJsSdkConfig($url, 'app');
        $work_config = $app_config = [];

        Log::info("workJsSdkConfigV2 结束时间：" . microtime(true));
        Log::info("workJsSdlConfigV2 时长：" . round(microtime(true) - $start_time, 3));
        return $this->success('ok', compact('work_config', 'app_config'));
    }

    public function workAppAuth($code, $target_path)
    {
        $redirect_url = config('app.url') . '/' . request()->path();
        Log::info("redirect_url1----$redirect_url");
        if ($code) {
            $redirectUrl = WechatService::connectWorkAuthByCode($code);
            Log::info("redirect_url2---" . $redirectUrl);
            return $redirectUrl;
        }
        if (empty(session('work_wechat_user'))) {
            $redirectUrl = WechatService::connectWorkAuth($redirect_url);
            Log::info("redirect_url3---" . $redirectUrl);
            return $redirectUrl;
        }
        return $target_path;
    }

    public function workOrderCommentsAuth()
    {
        //        $target_path = '/admin/#/h5/remarks';
//        $target_path = '/h5/#/h5/serviceCentre';
        $target_path = '/h5/#/h5/serviceCentre';
        $redirectUrl = $this->workAppAuth(request()->code, $target_path);
        //        Log::info("redirect_url---".$redirectUrl);
        return redirect($redirectUrl);
    }

    public function workOrderBoundEnterprise()
    {
        Log::info("workOrderBoundEnterprise 开始时间：" . microtime(true));
        $target_path = '/h5/#/h5/boundEnterprise';
        $redirectUrl = $this->workAppAuth(request()->code, $target_path);
        Log::info("redirect_url---" . $redirectUrl);
        Log::info("workOrderBoundEnterprise 结束时间：" . microtime(true));

        return redirect($redirectUrl);
    }

    public function workOrderBoundEnterpriseV2(Request $request)
    {
        $path = $request->input('target_path', 'boundEnterprise');
        $target_path = "work/#/h5/" . $path;
        Log::info("workOrderBoundEnterprise target_path:" . $target_path . "path:" . $path . "开始时间：" . microtime(true));
        //        $target_path = '/work/#/h5/boundEnterprise';
        $redirectUrl = $this->workAppAuth(request()->code, $target_path);
        Log::info("redirect_url---" . $redirectUrl);
        Log::info("workOrderBoundEnterprise 结束时间：" . microtime(true));

        return redirect($redirectUrl);
    }

    public function workInvite()
    {
        $target_path = '/work/#/h5/invite';
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        return redirect($redirectUrl);
    }
    public function workViewInvite()
    {
        $target_path = '/work/#/h5/viewInvite';
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        return redirect($redirectUrl);
    }

    public function workInviteV2()
    {
        $target_path = '/work/#/h5/inviteV2';
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        return redirect($redirectUrl);
    }
    public function workViewInviteV2()
    {
        $target_path = '/work/#/h5/viewInviteV2';
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        return redirect($redirectUrl);
    }
    public function workInviteV3()
    {
        $target_path = '/work/#/h5/inviteV3';
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        return redirect($redirectUrl);
    }

    public function workViewInviteV3()
    {
        $target_path = '/work/#/h5/viewInviteV3';
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        return redirect($redirectUrl);
    }
    public function workInviteV4()
    {
        $target_path = '/work/#/h5/inviteV4';
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        return redirect($redirectUrl);
    }

    public function workViewInviteV4()
    {
        $target_path = '/work/#/h5/viewInviteV4';
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        return redirect($redirectUrl);
    }

    public function workTalkAuth(Request $request)
    {
        $id = $request->input('id');
        $path = $request->get('target_path');
        Log::info("workTalkAuth1--- id:" . $id . '|target_path:' . $path);
        if (!empty($path)) {
            $target_path = $path;
        } else {
            if (!empty($id)) {
                $target_path = '/work/#/h5/discussDetail?id=' . $id;
            } else {
                $target_path = '/work/#/h5/discussList';
            }
        }
        $target_path = urldecode($target_path);
        Log::info("workTalkAuth2--- id:" . $id . '|target_path:' . $target_path);
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        Log::info("workTalkAuth2--- id:" . $id . '|target_path:' . $target_path . '|redirectUrl' . $redirectUrl);
        return redirect($redirectUrl);
    }

    public function workAddAnnualMeeting()
    {
        $target_path = '/work/#/h5/addAnnualMeeting';
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        return redirect($redirectUrl);
    }

    public function workAllAnnualMeeting()
    {
        $target_path = '/work/#/h5/allAnnualMeeting';
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        return redirect($redirectUrl);
    }

    /**
     * 企业微信授权
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function userWorkAuth()
    {
        $start_time = time();
        $service_user_id = request()->service_user_id;
        $target_path = request()->target_path;
        //获取target_path里面的service_user_id,避免有特殊字符导致获取不到
        if (empty($service_user_id) && !empty($target_path)) {
            // 使用正则表达式匹配service_user_id的值
            preg_match('/service_user_id=(\d+)/', $target_path, $matches);
            if (isset($matches[1])) {
                $service_user_id = $matches[1];
            }
        }
        session(['service_user_id' => $service_user_id]);
        $target_path = '/admin/#/h5/bindUserInfor?service_user_id=' . $service_user_id;
        Log::info('原始目标链接--' . $target_path . '开始时间：' . $start_time);
        $redirectUrl = $this->workAuth(request()->code, $target_path, true);
        $end_time = time();
        Log::info('授权后目标链接--' . $redirectUrl . '结束时间：' . $end_time);
        return redirect($redirectUrl);
    }

    public function workAuth($code, $target_path, $is_work = false)
    {
        Log::info("workAuth: code:" . $code . '|target_path:' . $target_path);
        $redirect_url = config('app.url') . '/' . request()->path() . "?target_path=" . urlencode($target_path);
        $config = "work_application";
        if ($is_work) {
            $config = "work_health";
        }
        if ($code) {
            Log::info("workAuth1:" . $redirect_url);
            $redirect_url = WechatService::connectWorkAuthByCode($code, $config);
            return $redirect_url;
        }
        if (empty(session('work_wechat_user'))) {
            Log::info("workAuth2:" . $redirect_url);
            $redirect_url = WechatService::connectWorkAuth($redirect_url, $config);
            return $redirect_url;
        }
        Log::info("workAuth3:" . $redirect_url);
        return $target_path;
    }

    public function bindWorkUser(Request $request)
    {
        $service_user_id = session('service_user_id');
        $service_user_id = $service_user_id ?: $request->input('service_user_id');
        if (empty($service_user_id))
            throw new \Exception("未获取到后台服务用户ID");
        if (config('app.env') == 'production') {
            $work_user = session('work_wechat_user');
            if (empty($work_user))
                throw new \Exception("未授权企业微信用户");
            if (!isset($work_user['raw']['userid']))
                return $this->failure("请使用企业微信扫码绑定");
            $work_id = $work_user['raw']['userid'];
        } else {
            $work_id = 'Feng...';
        }
        $user = ServiceUser::find($service_user_id);
        if (empty($user))
            throw new \Exception("后台服务用户不存在, service_user_id=" . $service_user_id);
        if ($user->work_user_id && $user->work_user_id != $work_id)
            return $this->failure("该二维码已绑定其他用户");
        //是否多次绑定
        $count = ServiceUser::where('work_user_id', $work_id)
            ->where('id', '<>', $user->id)
            ->whereNotNull('mobile')
            ->whereNotNull('name')
            ->count();
        Log::info('bindWorkUser work_id:' . $work_id . '|service_user_id:' . $user->id);
        if ($count > 0)
            return $this->failure("该企业微信已绑定其他服务人员");
        if (empty($user->work_user_id)) {
            DB::beginTransaction();
            try {
                //将旧的，没有名字和手机号的置空,并更新wechat表
                ServiceUser::where('work_user_id', $work_id)->update(['work_user_id' => null]);
                Wechat::where('openid', $work_id)->where('type', 'work')->update(['user_id' => $user->user_id]);
                //将新数据更新
                ServiceUser::where('id', $service_user_id)->update(['work_user_id' => $work_id]);
                DB::commit();
            } catch (\Exception $e) {
                DB::rollBack();
            }
        }
        return $this->success('ok', $user);
    }

    public function bindWorkUserInfo(Request $request)
    {
        $service_user_id = session('service_user_id');
        //        Log::info($service_user_id);
        $service_user_id = $service_user_id ?: $request->input('service_user_id');
        if (empty($service_user_id))
            throw new \Exception("未获取到后台用户ID");
        if (config('app.env') == 'production') {
            $work_user = session('work_wechat_user');
            if (empty($work_user))
                throw new \Exception("未授权企业微信用户");
            if (!isset($work_user['raw']['userid']))
                return $this->failure("请使用企业微信扫码绑定");
        }
        Log::info("授权企业微信id=" . $service_user_id);
        $user = ServiceUser::find($service_user_id);
        if (empty($user))
            throw new \Exception("后台服务用户不存在, service_user_id=" . $service_user_id);
        return $this->success('ok', $user);
    }

    public function chatUrlLink(Request $request)
    {
        $chat_id = $request->input('chat_id');
        if (empty($chat_id))
            throw new \Exception("缺少参数群信息chat_id");
        $path = '/pages/service/healthMGT';
        $query = 'chatId=' . $chat_id . '&index=0';
        $url_link = WechatService::urlLink($path, $query);
        return $this->success('ok', compact('url_link'));
    }

    public function urlLink(Request $request)
    {
        $path = $request->input('path');
        $query = $request->input('query');
        $url_link = WechatService::urlLink($path, $query);
        return $this->success('ok', compact('url_link'));
    }

    public function getUrlLink(Request $request)
    {
        $url_link = $request->url_link;
        $url_link_info = WechatService::getUrlLink($url_link);
        return $this->success('ok', $url_link_info);
    }


    /**
     * 用户主动点击拉起非静默授权
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function newNonSilenceAuth(Request $request)
    {
        $code = $request->code;
        $jump_url = $request->jump_url ?? 'my';
        $appid = config('wechat.official_account.default.app_id');
        $secret = config('wechat.official_account.default.secret');
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $appid . "&secret=" . $secret . "&code=" . $code . "&grant_type=authorization_code";
        $result = http_get_request($url);
        $invite_user_id = urldecode($request->invite_user_id);
        if ($result && isset($result['access_token'])) {
            DB::beginTransaction();
            try {
                $wechat_user = Wechat::where('openid', $result['openid'])->first();
                if ($wechat_user) {
                    $url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $result['access_token'] . '&openid=' . $result['openid'];
                    $result = http_get_request($url);
                    Log::info("code 获取  wechat_user");
                    Log::info($result);
                    $user = User::where('id', $wechat_user->user_id)->first();
                    $user->name = $wechat_user->nickname = $result['nickname'] ?? $wechat_user->nickname;
                    if (in_array($result['sex'], [1, 2])) {
                        $user->sex = $result['sex'] ?? '';
                    }
                    $wechat_user->gender = $result['sex'] ?? '';
                    $wechat_user->city = $result['city'] ?? $wechat_user->city;
                    $wechat_user->country = $result['country'] ?? $wechat_user->country;
                    $user->avatar = $wechat_user->avatar = $result['headimgurl'] ?? $wechat_user->avatar;

                    $user->save();
                    $wechat_user->save();
                }
                DB::commit();
            } catch (Exception $e) {
                DB::rollback();
                throw new Exception($e);
            }
        }
        $redirect_url = env('APP_URL') . '/h5/#/' . $jump_url . '?invite_user_id=' . $invite_user_id;
        return redirect($redirect_url);
    }

    /**
     * 查看用户是否授权
     */
    public function getUserIsAuth()
    {
        try {
            $user = Auth()->user();
            $wechat_user_info = Wechat::where('user_id', $user->id)->where('type', 'official')->first();
            $status = false;
            if ($wechat_user_info->nickname) {
                $status = true;
            }
            return $this->success('ok', $status);
        } catch (Exception $e) {
            return $this->jsonResponse(1, $e->getMessage());
        }
    }
}
