package service

import (
	"context"
	"crypto/ecdsa"
	"crypto/x509"
	"tydata-server/app/main/api/internal/config"
	"encoding/json"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"time"

	"github.com/golang-jwt/jwt/v4"
)

// ApplePayService 是 Apple IAP 支付服务的结构体
type ApplePayService struct {
	config config.ApplepayConfig // 配置项
}

// NewApplePayService 是一个构造函数，用于初始化 ApplePayService
func NewApplePayService(c config.Config) *ApplePayService {
	return &ApplePayService{
		config: c.Applepay,
	}
}
func (a *ApplePayService) GetIappayAppID(productName string) string {
	return fmt.Sprintf("%s.%s", a.config.BundleID, productName)
}

// VerifyReceipt 验证苹果支付凭证
func (a *ApplePayService) VerifyReceipt(ctx context.Context, receipt string) (*AppleVerifyResponse, error) {
	var reqUrl string
	if a.config.Sandbox {
		reqUrl = a.config.SandboxVerifyURL
	} else {
		reqUrl = a.config.ProductionVerifyURL
	}

	// 读取私钥
	privateKey, err := loadPrivateKey(a.config.LoadPrivateKeyPath)
	if err != nil {
		return nil, fmt.Errorf("加载私钥失败：%v", err)
	}

	// 生成 JWT
	token, err := generateJWT(privateKey, a.config.KeyID, a.config.IssuerID)
	if err != nil {
		return nil, fmt.Errorf("生成JWT失败：%v", err)
	}

	// 构造查询参数
	queryParams := fmt.Sprintf("?receipt-data=%s", receipt)
	fullUrl := reqUrl + queryParams

	// 构建 HTTP GET 请求
	req, err := http.NewRequestWithContext(ctx, http.MethodGet, fullUrl, nil)
	if err != nil {
		return nil, fmt.Errorf("创建 HTTP 请求失败：%v", err)
	}
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+token)

	// 发送请求
	client := &http.Client{Timeout: 10 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("请求苹果验证接口失败：%v", err)
	}
	defer resp.Body.Close()

	// 解析响应
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应体失败：%v", err)
	}

	var verifyResponse AppleVerifyResponse
	err = json.Unmarshal(body, &verifyResponse)
	if err != nil {
		return nil, fmt.Errorf("解析响应体失败：%v", err)
	}

	// 根据实际响应处理逻辑
	if verifyResponse.Status != 0 {
		return nil, fmt.Errorf("验证失败，状态码：%d", verifyResponse.Status)
	}

	return &verifyResponse, nil
}

func loadPrivateKey(path string) (*ecdsa.PrivateKey, error) {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}
	block, _ := pem.Decode(data)
	if block == nil || block.Type != "PRIVATE KEY" {
		return nil, fmt.Errorf("无效的私钥数据")
	}
	key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	ecdsaKey, ok := key.(*ecdsa.PrivateKey)
	if !ok {
		return nil, fmt.Errorf("私钥类型错误")
	}
	return ecdsaKey, nil
}

func generateJWT(privateKey *ecdsa.PrivateKey, keyID, issuerID string) (string, error) {
	now := time.Now()
	claims := jwt.RegisteredClaims{
		Issuer:    issuerID,
		IssuedAt:  jwt.NewNumericDate(now),
		ExpiresAt: jwt.NewNumericDate(now.Add(1 * time.Hour)),
		Audience:  jwt.ClaimStrings{"appstoreconnect-v1"},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
	token.Header["kid"] = keyID
	tokenString, err := token.SignedString(privateKey)
	if err != nil {
		return "", err
	}
	return tokenString, nil
}

// GenerateOutTradeNo 生成唯一订单号
func (a *ApplePayService) GenerateOutTradeNo() string {
	length := 16
	timestamp := time.Now().UnixNano()
	timeStr := strconv.FormatInt(timestamp, 10)
	randomPart := strconv.Itoa(int(timestamp % 1e6))
	combined := timeStr + randomPart

	if len(combined) >= length {
		return combined[:length]
	}

	for len(combined) < length {
		combined += strconv.Itoa(int(timestamp % 10))
	}

	return combined
}

// AppleVerifyResponse 定义苹果验证接口的响应结构
type AppleVerifyResponse struct {
	Status  int      `json:"status"`  // 验证状态码：0 表示收据有效
	Receipt *Receipt `json:"receipt"` // 收据信息
}

// Receipt 定义收据的精简结构
type Receipt struct {
	BundleID string      `json:"bundle_id"` // 应用的 Bundle ID
	InApp    []InAppItem `json:"in_app"`    // 应用内购买记录
}

// InAppItem 定义单条交易记录
type InAppItem struct {
	ProductID       string `json:"product_id"`              // 商品 ID
	TransactionID   string `json:"transaction_id"`          // 交易 ID
	PurchaseDate    string `json:"purchase_date"`           // 购买日期 (ISO 8601)
	OriginalTransID string `json:"original_transaction_id"` // 原始交易 ID
}
