package formview

import (
	"errors"
	"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/modules/sociaty"
	"go_dreamfactory/pb"
	"go_dreamfactory/utils"
	"time"

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

type SociatyMineView struct {
	BaseformView
	loadSociaty   func()
	flag_mine     bool
	itemList      *common.ItemList //申请列表
	memberList    *common.ItemList //成员列表
	logList       *common.ItemList //日志列表
	flag_apply    bool
	applyListFun  func()
	memberListFun func()
	sociaty       *pb.DBSociaty         // 公会
	master        *pb.SociatyMemberInfo //公会会长
	job           pb.SociatyJob         // 职位
	ticket        int32                 //挑战券
	uid           string
	flag_memeber  bool
	flag_log      bool
}

type entryItem struct {
	sociatyName  *widget.Entry
	notice       *widget.Entry
	icon         *widget.Entry
	isApplyCheck *widget.Check
	applyLv      *widget.Entry
	exp          *widget.Label
	activity     *widget.Label
	lv           *widget.Label
}

func (this *SociatyMineView) CreateView(t *model.TestCase) fyne.CanvasObject {
	user := this.service.GetUser()
	if user == nil {
		common.ShowTip("user not found")
	}
	this.uid = user.DbUser.Uid
	item := &entryItem{
		sociatyName:  widget.NewEntry(),
		notice:       widget.NewMultiLineEntry(),
		icon:         widget.NewEntry(),
		isApplyCheck: widget.NewCheck("审批", nil),
		applyLv:      widget.NewEntry(),
		lv:           widget.NewLabel(""),
		exp:          widget.NewLabel(""),
		activity:     widget.NewLabel(""),
	}

	this.form.AppendItem(widget.NewFormItem("公会名称", item.sociatyName))
	this.form.AppendItem(widget.NewFormItem("公告", item.notice))
	this.form.AppendItem(widget.NewFormItem("图标", item.icon))
	this.form.AppendItem(widget.NewFormItem("审批", item.isApplyCheck))
	this.form.AppendItem(widget.NewFormItem("入会等级", item.applyLv))
	this.form.AppendItem(widget.NewFormItem("等级", item.lv))
	this.form.AppendItem(widget.NewFormItem("经验", item.exp))
	this.form.AppendItem(widget.NewFormItem("活跃值", item.activity))

	//加载公会信息
	this.loadSociaty = func() {
		if err := service.GetPttService().SendToClient(
			t.MainType,
			"mine",
			&pb.SociatyMineReq{},
		); err != nil {
			logrus.Error(err)
			return
		}
	}

	refreshBtn := widget.NewButtonWithIcon("", theme.ViewRefreshIcon(), func() {
		this.loadSociaty()
		this.sociatyRender(item)
		this.form.Refresh()
	})
	// 签到
	signBtn := widget.NewButton("签到", this.showSignWin)

	// 退出
	quitBtn := widget.NewButton("退出", func() {
		dialog.ShowConfirm("提示", "确定退出公会?", func(b bool) {
			if !b {
				return
			}
			if err := service.GetPttService().SendToClient(
				t.MainType,
				"quit",
				&pb.SociatyQuitReq{},
			); err != nil {
				logrus.Error(err)
				return
			}

			item = &entryItem{}
		}, this.w)

	})

	btns := container.NewHBox(refreshBtn, signBtn)

	//解散公会
	jiesanBtn := widget.NewButton("解散", func() {
		dialog.ShowConfirm("提示", "确定解散公会?", func(b bool) {
			if !b {
				return
			}
			if err := service.GetPttService().SendToClient(
				t.MainType,
				"dismiss",
				&pb.SociatyDismissReq{},
			); err != nil {
				logrus.Error(err)
				return
			}

			item = &entryItem{}
		}, this.w)
	})

	// 取消解散
	cancelJiesanBtn := widget.NewButton("解散取消", func() {
		dialog.ShowConfirm("提示", "确定取消解散公会?", func(b bool) {
			if !b {
				return
			}
			if err := service.GetPttService().SendToClient(
				t.MainType,
				"dismiss",
				&pb.SociatyDismissReq{
					Dismiss: 1, //取消
				},
			); err != nil {
				logrus.Error(err)
				return
			}

			item = &entryItem{}
		}, this.w)
	})

	//申请列表
	applyListBtn := widget.NewButton("申请审批", this.showSociatyApplyListWin)

	// 日志
	logBtn := widget.NewButton("日志", this.showLogWin)

	// 活跃度
	activityBtn := widget.NewButton("活跃度", this.showActivityWin)

	//会长信息
	card := widget.NewCard("", "", nil)

	defer func() {
		this.loadSociaty()
		time.Sleep(time.Millisecond * 30) //必须要延迟，否则职位获取不到
		if this.sociaty == nil {
			// dialog.ShowInformation("提示", "还没有加入任何公会", this.w)
			return
		}

		if this.master == nil {
			logrus.Errorf("会长数据是空,公会ID:%v", this.sociaty.Id)
			return
		}
		//会长信息
		pName := widget.NewEntry()
		pName.Text = this.master.Name
		pAvatr := widget.NewEntry()
		pAvatr.Text = this.master.Avatar
		pLv := widget.NewEntry()
		pLv.Text = cast.ToString(this.master.Lv)
		ticket := widget.NewEntry()
		ticket.Text = cast.ToString(this.ticket)
		pOfftime := widget.NewEntry()
		if this.master.OfflineTime != 0 {
			t := time.Unix(this.master.OfflineTime, 0)
			pOfftime.Text = t.Format("2006/01/02 15:04:05")
		} else {
			pOfftime.Text = cast.ToString(this.master.OfflineTime)
		}

		form := widget.NewForm(
			widget.NewFormItem("会长", pName),
			widget.NewFormItem("头像", pAvatr),
			widget.NewFormItem("等级", pLv),
			widget.NewFormItem("挑战券", ticket),
			widget.NewFormItem("离线", pOfftime),
		)
		card.SetContent(form)
		card.Refresh()
		form.Refresh()

		//管理或副会长权限
		if this.job == pb.SociatyJob_ADMIN ||
			this.job == pb.SociatyJob_VICEPRESIDENT {

			btns.Add(applyListBtn)
		}
		//会长权限
		if this.job == pb.SociatyJob_PRESIDENT {
			btns.Add(applyListBtn)
			btns.Add(jiesanBtn)
			btns.Add(cancelJiesanBtn)
		} else {
			btns.Add(quitBtn)
		}

		btns.Add(logBtn)
		btns.Add(activityBtn)
		this.sociatyRender(item)
		this.form.Refresh()
	}()

	//成员列表
	membersBtn := widget.NewButton("成员列表", this.showSociatyMemberWin)
	btns.Add(membersBtn)

	// 保存修改
	this.form.OnSubmit = func() {
		defer func() {
			common.ShowTip("公告已更新")
		}()
		if err := service.GetPttService().SendToClient(
			t.MainType,
			"",
			&pb.SociatySettingReq{
				Icon:         item.icon.Text,
				Notice:       item.notice.Text,
				ApplyLv:      cast.ToInt32(item.applyLv.Text),
				IsApplyCheck: item.isApplyCheck.Checked,
			},
		); err != nil {
			logrus.Error(err)
			return
		}
	}
	this.form.SubmitText = "保存修改"

	c := container.NewBorder(btns, card, nil, nil, this.form)
	this.dataListener(item)

	return c
}

func (this *SociatyMineView) sociatyRender(item *entryItem) {
	if this.sociaty == nil {
		dialog.ShowInformation("提示", "还没有加入任何公会", this.w)
		return
	}
	if item != nil {
		item.sociatyName.Text = this.sociaty.Name
		item.notice.Text = this.sociaty.Notice
		item.icon.Text = this.sociaty.Icon
		item.isApplyCheck.Checked = this.sociaty.IsApplyCheck
		item.applyLv.Text = cast.ToString(this.sociaty.ApplyLv)
		item.lv.Text = cast.ToString(this.sociaty.Lv)
		item.exp.Text = cast.ToString(this.sociaty.Exp)
		item.activity.Text = cast.ToString(this.sociaty.Activity)
	}
}

func (this *SociatyMineView) dataListener(item *entryItem) {
	if this.flag_mine {
		return
	}
	this.obs.AddListener(observer.EVENT_REQ_RSP, observer.Listener{
		OnNotify: func(d interface{}, args ...interface{}) {
			data := d.(*pb.UserMessage)
			if data.MainType == "sociaty" {
				switch data.SubType {
				case "mine":
					rsp := &pb.SociatyMineResp{}

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

					if rsp.Sociaty == nil {
						logrus.Debug("公会信息 nil")
						// item = &entryItem{}
						dialog.ShowInformation("提示", "未加入公会", this.w)
						return
					}

					this.sociaty = rsp.Sociaty
					this.master = rsp.Master
					// this.ticket = rsp.Ticket

					//设置成员职位
					for _, m := range rsp.Sociaty.Members {
						if m.Uid == this.uid {
							logrus.Debug(m.Uid)
							this.job = m.Job
							break
						}
					}

					logrus.Debugf("公会:%v", rsp.Sociaty)

					item.sociatyName.Text = rsp.Sociaty.Name
					item.notice.Text = rsp.Sociaty.Notice
					item.icon.Text = rsp.Sociaty.Icon
					item.isApplyCheck.Checked = rsp.Sociaty.IsApplyCheck
					item.applyLv.Text = cast.ToString(rsp.Sociaty.ApplyLv)
					item.lv.Text = cast.ToString(rsp.Sociaty.Lv)
					item.exp.Text = cast.ToString(rsp.Sociaty.Exp)
					item.activity.Text = cast.ToString(rsp.Sociaty.Activity)
					this.form.Refresh()

				//踢人
				case "discharge":
					rsp := &pb.SociatyDischargeResp{}
					if !comm.ProtoUnmarshal(data, rsp) {
						logrus.Error("unmarshal err")
						return
					}
					if rsp.SociatyId == "" {
						dialog.ShowError(errors.New("踢人失败"), this.w)
					} else {
						common.ShowTip("踢人成功")
					}
				}
			}
		},
	})
	this.flag_mine = true
}

// 申请列表windows
func (this *SociatyMineView) showSociatyApplyListWin() {

	this.itemList = common.NewItemList()
	this.itemList.ItemList = this.itemList.CreateList()

	this.applyListFun = func() {
		if this.sociaty == nil {
			dialog.ShowInformation("提示", "还没有加入任何公会", this.w)
			return
		}
		sociatyId := this.sociaty.Id
		if sociatyId == "" {
			common.ShowTip("公会ID空")
			return
		}
		if err := service.GetPttService().SendToClient(
			"sociaty",
			"applylist",
			&pb.SociatyApplyListReq{
				SociatyId: sociatyId,
			}); err != nil {
			logrus.Error(err)
		}
	}
	defer this.applyListFun()

	refreshBtn := widget.NewButtonWithIcon("", theme.ViewRefreshIcon(), func() {
		this.itemList.Reset()
		this.applyListFun()
	})

	agreeBtn := widget.NewButton("同意", func() {
		defer this.itemList.Reset()
		selId := this.itemList.SelItemId
		if selId == "" {
			common.ShowTip("请选择项目")
			return
		}
		sociatyId := this.sociaty.Id
		if sociatyId == "" {
			common.ShowTip("公会ID空")
			return
		}
		if err := service.GetPttService().SendToClient(
			"sociaty",
			"agress",
			&pb.SociatyAgreeReq{
				Uid: selId,
			}); err != nil {
			logrus.Error(err)
		}
	})
	refuseBtn := widget.NewButton("拒绝", func() {
		defer this.itemList.Reset()
		selId := this.itemList.SelItemId
		if selId == "" {
			common.ShowTip("请选择项目")
			return
		}
		sociatyId := this.sociaty.Id
		if sociatyId == "" {
			common.ShowTip("公会ID空")
			return
		}
		if err := service.GetPttService().SendToClient(
			"sociaty",
			"refuse",
			&pb.SociatyRefuseReq{
				Uid: selId,
			}); err != nil {
			logrus.Error(err)
		}
	})
	btns := container.NewHBox(refreshBtn, agreeBtn, refuseBtn)

	c := container.NewBorder(btns, nil, nil, nil, this.itemList.ItemList)

	dconf := dialog.NewCustom("公会审批", "关闭", c, this.w)
	dconf.Resize(fyne.NewSize(800, 500))
	dconf.Show()
	this.applyListen()
}

func (this *SociatyMineView) applyListen() {
	if this.flag_apply {
		return
	}
	this.obs.AddListener(observer.EVENT_REQ_RSP, observer.Listener{
		OnNotify: func(d interface{}, args ...interface{}) {
			data := d.(*pb.UserMessage)
			if !(data.MainType == "sociaty" &&
				data.SubType == "applylist") {
				return
			}
			rsp := &pb.SociatyApplyListResp{}

			if !comm.ProtoUnmarshal(data, rsp) {
				logrus.Error("unmarshal err")
				return
			}
			for i, v := range rsp.List {
				item := common.Item{
					Id:   v.Uid,
					Text: fmt.Sprintf("%d - %s lv:%d", i+1, v.Name, v.Lv),
				}
				this.itemList.AddItem(item)
			}
		},
	})
	this.flag_apply = true
}

// 成员列表windows
func (this *SociatyMineView) showSociatyMemberWin() {
	this.memberList = common.NewItemList()
	this.memberList.ItemList = this.memberList.CreateList()

	this.memberListFun = func() {
		sociatyId := this.sociaty.Id
		if sociatyId == "" {
			common.ShowTip("公会ID空")
			return
		}
		if err := service.GetPttService().SendToClient(
			"sociaty",
			"members",
			&pb.SociatyMembersReq{}); err != nil {
			logrus.Error(err)
		}
	}

	defer this.memberListFun()

	refreshBtn := widget.NewButtonWithIcon("", theme.ViewRefreshIcon(), func() {
		this.memberList.Reset()
		this.memberListFun()
	})

	//弹劾
	tanheBtn := widget.NewButton("弹劾", func() {
		dialog.ShowConfirm("提示", "确定弹劾会长?", func(b bool) {
			if !b {
				return
			}
			if err := service.GetPttService().SendToClient(
				"sociaty",
				"accuse",
				&pb.SociatyAccuseReq{},
			); err != nil {
				logrus.Error(err)
				return
			}

		}, this.w)
	})

	// 转让
	zhuanrangBtn := widget.NewButton("转让", func() {
		selId := this.memberList.SelItemId
		if selId == "" {
			common.ShowTip("请选择项目")
			return
		}
		dialog.ShowConfirm("提示", "确定转让公会?", func(b bool) {
			if !b {
				return
			}

			if err := service.GetPttService().SendToClient(
				"sociaty",
				"assign",
				&pb.SociatyAssignReq{
					TargetId: selId,
				},
			); err != nil {
				logrus.Error(err)
				return
			}

			dialog.ShowInformation("提示", "转让后请重新登录", this.w)

		}, this.w)
	})
	// 踢人
	tirenBtn := widget.NewButton("踢人", func() {
		selId := this.memberList.SelItemId
		if selId == "" {
			common.ShowTip("请选择一个成员")
			return
		}
		if err := service.GetPttService().SendToClient(
			"sociaty",
			"discharge",
			&pb.SociatyDischargeReq{
				TargetId: selId,
			}); err != nil {
			logrus.Error(err)
			return
		}
		// this.memberList.DeleteItem(selId)
	})

	// 设置职位
	setJobSel := widget.NewSelect([]string{"设置职位", "副会长", "管理", "普通成员"}, func(s string) {
		selId := this.memberList.SelItemId
		if selId == "" {
			common.ShowTip("请选择项目")
			return
		}
		var job pb.SociatyJob
		switch s {
		case "副会长":
			job = pb.SociatyJob_VICEPRESIDENT
		case "管理":
			job = pb.SociatyJob_ADMIN
		case "普通成员":
			job = pb.SociatyJob_MEMBER
		default:
			job = pb.SociatyJob_NOJOB
		}
		if err := service.GetPttService().SendToClient(
			"sociaty",
			"settingjob",
			&pb.SociatySettingJobReq{
				TargetId: selId,
				Job:      job,
			},
		); err != nil {
			logrus.Error(err)
			return
		}
	})
	setJobSel.Selected = "设置职位"

	btns := container.NewHBox(refreshBtn)

	// 会长
	if this.job == pb.SociatyJob_PRESIDENT {
		btns.Add(setJobSel)
		btns.Add(tirenBtn)
		btns.Add(zhuanrangBtn)
	}
	// 副会长或管理员
	if this.job == pb.SociatyJob_VICEPRESIDENT ||
		this.job == pb.SociatyJob_ADMIN {
		btns.Add(tirenBtn)
		btns.Add(tanheBtn)
	}
	// 成员
	if this.job == pb.SociatyJob_MEMBER {
		btns.Add(tanheBtn)
	}

	c := container.NewBorder(btns, nil, nil, nil, this.memberList.ItemList)
	dconf := dialog.NewCustom("公会成员", "关闭", c, this.w)
	dconf.Resize(fyne.NewSize(800, 500))
	dconf.Show()
	this.memberListen()
}

func (this *SociatyMineView) memberListen() {
	if this.flag_memeber {
		return
	}
	this.obs.AddListener(observer.EVENT_REQ_RSP, observer.Listener{
		OnNotify: func(d interface{}, args ...interface{}) {
			data := d.(*pb.UserMessage)
			if !(data.MainType == "sociaty" &&
				data.SubType == "members") {
				return
			}
			rsp := &pb.SociatyMembersResp{}

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

			for i, v := range rsp.List {
				item := common.Item{
					Id:   v.Uid,
					Text: fmt.Sprintf("%d - %s lv:%d %v", i+1, v.Name, v.Lv, v.Job),
				}
				this.memberList.AddItem(item)
			}
		},
	})
	this.flag_memeber = true
}

// 签到
func (this *SociatyMineView) showSignWin() {
	this.loadSociaty()
	var lastCount int32
	if this.sociaty == nil {
		logrus.Error("公会 is nil")
		return
	}

	// 昨日签到
	lastCount = this.sociaty.LastSignCount
	lastSignCard := canvas.NewText(cast.ToString(lastCount), nil)
	lastSignCard.TextSize = 50

	// 已签到数
	todaySignCount := len(this.sociaty.SignIds)
	signedCard := canvas.NewText(cast.ToString(todaySignCount), nil)
	signedCard.TextSize = 50

	btn := widget.NewButton("签到", nil)
	btn.OnTapped = func() {
		defer btn.Disable()
		if err := service.GetPttService().SendToClient(
			"sociaty",
			"sign",
			&pb.SociatySignReq{},
		); err != nil {
			logrus.Error(err)
			return
		}
	}

	if _, ok := utils.Findx(this.sociaty.SignIds, this.uid); ok {
		btn.Text = "已签到"
		btn.Disable()
	}

	l := container.NewVBox(container.NewCenter(lastSignCard), btn, container.NewCenter(signedCard))
	dconf := dialog.NewCustom("签到", "关闭", l, this.w)
	dconf.Resize(fyne.NewSize(400, 600))
	dconf.Show()
}

// 日志列表
func (this *SociatyMineView) showLogWin() {
	this.logList = common.NewItemList()
	this.logList.ItemList = this.logList.CreateList()

	logList := func() {
		if err := service.GetPttService().SendToClient(
			"sociaty",
			"log",
			&pb.SociatyLogReq{}); err != nil {
			logrus.Error(err)
		}
	}
	refreshBtn := widget.NewButtonWithIcon("", theme.ViewRefreshIcon(), func() {
		this.logList.Reset()
		logList()
	})
	defer logList()

	btns := container.NewHBox(refreshBtn)
	c := container.NewBorder(btns, nil, nil, nil, this.logList.ItemList)
	dconf := dialog.NewCustom("日志", "关闭", c, this.w)
	dconf.Resize(fyne.NewSize(800, 500))
	dconf.Show()
	this.logListListen()
}

func (this *SociatyMineView) logListListen() {
	if this.flag_log {
		return
	}
	this.obs.AddListener(observer.EVENT_REQ_RSP, observer.Listener{
		OnNotify: func(d interface{}, args ...interface{}) {
			data := d.(*pb.UserMessage)
			if !(data.MainType == "sociaty" &&
				data.SubType == "log") {
				return
			}
			rsp := &pb.SociatyLogResp{}

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

			for i, v := range rsp.Log.List {
				t := time.Unix(v.Ctime, 10)
				ft := t.Format(time.RFC3339)
				item := common.Item{
					Id:   "",
					Text: fmt.Sprintf("%d - %-50s %v", i+1, v.Content, ft),
				}
				this.logList.AddItem(item)
			}
		},
	})
	this.flag_log = true
}

// 活跃度
func (this *SociatyMineView) showActivityWin() {
	itemList := this.activityList()

	//活跃度领取
	activityBtn := widget.NewButton("活跃度领取", func() {
		selId := itemList.SelItemId
		if err := service.GetPttService().SendToClient(
			"sociaty",
			"activityreceive",
			&pb.SociatyActivityReceiveReq{
				Id: cast.ToInt32(selId),
			}); err != nil {
			logrus.Error(err)
		}
	})

	var activityVal int32
	if this.sociaty != nil {
		activityVal = this.sociaty.Activity
	}

	aVal := canvas.NewText(cast.ToString(activityVal), nil)
	aVal.TextSize = 46
	aLayout := container.NewVBox(container.NewCenter(aVal), activityBtn)

	c := container.NewBorder(aLayout, nil, nil, nil, itemList.ItemList)
	dconf := dialog.NewCustom("活跃度", "关闭", c, this.w)
	dconf.Resize(fyne.NewSize(800, 500))
	dconf.Show()
}

func (this *SociatyMineView) activityList() *common.ItemList {
	// 活跃度列表
	activityItemList := common.NewItemList()
	activityItemList.ItemList = activityItemList.CreateList()

	n := map[int32]int32{
		1: 1000,
		2: 2000,
		3: 3000,
		4: 4000,
		5: 5000,
	}

	var nn int
	for k, v := range n {
		nn++
		item := common.Item{
			Id:   cast.ToString(k),
			Text: fmt.Sprintf("%d - Id:%v 活跃度:%d ", nn, k, v),
		}
		activityItemList.AddItem(item)
	}
	return activityItemList
}
