package model

import (
	"ehttp/http"
	"encoding/json"
	"epur-pay/pkg/logger"
	"epur-pay/pkg/tools"
	"epur-pay/pkg/utils"
	"errors"
	"fmt"
	"github.com/deatil/go-array/array"
	"github.com/golang-module/carbon/v2"
	"github.com/shopspring/decimal"
	"strconv"
)

type Http struct {
	Url          string           `json:"url"`          // 请求地址
	Method       string           `json:"method"`       // 请求方法
	RequestType  http.RequestType `json:"requestType"`  // 请求类型 http.RequestType
	Query        []HttpParams     `json:"query"`        // 请求参数
	Body         []HttpParams     `json:"body"`         // 请求参数
	ResponseType string           `json:"responseType"` // 返回类型
}

func (p *Http) Do() (*http.Request, error) {
	req := http.New(
		http.WithMethod(p.Method),
		http.WithRequestType(p.RequestType),
		http.WithUrl(p.Url),
	)

	allValues := map[string]any{}

	if len(p.Body) > 0 {
		for idx := range p.Body {
			if p.Body[idx].DataType != "event" {
				if value, ok := p.Body[idx].Get1(); !ok {
					return req, errors.New(fmt.Sprintf("[%s]:类型不匹配", p.Body[idx].Field))
				} else {
					req.SetBody(p.Body[idx].Field, value)
					allValues[p.Body[idx].Field] = value
				}
			}
		}
	}

	if len(p.Query) > 0 {
		for idx := range p.Query {
			if p.Query[idx].DataType != "event" {
				if value, ok := p.Query[idx].Get1(); !ok {
					return req, errors.New(fmt.Sprintf("[%s]:类型不匹配", p.Query[idx].Field))
				} else {
					allValues[p.Query[idx].Field] = value
					req.QueryParams.Add(p.Query[idx].Field, http.ConvertToString(value))
				}
			}

		}
	}

	logger.AccessLogger.Infoln(utils.ToJson(&allValues))
	if len(p.Body) > 0 {
		for idx := range p.Body {
			if p.Body[idx].DataType == "event" {
				values := make([]interface{}, 0)

				BodyValues := p.Body[idx].Value.Value.([]any)

				logger.AccessLogger.Infoln(utils.ToJson(&BodyValues))

				for index := range BodyValues {
					logger.AccessLogger.Infoln(BodyValues[index].(string), array.Get(allValues, BodyValues[index].(string)))
					values = append(values, array.Get(allValues, BodyValues[index].(string)))
				}
				logger.AccessLogger.Infoln(utils.ToJson(&values))
				v := (&tools.Api{
					Tools:  p.Body[idx].Value.Tools,
					Values: values,
				}).Run()
				allValues[p.Body[idx].Field] = v
				req.SetBody(p.Body[idx].Field, v)
			}
		}
	}

	if len(p.Query) > 0 {
		for idx := range p.Query {
			if p.Query[idx].DataType == "event" {
				values := make([]interface{}, 0)
				for _, item := range p.Query[idx].Value.Value.([]interface{}) {
					values = append(values, array.Get(allValues, item.(string)))
				}
				v := (&tools.Api{
					Tools:  p.Query[idx].Value.Tools,
					Values: values,
				}).Run()
				allValues[p.Query[idx].Field] = v
				req.SetBody(p.Query[idx].Field, v)
			}
		}
	}

	if err := req.Do(); err != nil {
		return nil, err
	}
	return req, nil
}

type HttpParams struct {

	/*
		DataType:
			array      // 数组
			object 	   // 对象
			string	   // 字符串
			int64      // 整型
			float64	   // 浮点
			decimal	   // 金额
			dataTime   // 时间类型
			timeStamp  // 时间戳
			file 	   // 文件类型
			event 	   // 事件
			pool       // 参数池
			customPool // 自定义参数池
	*/

	Field    string          `json:"field"`
	Value    HttpParamsValue `json:"value"`
	DataType string          `json:"dataType"` // 数据类型
}

