// SaaS授权系统 - Go语言客户端
//
// 使用说明：
// 1. 修改 API_KEY 为您的真实API密钥
// 2. 在您的项目中导入此包
// 3. 调用验证：client.Verify("AUTH_CODE")
//
// 依赖：go get -u net/http, encoding/json, time
//
// @author 授权系统
// @version 1.0.0

package authorization

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"sync"
	"time"
)

// ==================== 配置区 ====================

// API密钥（从开发者中心获取）
// 网址：https://kuio.cn/user/developer
const DefaultAPIKey = "your_api_key_here"

// API接口地址
const BaseURL = "https://kuio.cn/api/saas"

// ==================== 数据结构 ====================

// AuthResult 授权验证结果
type AuthResult struct {
	Success   bool   `json:"success"`
	Message   string `json:"message"`
	Data      string `json:"data"`
	FromCache bool   `json:"from_cache"`
	Code      int    `json:"code"`
	HTTPCode  int    `json:"http_code"`
}

// verifyRequest API请求体
type verifyRequest struct {
	AuthCode string `json:"authcode"`
	Domain   string `json:"domain,omitempty"`
	IP       string `json:"ip,omitempty"`
}

// verifyResponse API响应体
type verifyResponse struct {
	Code int    `json:"code"`
	Msg  string `json:"msg"`
	Data string `json:"data"`
}

// cacheItem 缓存项
type cacheItem struct {
	data      string
	timestamp time.Time
}

// ==================== 客户端 ====================

// AuthorizationClient 授权客户端
type AuthorizationClient struct {
	APIKey        string
	BaseURL       string
	HTTPClient    *http.Client
	CacheEnabled  bool
	CacheDuration time.Duration
	cache         sync.Map // 并发安全的缓存
}

// NewAuthorizationClient 创建新的授权客户端实例
func NewAuthorizationClient(apiKey string) *AuthorizationClient {
	if apiKey == "" {
		apiKey = DefaultAPIKey
	}
	return &AuthorizationClient{
		APIKey:        apiKey,
		BaseURL:       BaseURL,
		HTTPClient:    &http.Client{Timeout: 10 * time.Second},
		CacheEnabled:  true,
		CacheDuration: 30 * time.Minute,
	}
}

// Verify 验证授权（带缓存）
func (c *AuthorizationClient) Verify(authCode string) (*AuthResult, error) {
	return c.VerifyWithDomain(authCode, "", "")
}

// VerifyWithDomain 验证授权（带域名和IP）
func (c *AuthorizationClient) VerifyWithDomain(authCode, domain, ip string) (*AuthResult, error) {
	// 1. 尝试从缓存读取
	if c.CacheEnabled {
		if cached, ok := c.cache.Load(authCode); ok {
			item := cached.(cacheItem)
			if time.Since(item.timestamp) < c.CacheDuration {
				return &AuthResult{
					Success:   true,
					Message:   "授权验证成功（缓存）",
					Data:      item.data,
					FromCache: true,
				}, nil
			}
			c.cache.Delete(authCode)
		}
	}

	// 2. 调用API验证
	result, err := c.verifyFromApi(authCode, domain, ip)
	if err != nil {
		return nil, err
	}

	// 3. 成功则写入缓存
	if result.Success && c.CacheEnabled {
		c.cache.Store(authCode, cacheItem{
			data:      result.Data,
			timestamp: time.Now(),
		})
	}

	return result, nil
}

// verifyFromApi 从API验证授权
func (c *AuthorizationClient) verifyFromApi(authCode, domain, ip string) (*AuthResult, error) {
	url := c.BaseURL + "/verify"

	reqBody := verifyRequest{
		AuthCode: authCode,
		Domain:   domain,
		IP:       ip,
	}

	jsonData, err := json.Marshal(reqBody)
	if err != nil {
		return nil, fmt.Errorf("JSON序列化失败: %w", err)
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		return nil, fmt.Errorf("创建请求失败: %w", err)
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("X-API-Key", c.APIKey)
	req.Header.Set("User-Agent", "Go-AuthClient/1.0")

	resp, err := c.HTTPClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("请求失败: %w", err)
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)

	var respData verifyResponse
	json.Unmarshal(body, &respData)

	if resp.StatusCode == 200 && respData.Code == 0 {
		return &AuthResult{
			Success:  true,
			Message:  respData.Msg,
			Data:     respData.Data,
			HTTPCode: resp.StatusCode,
		}, nil
	}

	return &AuthResult{
		Success:  false,
		Message:  respData.Msg,
		Code:     respData.Code,
		HTTPCode: resp.StatusCode,
	}, nil
}

// ClearCache 清除缓存
func (c *AuthorizationClient) ClearCache() {
	c.cache.Range(func(key, value interface{}) bool {
		c.cache.Delete(key)
		return true
	})
}

// Check 快速检查授权是否有效
func (c *AuthorizationClient) Check(authCode string) (bool, error) {
	result, err := c.Verify(authCode)
	if err != nil {
		return false, err
	}
	return result.Success, nil
}

// String 格式化输出
func (r *AuthResult) String() string {
	return fmt.Sprintf("AuthResult{Success=%v, Message=%q, FromCache=%v}", r.Success, r.Message, r.FromCache)
}

/*
// ========== 使用示例 ==========

package main

import (
	"fmt"
	authorization "your-module-path/authorization"
)

func main() {
	// 创建客户端
	client := authorization.NewAuthorizationClient("your_api_key_here")

	// 示例1：基础验证
	result, err := client.Verify("ABC123XYZ")
	if err != nil {
		fmt.Println("❌ 请求错误:", err)
		return
	}

	if result.Success {
		fmt.Println("✅ 授权验证成功！")
		fmt.Println("消息:", result.Message)
		fmt.Println("数据:", result.Data)
	} else {
		fmt.Println("❌ 授权验证失败:", result.Message)
	}

	// 示例2：带域名的验证
	result2, err := client.VerifyWithDomain("ABC123XYZ", "example.com", "")

	// 示例3：快速检查
	if ok, _ := client.Check("CODE"); ok {
		fmt.Println("✅ 授权有效")
	}

	// 示例4：清除缓存
	client.ClearCache()
}
*/
