package conv

import (
	_ "embed"
	"encoding/json"
	"errors"
	"fmt"
	"gadmin/utility"
	"io"
	"os"
	"os/exec"
	"sort"

	"github.com/sirupsen/logrus"
)

var Goods = new(cGoods)

type cGoods struct {
	version string
	lst     []*GoodItem
}

type GoodsSlice []*GoodItem

func (p GoodsSlice) Len() int {
	return len(p)
}

func (p GoodsSlice) Swap(i, j int) {
	p[i], p[j] = p[j], p[i]
}

func (p GoodsSlice) Less(i, j int) bool {
	return p[j].Value > p[i].Value
}

type GoodItem struct {
	Value int64  `json:"value"`
	Label string `json:"label"`
}

type GoodsItemer interface {
	GetId() int64
	GetName() string
}

type ShopGoodsItem struct {
	ID   int64  `json:"goods_id"`
	Name string `json:"name"`
}

func (d ShopGoodsItem) GetId() int64 {
	return d.ID
}
func (d ShopGoodsItem) GetName() string {
	return d.Name
}

type GiftItem struct {
	ID   int64  `json:"gift_id"`
	Name string `json:"gift_name"`
}

func (d GiftItem) GetId() int64 {
	return d.ID
}
func (d GiftItem) GetName() string {
	return d.Name
}

type LimitGiftItem struct {
	ID   int64  `json:"id"`
	Name string `json:"name"`
}

func (d LimitGiftItem) GetId() int64 {
	return d.ID
}
func (d LimitGiftItem) GetName() string {
	return d.Name
}

type EquipBoxBaseItem struct {
	ID   int64 `json:"goods_id"`
	Name int32 `json:"BoxType"`
}

func (d EquipBoxBaseItem) GetId() int64 {
	return d.ID
}
func (d EquipBoxBaseItem) GetName() string {
	return fmt.Sprintf("%v", d.Name)
}

type EquipBoxGiftItem struct {
	ID   int64  `json:"GiftPackID"`
	Name string `json:"PackName"`
}

func (d EquipBoxGiftItem) GetId() int64 {
	return d.ID
}
func (d EquipBoxGiftItem) GetName() string {
	return d.Name
}

type FirtstChargeItem struct {
	ID   int64  `json:"giftId"`
	Name string `json:"giftName"`
}

func (d FirtstChargeItem) GetId() int64 {
	return d.ID
}
func (d FirtstChargeItem) GetName() string {
	return d.Name
}

type PropStoreItem struct {
	ID   int64 `json:"Shop_ID"`
	Name int32 `json:"Item_Type"`
}

func (d PropStoreItem) GetId() int64 {
	return d.ID
}

func (d PropStoreItem) GetName() string {
	return fmt.Sprintf("%v", d.Name)
}

type WeekendGiftItem struct {
	ID   int64  `json:"gift_id"`
	Name string `json:"gift_name"`
}

func (d WeekendGiftItem) GetId() int64 {
	return d.ID
}
func (d WeekendGiftItem) GetName() string {
	return d.Name
}

type MonarchGiftRewardItem struct {
	ID   int64  `json:"shopId"`
	Name string `json:"shopName"`
}

func (d MonarchGiftRewardItem) GetId() int64 {
	return d.ID
}
func (d MonarchGiftRewardItem) GetName() string {
	return d.Name
}

type MonarchGift2Item struct {
	ID   int64  `json:"shopId"`
	Name string `json:"shopName"`
}

func (d MonarchGift2Item) GetId() int64 {
	return d.ID
}
func (d MonarchGift2Item) GetName() string {
	return d.Name
}

type ELPassportItem struct {
	ID   int64  `json:"GiftPackID"`
	Name string `json:"Name"`
}

func (d ELPassportItem) GetId() int64 {
	return d.ID
}
func (d ELPassportItem) GetName() string {
	return d.Name
}

type Holiday12GiftItem struct {
	ID   int64  `json:"gift_id"`
	Name string `json:"gift_name"`
}

func (d Holiday12GiftItem) GetId() int64 {
	return d.ID
}
func (d Holiday12GiftItem) GetName() string {
	return d.Name
}

