package service

import (
	"context"
	"fmt"
	"gadmin/config"
	"gadmin/internal/admin/consts"
	"gadmin/internal/admin/forms"
	"gadmin/internal/gorm/model"
	"gadmin/internal/gorm/query"
	"gadmin/utility/serializer"
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"strings"
)

// Channel 渠道
var Channel = new(sChannel)

type sChannel struct{}

func (s *sChannel) Stat(ctx *gin.Context, req forms.ChannelStatReq) serializer.Response {
	type Result struct {
		ID           int64  `json:"id"`
		ChannelId    string `json:"channel_id"`
		Name         string `json:"name"`
		TotalLogin   int64  `json:"totalLogin"`
		TotalNewUser int64  `json:"totalNewUser"`
		LastAt       int32  `json:"lastAt"`
	}

	var (
		q            = query.Use(config.DB).Channel
		m            = q.WithContext(ctx)
		a            = query.Use(config.DB).AdvOriginLog
		offset int64 = 0
		models forms.ListRes
		lists  []*Result
		err    error
	)

	req.Page, req.PerPage, offset = forms.CalculatePage(req.Page, req.PerPage)

	count, err := m.Count()
	if err != nil {
		return serializer.Err(consts.CodeParamErr, "查询出错 count", err)
	}

	if count > 0 {
		if err = m.Limit(int(req.PerPage)).Offset(int(offset)).Scan(&lists); err != nil {
			return serializer.Err(consts.CodeParamErr, "查询出错 lists", err)
		}
	}

	for _, v := range lists {
		// 全部广告渠道
		if v.ChannelId == "1" {
			continue
		}
		v.TotalLogin, err = a.WithContext(ctx).Where(a.Traceid.Eq(v.ChannelId)).Count()
		if err != nil {
			return serializer.Err(consts.CodeParamErr, "查询出错 Count2", err)
		}
		v.TotalNewUser, err = a.WithContext(ctx).Where(a.Traceid.Eq(v.ChannelId), a.NewUser.Eq(1)).Count()
		if err != nil {
			return serializer.Err(consts.CodeParamErr, "查询出错 NewUser", err)
		}
		last, err := a.WithContext(ctx).Where(a.Traceid.Eq(v.ChannelId)).Last()
		if err != nil && err.Error() != "record not found" {
			//return serializer.Err(consts.CodeParamErr, "查询出错 Last", err)
		}

		if last != nil {
			v.LastAt = last.EventAt
		}

	}

	models.List = lists
	models.Page = req.Page
	models.PerPage = req.PerPage
	models.PageCount = (count + req.PerPage - 1) / req.PerPage

	return serializer.Suc(models)
}

func (s *sChannel) Edit(ctx *gin.Context, req forms.ChannelStatEditReq) serializer.Response {
	q := query.Use(config.DB).Channel
	_, err := q.WithContext(ctx).Where(q.ID.Eq(req.Id)).Update(q.Name, req.Name)
	if err != nil {
		return serializer.Err(consts.CodeParamErr, "更新出错", err)
	}

	return serializer.Suc(nil)
}

// Option 选项
func (s *sChannel) Option(ctx *gin.Context) (list []forms.Option) {
	var (
		q     = query.Use(config.DB).Channel
		m     = q.WithContext(ctx)
		lists []*model.Channel
		err   error
	)

	if err = m.Scan(&lists); err != nil {
		logrus.Warnf("查询出错 lists err:%+v", err)
		return list
	}
	list = append(list, forms.Option{
		Value: "",
		Label: "全部渠道",
		Name:  "全部渠道",
	})
	for _, v := range lists {
		//if v.ChannelID == "0" {
		//	v.Name = "自然玩家"
		//}
		list = append(list, forms.Option{
			Value: v.ChannelID,
			Label: fmt.Sprintf("%v(%v)", v.Name, v.ChannelID),
			Name:  v.Name,
		})
	}
	return list
}

// TreeOption 选项
func (s *sChannel) TreeOption(ctx *gin.Context) (list []*forms.TreeOption) {
	var (
		q     = query.Use(config.DB).Channel
		m     = q.WithContext(ctx)
		lists []*model.Channel
		err   error
	)

	if err = m.Scan(&lists); err != nil {
		logrus.Warnf("查询出错 lists err:%+v", err)
		return list
	}

	list = []*forms.TreeOption{
		{
			Label: "全部渠道",
			Key:   "",
		},
		{
			Label: "自然玩家",
			Key:   consts.ChannelIdDefault,
		},
		{
			Label: "全部广告渠道",
			Key:   consts.ChannelIdAllAdv,
		},
	}

	wx := &forms.TreeOption{
		Label: "微信渠道",
		Key:   consts.ChannelIdAllWx,
	}

	tt := &forms.TreeOption{
		Label: "抖音渠道",
		Key:   consts.ChannelIdAllTT,
	}

	for _, v := range lists {
		opt := &forms.TreeOption{
			Label: v.ChannelID,
			Key:   v.ChannelID,
		}

		switch v.Type {
		case consts.ChannelTypeMaster:
			continue
		case consts.ChannelPlatformWx:
			wx.Children = append(wx.Children, opt)
		case consts.ChannelPlatformTT:
			tt.Children = append(tt.Children, opt)
		}

	}

	list = append(list, wx, tt)
	return list
}

func (s *sChannel) Ids() (resp []string, err error) {
	rdb := query.Use(config.DB).Channel
	results, err := rdb.Find()
	if err != nil {
		return
	}

	for _, v := range results {
		resp = append(resp, v.ChannelID)
	}

	return
}

// GetIdsByType 获取指定主渠道ID获取子级渠道ID集合
func (s *sChannel) GetIdsByType(pid string) (resp []string) {
	rdb := query.Use(config.DB).Channel
	m := rdb.WithContext(context.TODO())

	switch pid {
	case consts.ChannelIdAllAdv:
		m = m.Where(rdb.Type.In(consts.ChannelPlatformWx, consts.ChannelPlatformTT))
	case consts.ChannelIdAllWx:
		m = m.Where(rdb.Type.Eq(consts.ChannelPlatformWx))
	case consts.ChannelIdAllTT:
		m = m.Where(rdb.Type.Eq(consts.ChannelPlatformTT))
	}

	results, err := m.Find()
	if err != nil {
		logrus.Warnf("service.GetIdsByType err:%+v", err)
		return
	}

	for _, v := range results {
		resp = append(resp, v.ChannelID)
	}

	return
}

func (s *sChannel) GetIdsByTypeToString(pid string) string {
	return strings.Join(s.GetIdsByType(pid), `,`)
}

// IsMasterChannel 是否是主渠道
func (s *sChannel) IsMasterChannel(channelId string) bool {
	switch channelId {
	case consts.ChannelIdDefault, consts.ChannelIdAllAdv, consts.ChannelIdAllWx, consts.ChannelIdAllTT:
		return true
	}

	return false
}

// IsSubChannel 是否是子渠道
func (s *sChannel) IsSubChannel(ctx *gin.Context, channelId string) bool {
	q := query.Use(config.DB).Channel
	data, err := q.WithContext(ctx).Where(q.ChannelID.Eq(channelId)).First()
	if err != nil || data == nil {
		return true // 默认子渠道
	}

	return data.Type != 0
}