type HttpParamsValue struct {
	Value interface{} `json:"value"`
	Tools string      `json:"tools,omitempty"` // 如果是事件 那么这里是工具选择
}

func (p *HttpParams) Get() interface{} {
	row, _ := p.Get1()
	return row
}

func (p *HttpParams) Get1() (interface{}, bool) {

	switch p.DataType {
	case "string":
		row, ok := p.Value.Value.(string)
		return row, ok
	case "int64":
		if row, ok := p.Value.Value.(string); !ok {
			return nil, false
		} else {
			if row1, err := strconv.ParseInt(row, 10, 64); err != nil {
				return nil, false
			} else {
				return row1, true
			}
		}
	case "float64":
		row, ok := p.Value.Value.(float64)
		return row, ok
	case "decimal":
		if row, ok := p.Value.Value.(string); ok {
			if row1, err1 := decimal.NewFromString(row); err1 == nil {
				return row1, true
			} else {
				return nil, false
			}
		} else {
			return row, ok
		}
	case "object":
		if b, err := json.Marshal(p.Value.Value); err != nil {
			return nil, false
		} else {
			row := make([]HttpParams, 0)
			if err1 := json.Unmarshal(b, &row); err1 != nil {
				return nil, false
			}
			result := map[string]interface{}{}
			for _, item := range row {
				if row1, ok := item.Get1(); !ok {
					return nil, false
				} else {
					result[item.Field] = row1
				}
			}
			return result, true
		}
	case "array":
		if b, err := json.Marshal(p.Value.Value); err != nil {
			return nil, false
		} else {
			row := make([]HttpParams, 0)
			if err1 := json.Unmarshal(b, &row); err1 != nil {
				return nil, false
			}
			result := make([]interface{}, 0)
			for _, item := range row {
				if row1, ok := item.Get1(); !ok {
					return nil, false
				} else {
					result = append(result, row1)
				}
			}
			return result, true
		}
	case "dataTime":
		if row, ok := p.Value.Value.(string); !ok {
			return nil, false
		} else {
			return carbon.Now().Format(row), true
		}
	case "timeStamp":
		if row, ok := p.Value.Value.(string); !ok {
			return nil, false
		} else {
			switch row {
			case "0":
				return carbon.Now().Timestamp(), true
			case "1":
				return carbon.Now().TimestampMilli(), true
			case "2":
				return carbon.Now().TimestampMicro(), true
			case "3":
				return carbon.Now().TimestampNano(), true
			default:
				return nil, false
			}
		}
		//case "event":
		//	var value interface{}
		//	var ok bool
		//
		//	lastHttpParams := HttpParams{}
		//	routers := strings.Split(p.Value.Value.(string), ".")
		//
		//	if lastHttpParams.DataType == "" {
		//		for idx := range EventValues {
		//			if routers[0] == EventValues[idx].Field {
		//				lastHttpParams = EventValues[idx]
		//			}
		//		}
		//	}
		//
		//	if lastHttpParams.DataType == "" {
		//		return nil, false
		//	}
		//
		//	if value, ok = lastHttpParams.Get1(EventValues); !ok {
		//		return nil, ok
		//	}
		//
		//	value = array.Get(value, strings.Join(routers[1:], "."))
		//	return value, ok
	}

	return nil, false
}

/*
	请求事件
*/

//type HttpEvents []HttpEvent
//
//type HttpEvent struct {
//
//	/*
//		工具选择
//			MD5
//			AES
//			RSA
//			SORT // 排序工具
//	*/
//	EventName string    `json:"eventName"` // 事件名称
//	Tools     HttpTools `json:"tools"`     // 工具选择
//}

//type HttpTools struct {
//	Field  string   `json:"field"`
//	Inputs []string `json:"inputs,omitempty"` // 传参 HttpParams中的Field
//}

/*
	回调
*/

type HttpCallback struct {
	White        ArryString   `json:"white"`        // 白名单
	ResponseType string       `json:"responseType"` // 回调类型
	Query        []HttpParams `json:"query"`        // 回调参数
	Body         []HttpParams `json:"body"`         // 回调参数
}