package webScene

import (
	"encoding/json"
	"fmt"
	"reflect"
	"testing"

	"github.com/tidbcloud/qa-gourd/ProductService"
	"github.com/tidbcloud/qa-gourd/util"
)

type WebE2ECase struct {
	WebRequestInfo *ProductService.WebRequestInfo
	Reporter       util.AllureReporter
	URLInfoMap     map[string]ProductService.UrlInfo
	CaseList       []string
}

func (w *WebE2ECase) GetReporter() util.AllureReporter {
	return w.Reporter
}

func (w *WebE2ECase) SetReporter(t *testing.T) {
	w.Reporter.T = t
	w.WebRequestInfo.T = t
}

func (w *WebE2ECase) SetCaseList(caseList []string) {
	w.CaseList = caseList
}

func (w *WebE2ECase) AnalyzeAPIInfo() {
	w.URLInfoMap = ProductService.MapURLInfo(ProductService.GetUrlInfo("../conf/urlConfig.csv"))
}

func (w *WebE2ECase) GetUserInfo() *ProductService.User {
	return w.WebRequestInfo.User
}

func (w *WebE2ECase) GetClusterInfo() *ProductService.Cluster {
	return w.WebRequestInfo.Cluster
}

func (w *WebE2ECase) DeleteCluster() {
	w.WebRequestInfo.DeleteCluster()
}

func (w *WebE2ECase) DeleteClusterById(clusterId string) {
	w.WebRequestInfo.DeleteClusterById(clusterId)
}

// check scene's bils, you only need to send msg to ch in your scene cases.
/*
   ProductService.SendClusterCostQuantityToCh(w *WebRequestInfo, event string, cost decimal.Decimal)
   ProductService.SendClusterPriceToCh(w *WebRequestInfo, event string, isPaused ...bool)
   ProductService.SendClusterCostQuantityAndPriceToCh(w *WebRequestInfo, event string, cost decimal.Decimal, isPaused ...bool)
   ProductService.SendCategoryCostQuantityToCh(w *WebRequestInfo, event string, categoryCost map[string]decimal.Decimal)
   ProductService.SendCategoryPriceToCh(w *WebRequestInfo, event string, categoryPrice map[string]decimal.Decimal)
   ProductService.SendClusterComponentPriceToCh(w *WebRequestInfo, event string, clusterFeeBody *ProductModel.ClusterFee)
   ProductService.SendClusterBillsCheckToCh(w *WebRequestInfo)
   ProductService.SendQuitSceneBillsCheckToCh()
*/
func (w *WebE2ECase) SceneBillsCheckBeta(t *testing.T) {
	t.Parallel()
	w.Reporter.T = t
	w.Reporter.SceneReport(func() {
		w.WebRequestInfo.SceneBillsCheckChDistribute(w.Reporter)
	})
}

func (w *WebE2ECase) CallFunctionByName(funcName string, args ...interface{}) {
	// 获取对象的值信息
	objValue := reflect.ValueOf(w)

	// 获取对象的方法
	method := objValue.MethodByName(funcName)

	// 检查方法是否存在
	if method.IsValid() {
		// 准备方法调用的参数
		methodArgs := make([]reflect.Value, len(args))
		for i, arg := range args {
			methodArgs[i] = reflect.ValueOf(arg)
		}

		// 调用方法
		method.Call(methodArgs)
	} else {
		fmt.Printf("Method %s not found\n", funcName)
	}
}

func (w *WebE2ECase) DeepCopy() *WebE2ECase {
	// 序列化原始对象
	jsonData, err := json.Marshal(w)
	if err != nil {
		fmt.Println("Error marshaling JSON:", err)
		return nil
	}
	var dst *WebE2ECase
	// 反序列化为目标对象
	err = json.Unmarshal(jsonData, &dst)
	if err != nil {
		fmt.Println("Error unmarshaling JSON:", err)
		return dst
	}
	return dst
}
