/**
 * Copyright (c) 2022 Yansen Zhang
 * wxcomponent is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
**/

package authorization

import (
	"errors"
	"net/url"
	"strconv"

	"gitee.com/yansen_zh/wxcomponent/config"
)

// AuthLinkParam 构建授权链接入参
type AuthLinkParam struct {
	ComponentAppId string
	PreAuthCode    string

	// RedirectUri 不需要转码
	RedirectUri string
	AuthType    int
	BizAppId    string
}

const (
	componentloginpage = "https://mp.weixin.qq.com/cgi-bin/componentloginpage"
	bindcomponent      = "https://mp.weixin.qq.com/safe/bindcomponent"
)

// GetPCAuthLink 构建PC端授权链接
func GetPCAuthLink(preAuthCode, redirectURI, bizAppID string, authType int) (string, error) {
	return GetAuthLink("PC", preAuthCode, redirectURI, bizAppID, authType)
}

// GetH5AuthLink 构建H5端授权链接
func GetH5AuthLink(preAuthCode, redirectURI, bizAppID string, authType int) (string, error) {
	return GetAuthLink("H5", preAuthCode, redirectURI, bizAppID, authType)
}

// GetAuthLink 构建授权链接
// redirectURI 回调地址必须是未经过处理的原始URL字符串
func GetAuthLink(client, preAuthCode, redirectURI, bizAppID string, authType int) (string, error) {
	isH5 := client == "H5"

	if preAuthCode == "" {
		return "", errors.New("构建授权链接 预授权码 不能为空")
	}

	if redirectURI == "" {
		return "", errors.New("构建授权链接 回调 URI 不能为空")
	}

	if authType < 1 || authType > 3 {
		authType = 3
	}

	queryParams := url.Values{}
	if isH5 {
		queryParams.Set("action", "bindcomponent")
		queryParams.Set("no_scan", "1")
	}
	queryParams.Set("component_appid", config.GetAppID())
	queryParams.Set("pre_auth_code", preAuthCode)
	queryParams.Set("redirect_uri", redirectURI)
	// auth_type、biz_appid 两个字段互斥
	if bizAppID != "" {
		queryParams.Set("biz_appid", bizAppID)
	} else {
		queryParams.Set("auth_type", strconv.Itoa(authType))
	}

	link := componentloginpage
	if isH5 {
		link = bindcomponent
	}

	link += "?" + queryParams.Encode()

	if isH5 {
		link += "#wechat_redirect"
	}

	return link, nil
}