// Package wrapper ...
//
// Description : wrapper ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2023-06-11 21:02
package wrapper

import (
	"encoding/json"
	"git.zhangdeman.cn/zhangdeman/op_type"
	"github.com/tidwall/gjson"
	"reflect"
	"strings"
)

// ArrayType 数组实例
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 21:03 2023/6/11
func ArrayType[Bt op_type.BaseType](value []Bt) *Array[Bt] {
	at := &Array[Bt]{
		value: value,
	}
	return at
}

// Array ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 21:05 2023/6/11
type Array[Bt op_type.BaseType] struct {
	value      []Bt
	convertErr error
	itemType   reflect.Kind // 简单list场景下, 每一项的数据类型
}

// IsNil 输入是否为nil
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 21:11 2023/6/11
func (at *Array[Bt]) IsNil() bool {
	return at.value == nil
}

// ToStringSlice ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:42 2024/4/22
func (at *Array[Bt]) ToStringSlice() []string {
	list := make([]string, 0)
	for _, item := range at.value {
		str := AnyDataType(item).ToString().Value()
		list = append(list, str)
	}
	return list
}

// Unique 对数据结果进行去重
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:43 2023/6/12
func (at *Array[Bt]) Unique() []Bt {
	result := make([]Bt, 0)
	dataTable := make(map[string]bool)

	for _, item := range at.value {
		byteData, _ := json.Marshal(item)
		k := string(byteData)
		if strings.HasPrefix(k, "\"\"") && strings.HasSuffix(k, "\"\"") {
			k = string(byteData[1 : len(byteData)-1])
		}
		if _, exist := dataTable[k]; exist {
			continue
		}
		dataTable[k] = true
		result = append(result, item)
	}
	return result

}

// Has 查询一个值是否在列表里, 在的话, 返回首次出现的索引, 不在返回-1
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:28 2023/7/31
func (at *Array[Bt]) Has(input Bt) int {
	for idx := 0; idx < len(at.value); idx++ {
		if reflect.TypeOf(at.value[idx]).String() != reflect.TypeOf(input).String() {
			// 类型不同
			continue
		}
		sourceByte, _ := json.Marshal(at.value[idx])
		inputByte, _ := json.Marshal(input)
		if string(sourceByte) != string(inputByte) {
			continue
		}
		return idx
	}
	return -1
}

// ToString ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 16:57 2023/9/28
func (at *Array[Bt]) ToString() StringResult {
	if at.IsNil() {
		return StringResult{
			Value: "",
			Err:   nil,
		}
	}
	byteData, err := json.Marshal(at.value)
	return StringResult{
		Value: string(byteData),
		Err:   err,
	}
}

// ToStringWithSplit 数组按照指定分隔符转为字符串
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 17:42 2023/10/25
func (at *Array[Bt]) ToStringWithSplit(split string) StringResult {
	if at.IsNil() {
		return StringResult{
			Value: "",
			Err:   nil,
		}
	}
	return StringResult{
		Value: strings.Join(at.ToStringSlice(), split),
		Err:   nil,
	}
}

// ExtraField 提取[]map/[]struct 中的指定字段, 并以list形式返回
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 19:00 2024/10/13
func (at *Array[Bt]) ExtraField(fieldName string) String {
	if at.IsNil() {
		return String("[]")
	}
	byteData, _ := json.Marshal(at.value)
	res := make([]any, 0)
	list := gjson.ParseBytes(byteData).Array()
	for _, item := range list {
		itemValue := item.Get(fieldName)
		if itemValue.Exists() {
			res = append(res, itemValue.Value())
		}
	}
	return String(ArrayType(res).ToString().Value)
}