package formview

import (
	"bytes"
	"fmt"
	"go_dreamfactory/cmd/v2/lib/common"
	"go_dreamfactory/cmd/v2/model"
	"go_dreamfactory/cmd/v2/service"
	"go_dreamfactory/cmd/v2/service/observer"
	"go_dreamfactory/comm"
	"go_dreamfactory/pb"
	"go_dreamfactory/utils"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"sync"
	"sync/atomic"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/widget"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cast"
	"github.com/tidwall/gjson"
)

type RtaskTestView struct {
	BaseformView
	itemList    *common.ItemList
	resultCount int32       //结果条数
	resultChan  chan string //结果内容
	flag        bool
	msgs        []string
	reportPath  string //Json Data数据路径
	loadCount   int32
}

func (this *RtaskTestView) CreateView(t *model.TestCase) fyne.CanvasObject {
	defer this.loadProtocol()
	this.itemList = common.NewItemList()
	this.itemList.ItemList = this.itemList.CreateDefaultCheckList()

	this.resultChan = make(chan string)

	rtaskTypeInput := widget.NewEntry()

	paramsInput := widget.NewEntry()
	paramsInput.PlaceHolder = "多个数值使用,分隔"

	condiInput := widget.NewEntry()
	condiInput.PlaceHolder = "条件ID为空时走触发逻辑否则走校验逻辑"

	input := widget.NewEntry()
	input.PlaceHolder = "分组编号"

	this.form.AppendItem(widget.NewFormItem("任务类型", rtaskTypeInput))
	this.form.AppendItem(widget.NewFormItem("参数", paramsInput))
	this.form.AppendItem(widget.NewFormItem("条件ID", condiInput))

	this.form.AppendItem(widget.NewFormItem("分组编号", input))

	testBtn := widget.NewButton("手动触发", func() {
		this.form.OnSubmit = func() {
			if err := service.GetPttService().SendToClient(
				t.MainType,
				t.SubType,
				&pb.WorldtaskTriggerReq{
					RtaskType: cast.ToInt32(rtaskTypeInput.Text),
					Params:    utils.TrInt32(paramsInput.Text),
					CondiId:   cast.ToInt32(condiInput.Text),
				},
			); err != nil {
				logrus.Error(err)
				return
			}
		}

		paiWin := dialog.NewCustom("手动触发", "关闭", this.form, this.w)
		paiWin.Resize(fyne.NewSize(600, 300))
		paiWin.Show()
	})

	//"F:\\projects\\workspace\\go_dreamfactory\\bin\\json"
	jsonPathEntry := widget.NewEntry()
	jsonPathEntry.SetText("F:\\")
	reportEntry := widget.NewEntry()
	reportEntry.SetText("F:\\")

	autoTestForm := widget.NewForm(
		widget.NewFormItem("Json配置", jsonPathEntry),
		widget.NewFormItem("报告保存", reportEntry),
	)

	autoTestForm.OnSubmit = func() {
		commCfg := &common.Config{
			Path: jsonPathEntry.Text,
		}

		this.reportPath = reportEntry.Text
		var wg sync.WaitGroup

		b, err := ioutil.ReadFile(filepath.Join(commCfg.Path, "game_rdtaskcondi.json"))
		if err != nil {
			logrus.Error(err)
			return
		}

		r := gjson.ParseBytes(b)

		for _, line := range r.Array() {
			logrus.Debug(line.String())
			id := line.Get("id").Int()
			rtype := line.Get("type").Int()
			data1 := line.Get("data1").Int()
			data2 := line.Get("data2").Int()
			data3 := line.Get("data3").Int()
			data4 := line.Get("data4").Int()
			data5 := line.Get("data5").Int()

			wg.Add(1)
			params := []int32{int32(data1), int32(data2), int32(data3), int32(data4), int32(data5)}

			var p []int32
			for _, v := range params {
				if v > 0 {
					p = append(p, v)
				}
			}
			logrus.Debugf("id:%v rtype:%v params:%v", id, rtype, p)
			go func(condId, rtype int32, p []int32) {
				defer wg.Done()
				if err := service.GetPttService().SendToClient(
					t.MainType,
					t.SubType,
					&pb.RtaskTestReq{
						RtaskType: rtype,
						Params:    p,
					},
				); err != nil {
					logrus.Error(err)
					return
				}
			}(int32(id), int32(rtype), p)
			wg.Wait()
		}

		go func() {
			for msg := range this.resultChan {
				this.msgs = append(this.msgs, msg)
				atomic.AddInt32(&this.loadCount, 1)
			}
		}()

		go func() {
			var flag bool
			for !flag {
				count := atomic.LoadInt32(&this.resultCount)
				lcount := atomic.LoadInt32(&this.loadCount)
				// logrus.Debug("count:", count)
				if count == lcount {
					logrus.Debug("结束")
					record := strings.Join(this.msgs, "\n")
					var buf bytes.Buffer
					buf.WriteString(fmt.Sprintf("---任务参数测试报告---\n"))
					buf.WriteString(record)
					buf.WriteString("\n-------")

					file, err := os.OpenFile(filepath.Join(this.reportPath, "report.txt"), os.O_TRUNC|os.O_CREATE, os.ModePerm)
					if err != nil {
						logrus.Error(err)
					}
					defer file.Close()

					if _, err := file.WriteString(buf.String()); err != nil {
						logrus.Error(err)
					}
					flag = true
				}
			}
		}()
	}

	autoTestBtn := widget.NewButton("自动触发配置", func() {
		paiWin := dialog.NewCustom("自动触发配置", "关闭", autoTestForm, this.w)
		paiWin.Resize(fyne.NewSize(600, 300))
		paiWin.Show()
	})

	autoBtn := widget.NewButton("模拟API测试", func() {
		// for k, v := range pb2.TaskCase {
		// 	if k != "" && strings.Contains(k, ".") && v.Enabled {
		// 		if err := service.GetPttService().SendToClient(
		// 			v.MainType,
		// 			v.SubType,
		// 			v.Req,
		// 		); err != nil {
		// 			logrus.Errorf("%v.%v err:%v", v.MainType, v.SubType, err)
		// 			return
		// 		}
		// 		logrus.Debugf("%v.%v", v.MainType, v.SubType)
		// 	}
		// }
	})

	this.rtestListener()
	c := container.NewBorder(
		container.NewHBox(testBtn, autoTestBtn, autoBtn), nil, nil, nil, this.itemList.ItemList)

	return c
}

func (this *RtaskTestView) loadProtocol() {
	// for k, v := range pb2.TaskCase {
	// 	if k != "" && strings.Contains(k, ".") && v.Enabled {
	// 		item := common.Item{
	// 			Id:   k,
	// 			Text: fmt.Sprintf("%v (%v)", v.NavLabel, k),
	// 		}
	// 		this.itemList.AddItem(item)
	// 	}
	// }

}

func (this *RtaskTestView) rtestListener() {
	if this.flag {
		return
	}

	this.obs.AddListener(observer.EVENT_REQ_RSP, observer.Listener{
		OnNotify: func(d interface{}, args ...interface{}) {
			data := d.(*pb.UserMessage)
			if data.MainType == string("worldtask") &&
				data.SubType == "rtest" {
				rsp := &pb.RtaskTestResp{}

				if !comm.ProtoUnmarshal(data, rsp) {
					logrus.Error("unmarshal err")
					return
				}

				msg := fmt.Sprintf("%v - %v", rsp.RtaskType, rsp.Flag)

				this.resultChan <- msg
				atomic.AddInt32(&this.resultCount, 1)

				logrus.Debug("resp", msg)
			}
		},
	})
	this.flag = true
}