type Cost struct {
	Id    int64 `json:"id"`
	Count int64 `json:"count"`
}

type ShopGoods struct {
	Id        int64  `json:"ID"`
	Name      string `json:"Name"`
	Cost      []Cost `json:"Cost"`
	GoodsType int    `json:"GoodsType"`
}

//go:embed resource/jsonConvert
var jsonConvert []byte

func (j *cGoods) webProduct() *cGoods {
	/*utility.CreateDir("./tmp")
	if _, err := os.Stat("./tmp/jsonConvert"); err != nil {
		tmpFile, err := os.Create("./tmp/jsonConvert")
		if err != nil {
			logrus.Errorln("创建jsonConvert失败", err)
			return j
		}
		if _, err := tmpFile.Write(jsonConvert); err != nil {
			logrus.Errorln("写入jsonConvert失败", err)
			return j
		}
		_ = tmpFile.Close()
		if err := os.Chmod("./tmp/jsonConvert", 0755); err != nil {
			logrus.Errorln("修改jsonConvert权限失败", err)
			return j
		}
	}*/

	// 执行jsonConvert,生成webproduct.json文件并放到resource/public/json/下
	/*cmd := exec.Command("./jsonConvert", fmt.Sprintf("-v=%s", j.version), fmt.Sprintf("-m=%s", os.Getenv("JSONCONVERTiMODE")), "-j=./")
	if err := os.Chdir("./tmp"); err != nil {
		logrus.Errorf("os.Chdir err:%+v", err)
	}
	if err := cmd.Run(); err != nil {
		logrus.Errorf("cmd.Run err:%+v", err)
	}
	if err := os.Chdir("../"); err != nil {
		logrus.Errorf("os.Chdir2 err:%+v", err)
	}*/
	utility.CreateDir(fmt.Sprintf("./resource/public/json/%s/", j.version))
	cmd2 := exec.Command("cp", "./tmp/serverjson/webproduct.json", fmt.Sprintf("./resource/public/json/%s/", j.version))
	if err := cmd2.Run(); err != nil {
		logrus.Errorf("cmd2.Run err:%+v", err)
	}
	return j
}
func (j *cGoods) Extract(version string) {
	logrus.Info("Goods Extract...")
	// shopMaps := map[int32]string{
	// 	1:  "低品质广告宝箱",
	// 	2:  "高品质广告宝箱",
	// 	3:  "十连抽宝箱",
	// 	4:  "钻石购买少量金币",
	// 	5:  "钻石购买中等金币",
	// 	6:  "钻石购买大量金币",
	// 	7:  "6元充值",
	// 	8:  "30元充值",
	// 	9:  "98元充值",
	// 	12: "198元充值",
	// 	13: "328元充值",
	// 	14: "648元充值",
	// 	10: "6元首充",
	// 	11: "25元首充",
	// 	15: "每日礼包",
	// 	16: "金币不足 钻石换购",
	// 	17: "新年礼包",
	// 	18: "新年礼包",
	// 	19: "月卡（25元）",
	// 	20: "季卡",
	// 	21: "角色抽奖-单抽",
	// 	22: "角色抽奖-十连抽",
	// 	23: "每日金币礼包",
	// 	24: "月卡（128元）",
	// 	25: "成长基金（30元）",
	// 	26: "成长基金（128元）",
	// 	27: "通行证",
	// 	28: "关卡内购买广告券",
	// }

	// for k, v := range shopMaps {
	// 	j.lst = append(j.lst, &GoodItem{
	// 		Value: k,
	// 		Label: v,
	// 	})
	// }
	j.setVersion(version).convert().webProduct()

	tmpShopGoods := make(map[int64]*ShopGoods)
	filePath := utility.LocalJsonPath(j.version, "webproduct.json")
	err := LoadItemData(filePath, &tmpShopGoods)
	if err == nil {
		for _, v := range j.lst {
			if v2, ok := tmpShopGoods[v.Value]; ok {
				v2.Name = v.Label
			}
		}
		j.save("product.json", tmpShopGoods)
	} else {
		logrus.Errorf("LocalJsonPath err:%+v", err)
	}

	for _, v := range j.lst {
		v.Label = fmt.Sprintf("%v(%v)", v.Label, v.Value)
	}
	j.save("goods.json", j.lst)
}

func (j *cGoods) setVersion(version string) *cGoods {
	j.version = version
	return j
}

func (j *cGoods) downloadFile(fileName string, lst any) error {
	b, err := GetUrlBody(j.version, fileName)
	if err != nil {
		logrus.Errorf("GetUrlBody err:%+v", err)
		return err
	}

	if err := json.Unmarshal(b, lst); err != nil {
		return err
	}
	return nil
}

func downloadGift[T GoodsItemer](filePath string, j *cGoods) error {
	lst1 := make([]T, 0)
	err := j.downloadFile(filePath, &lst1)
	if err != nil {
		logrus.Errorf("downloadGift %v err: %+v", filePath, err)
		return err
	}
	for _, v := range lst1 {
		if v.GetId() == 0 || len(v.GetName()) == 0 {
			logrus.Errorf("downloadGift %v filed error", filePath)
			return errors.New("field error")
		}
		j.lst = append(j.lst, &GoodItem{
			Value: v.GetId(),
			Label: v.GetName(),
		})
	}
	return nil
}

func (j *cGoods) convert() *cGoods {

	downloadGift[ShopGoodsItem]("shop.json", j)

	downloadGift[GiftItem]("DailyGift.json", j)
	downloadGift[GiftItem]("RoleGift.json", j)
	downloadGift[GiftItem]("NewerGift.json", j)
	downloadGift[GiftItem]("Holiday9Gift.json", j)
	downloadGift[GiftItem]("LanternFestivalGift.json", j)
	downloadGift[GiftItem]("Holiday3_Gift.json", j)
	downloadGift[GiftItem]("BuyOnceGetThreeDays.json", j)
	downloadGift[GiftItem]("Holiday10Gift.json", j)
	downloadGift[GiftItem]("LaborDayGift.json", j)
	downloadGift[GiftItem]("DragonBoatFestivalGift.json", j)
	downloadGift[GiftItem]("WeekendGift.json", j)
	downloadGift[GiftItem]("QixiFestivalGift.json", j)
	downloadGift[GiftItem]("MoonFestivalGift.json", j)

	downloadGift[EquipBoxGiftItem]("EquipBoxGiftPack.json", j)
	downloadGift[EquipBoxBaseItem]("EquipBoxBase.json", j)
	downloadGift[ELPassportItem]("EndlessPassportBase.json", j)
	downloadGift[GiftItem]("ReturnGift.json", j)
	downloadGift[GiftItem]("NewServerGift.json", j)
	downloadGift[FirtstChargeItem]("FirstChargeGift.json", j)
	downloadGift[PropStoreItem]("PropsStore.json", j)

	downloadGift[LimitGiftItem]("LimitGift.json", j)
	downloadGift[WeekendGiftItem]("WeekendGift.json", j)
	downloadGift[MonarchGiftRewardItem]("MonarchGiftReward.json", j)
	downloadGift[MonarchGift2Item]("MonarchGift2.json", j)
	downloadGift[Holiday12GiftItem]("Holiday12Gift.json", j)

	sort.Sort(GoodsSlice(j.lst))
	return j
}

// // ActivityGiftItem 活动礼包
// type ActivityGiftItem struct {
// 	GiftId        int32   `json:"gift_id"`
// 	GiftName      string  `json:"gift_name"`
// 	Icon          string  `json:"icon"`
// 	GiftType      int     `json:"gift_type"`
// 	OriginalPrice int     `json:"original_price"`
// 	GiftPrice     int     `json:"gift_price"`
// 	GiftAward     [][]int `json:"gift_award"`
// 	GiftStartTime string  `json:"gift_start_time"`
// 	GiftEndTime   string  `json:"gift_end_time"`
// 	GiftLimit     int     `json:"gift_limit"`
// 	ShowOrNot     int     `json:"show_or_not"`
// }

// func (j *cGoods) loadActivityGift() {
// 	var jsons = []string{
// 		"DragonBoatFestivalGift.json",
// 		"LaborDayGift.json",
// 		"TombSweepingDayGift.json",
// 		"Holiday3_Gift.json",
// 		"LanternFestivalGift.json",
// 		"NewYearGift.json",
// 		"QixiFestivalGift.json",
// 	}
// 	for _, file := range jsons {
// 		var lst []*ActivityGiftItem
// 		b, err := GetUrlBody(j.version, file)
// 		if err != nil {
// 			logrus.Errorf("loadActivityGift GetUrlBody err:%+v", err)
// 			continue
// 		}
// 		if err = json.Unmarshal(b, &lst); err != nil {
// 			logrus.Fatalf("loadActivityGift err=%v", err)
// 		}

// 		for _, v := range lst {
// 			j.lst = append(j.lst, &GoodItem{
// 				Value: v.GiftId,
// 				Label: v.GiftName,
// 			})
// 		}
// 	}
// }

// // LimitGiftItem 礼包详情
// type LimitGiftItem2 struct {
// 	Id   int32 `json:"id"`   // 礼包ID
// 	Type int64 `json:"type"` // 礼包类型
// 	//Value       []int                 `json:"value"`          // 类型值
// }

// func (j *cGoods) loadLimitGift() {
// 	var limitGift []*LimitGiftItem
// 	b, err := GetUrlBody(j.version, "LimitGift.json")
// 	if err != nil {
// 		logrus.Fatalf("loadLimitGift GetUrlBody err:%+v", err)
// 	}
// 	if err = json.Unmarshal(b, &limitGift); err != nil {
// 		logrus.Fatalf("loadLimitGift err=%v", err)
// 	}

// 	var typeMap = make(map[int64]string)
// 	typeMap = map[int64]string{
// 		1001: "登录",
// 		1002: "冒险等级达到N级",
// 		1003: "角色激活成功",
// 		1004: "角色突破成功",
// 		1005: "角色升星成功",
// 		1006: "章节通关",
// 		1007: "闯关失败（未通关）",
// 		1008: "已佩戴N件X品质装备",
// 		1009: "广告特惠礼包",
// 	}

// 	for _, v := range limitGift {
// 		j.lst = append(j.lst, &GoodItem{
// 			Value: v.Id,
// 			Label: "限时礼包-" + typeMap[v.Type],
// 		})
// 	}

// }

// func (j *cGoods) append(v interface{}) {
// 	getValue := reflect.ValueOf(v)
// 	if getValue.Kind() != reflect.Slice {
// 		logrus.Fatalf("need slice kind")
// 	}
// 	l := getValue.Len()
// 	for i := 0; i < l; i++ {
// 		value := getValue.Index(i)
// 		typel := value.Type()
// 		if typel.Kind() != reflect.Struct {
// 			logrus.Fatalf("need struct kind:%+v", typel.Kind())
// 		}
// 		var goodItem GoodItem
// 		num := value.NumField()
// 		for j2 := 0; j2 < num; j2++ {
// 			if typel.Field(j2).Name == "ID" {
// 				goodItem.Value = value.Field(j2).Interface().(int32)
// 			} else if typel.Field(j2).Name == "Name" {
// 				goodItem.Label = value.Field(j2).Interface().(string)
// 			} else {
// 				fmt.Printf("跳过数据 type-kind: %s, name: %s, type: %s, value: %v\n", typel.Kind(), typel.Field(j2).Name, value.Field(j2).Type(), value.Field(j2).Interface())
// 			}
// 		}
// 		j.lst = append(j.lst, &goodItem)
// 	}

// }

func (j *cGoods) save(fileName string, v interface{}) {
	//保存到文件
	filePath := utility.LocalJsonPath(j.version, fileName)
	SaveJsonPath(filePath, v)
}

func LoadItemData(filePath string, value interface{}) (err error) {

	if filePath == "" {
		return errors.New("file cannot be blank")
	}

	_, err = os.Stat(filePath)
	if err != nil {
		if os.IsNotExist(err) {
			return err
		}
		return err
	}

	fileObj, err := os.Open(filePath)
	if err != nil {
		return err
	}
	fileData, err := io.ReadAll(fileObj)
	if err != nil {
		return err
	}
	err = json.Unmarshal(fileData, value)
	if err != nil {
		return err
	}
	return nil
}
