package service

import (
	"github.com/go-admin-team/go-admin-core/sdk/service"
	cDto "go-admin/common/dto"
	"go-admin/common/utils"
	"sort"
	"strconv"

	"go-admin/app/mobile/service/dto"
	"go-admin/common/actions"
)

type OrgPlayerRank struct {
	service.Service
}

// GetPage 获取OrgMatchEvaluate列表
func (e *OrgPlayerRank) GetPage(c *dto.OrgPlayerRankGetPageReq, p *actions.DataPermission, list *[]dto.OrgPlayerRankGetPageReply, count *int64) error {
	var err error

	err = e.Orm.Table("org_match_team_player as omtp").
		Select("omtp.player_id as id, omtp.player_name, omtp.player_number,"+
			"ol.league_name, oc.club_name, oc.club_logo, oc.club_qrcode,"+
			"sum(omtp.scoring)as scoring,"+
			"sum(omtp.rebound)as rebound,"+
			"sum(omtp.assist)as assist,"+
			"sum(omtp.steal)as steal,"+
			"sum(omtp.free_throw)as free_throw,"+
			"sum(omtp.block_shot)as block_shot,"+
			"sum(omtp.foul)as foul,"+
			"sum(omtp.two_point_shot)as two_point_shot,"+
			"sum(omtp.three_point_shot)as three_point_shot").
		Joins("left join org_team as ot on ot.id = omtp.team_id").
		Joins("left join org_club as oc on oc.id = omtp.club_id").
		Joins("left join org_player as op on op.id = omtp.player_id").
		Joins("left join org_match as om on omtp.match_id = om.id and omtp.rounds = om.rounds").
		Joins("left join org_league as ol on ol.id = om.league_id").
		Scopes(
			cDto.MakeCondition(c.GetNeedSearch()),
			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
			actions.Permission("omtp", p),
			cDto.PassDel("omtp"),
			cDto.SetWhere("om", "league_id", c.LeagueId),
		).
		Group("omtp.player_id").
		Find(list).Limit(-1).Offset(-1).
		Count(count).Error
	if err != nil {
		e.Log.Errorf("OrgClubPlayer GetPage error:%s \r\n", err)
		return err
	}

	if c.TypeName == "scoring" {
		e.rankingScoring(list)
	}
	if c.TypeName == "rebound" {
		e.rankingRebound(list)
	}
	if c.TypeName == "steal" {
		e.rankingSteal(list)
	}
	if c.TypeName == "freeThrow" {
		e.rankingFreeThrow(list)
	}
	if c.TypeName == "blockShot" {
		e.rankingBlockShot(list)
	}
	if c.TypeName == "foul" {
		e.rankingFoul(list)
	}
	if c.TypeName == "twoPointShot" {
		e.rankingTwoPointShot(list)
	}
	if c.TypeName == "threePointShot" {
		e.rankingThreePointShot(list)
	}

	return nil
}

// GetPage 获取OrgMatchEvaluate列表
func (e *OrgPlayerRank) GetPageOwn(c *dto.OrgPlayerRankGetPageReq, p *actions.DataPermission, data *dto.OrgPlayerRankGetPageReply, count *int64) error {
	var err error

	list := make([]dto.OrgPlayerRankGetPageReply, 0)

	err = e.Orm.Table("org_match_team_player as omtp").
		Select("omtp.player_id as id, omtp.player_name, omtp.player_number,"+
			"ol.league_name, oc.club_name, oc.club_logo, oc.club_qrcode,"+
			"sum(omtp.scoring)as scoring,"+
			"sum(omtp.rebound)as rebound,"+
			"sum(omtp.assist)as assist,"+
			"sum(omtp.steal)as steal,"+
			"sum(omtp.free_throw)as free_throw,"+
			"sum(omtp.block_shot)as block_shot,"+
			"sum(omtp.foul)as foul,"+
			"sum(omtp.two_point_shot)as two_point_shot,"+
			"sum(omtp.three_point_shot)as three_point_shot").
		Joins("left join org_team as ot on ot.id = omtp.team_id").
		Joins("left join org_club as oc on oc.id = omtp.club_id").
		Joins("left join org_player as op on op.id = omtp.player_id").
		Joins("left join org_match as om on omtp.match_id = om.id and omtp.rounds = om.rounds").
		Joins("left join org_league as ol on ol.id = om.league_id").
		Scopes(
			cDto.MakeCondition(c.GetNeedSearch()),
			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
			actions.Permission("omtp", p),
			cDto.PassDel("omtp"),
			cDto.SetWhere("om", "league_id", c.LeagueId),
		).
		Group("omtp.player_id").
		Find(&list).Limit(-1).Offset(-1).
		Count(count).Error
	if err != nil {
		e.Log.Errorf("OrgClubPlayer GetPage error:%s \r\n", err)
		return err
	}

	if c.TypeName == "scoring" {
		e.rankingScoring(&list)
	}
	if c.TypeName == "rebound" {
		e.rankingRebound(&list)
	}
	if c.TypeName == "assist" {
		e.rankingAssist(&list)
	}
	if c.TypeName == "steal" {
		e.rankingSteal(&list)
	}
	if c.TypeName == "freeThrow" {
		e.rankingFreeThrow(&list)
	}
	if c.TypeName == "blockShot" {
		e.rankingBlockShot(&list)
	}
	if c.TypeName == "foul" {
		e.rankingFoul(&list)
	}
	if c.TypeName == "twoPointShot" {
		e.rankingTwoPointShot(&list)
	}
	if c.TypeName == "threePointShot" {
		e.rankingThreePointShot(&list)
	}

	for _, v := range list {
		if v.Id == c.PlayerId {
			data.Id = v.Id
			data.ClubLogo = v.ClubLogo
			data.ClubName = v.ClubName
			data.PlayerImg = v.PlayerImg
			data.PlayerName = v.PlayerName
			data.PlayerNumber = v.PlayerNumber
			data.Position = v.Position
			data.Rank = v.Rank
			data.Scoring = v.Scoring
			data.Rebound = v.Rebound
			data.Assist = v.Assist
			data.Steal = v.Steal
			data.FreeThrow = v.FreeThrow
			data.BlockShot = v.BlockShot
			data.Foul = v.Foul
			data.TwoPointShot = v.TwoPointShot
			data.ThreePointShot = v.ThreePointShot
		}
	}

	return nil
}

// GetPage 获取OrgMatchEvaluate列表
func (e *OrgPlayerRank) GetPageTeam(c *dto.OrgPlayerRankGetPageReq, p *actions.DataPermission, list *[]dto.OrgPlayerRankGetPageReply, count *int64) error {
	var err error

	err = e.Orm.Table("org_match_team_player as omtp").
		Select("omtp.team_id as id, ol.league_name, omtp.player_name, omtp.player_number,"+
			"sum(omtp.scoring)as scoring,"+
			"sum(omtp.rebound)as rebound,"+
			"sum(omtp.assist)as assist,"+
			"sum(omtp.steal)as steal,"+
			"sum(omtp.free_throw)as free_throw,"+
			"sum(omtp.block_shot)as block_shot,"+
			"sum(omtp.foul)as foul,"+
			"sum(omtp.two_point_shot)as two_point_shot,"+
			"sum(omtp.three_point_shot)as three_point_shot").
		Joins("left join org_team as ot on ot.id = omtp.team_id").
		Joins("left join org_player as op on op.id = omtp.player_id").
		Joins("left join org_match as om on omtp.match_id = om.id and omtp.rounds = om.rounds").
		Joins("left join org_league as ol on ol.id = om.league_id").
		Scopes(
			cDto.MakeCondition(c.GetNeedSearch()),
			cDto.Paginate(c.GetPageSize(), c.GetPageIndex()),
			actions.Permission("omtp", p),
			cDto.PassDel("omtp"),
			cDto.SetWhere("om", "league_id", c.LeagueId),
		).
		Group("omtp.team_id").
		Find(list).Limit(-1).Offset(-1).
		Count(count).Error
	if err != nil {
		e.Log.Errorf("OrgClubPlayer GetPage error:%s \r\n", err)
		return err
	}

	if c.TypeName == "scoring" {
		e.rankingScoring(list)
	}
	if c.TypeName == "rebound" {
		e.rankingRebound(list)
	}
	if c.TypeName == "steal" {
		e.rankingSteal(list)
	}
	if c.TypeName == "freeThrow" {
		e.rankingFreeThrow(list)
	}
	if c.TypeName == "blockShot" {
		e.rankingBlockShot(list)
	}
	if c.TypeName == "foul" {
		e.rankingFoul(list)
	}
	if c.TypeName == "twoPointShot" {
		e.rankingTwoPointShot(list)
	}
	if c.TypeName == "threePointShot" {
		e.rankingThreePointShot(list)
	}

	return nil
}

// GetPage 获取OrgMatchEvaluate列表
func (e *OrgPlayerRank) GetPageTeamInfo(teamId string, seasonId string, list *[]dto.OrgPlayerRankGetPageReply, count *int64) error {
	var err error

	err = e.Orm.Table("org_match_team_player as omtp").
		Select("omtp.team_id as id,"+
			"sum(omtp.scoring)as scoring,"+
			"sum(omtp.rebound)as rebound,"+
			"sum(omtp.assist)as assist,"+
			"sum(omtp.steal)as steal,"+
			"sum(omtp.free_throw)as free_throw,"+
			"sum(omtp.block_shot)as block_shot,"+
			"sum(omtp.foul)as foul,"+
			"sum(omtp.two_point_shot)as two_point_shot,"+
			"sum(omtp.three_point_shot)as three_point_shot").
		Joins("left join org_match as om on omtp.match_id = om.id and omtp.rounds = om.rounds").
		Scopes(
			cDto.PassDel("omtp"),
			cDto.SetWhere("om", "season_id", seasonId),
		).
		Where("omtp.team_id=?", teamId).
		Find(list).Limit(-1).Offset(-1).
		Count(count).Error
	if err != nil {
		e.Log.Errorf("OrgClubPlayer GetPage error:%s \r\n", err)
		return err
	}

	return nil
}

// GetPage 获取OrgMatchEvaluate列表
func (e *OrgPlayerRank) GetTeamInfoData(teamId string, seasonId string, data *dto.OrgPlayerRankInfoGetReply) error {
	var err error

	list := make([]dto.OrgPlayerRankInfoGetData, 0)
	err = e.Orm.Table("org_match as om").
		Select("om.id, ol.league_name, os.season_name, oc.club_name, oc.club_logo, ot.team_name,"+
			"om.team_a_id,om.team_b_id,om.team_a_score,om.team_b_score,om.team_a_integral,om.team_b_integral").
		Joins("left join org_league as ol on ol.id = om.league_id").
		Joins("left join org_season as os on os.id = om.season_id").
		Joins("left join org_club as oc on oc.id = om.club_id").
		Joins("left join org_team as ot on ot.id = om.team_id").
		Scopes(
			cDto.PassDel("om"),
			cDto.SetWhere("om", "season_id", seasonId),
		).
		Where("om.team_a_id=? or om.team_a_id=?", teamId, teamId).
		Find(&list).Error
	if err != nil {
		e.Log.Errorf("OrgClubPlayer GetPage error:%s \r\n", err)
		return err
	}

	var countWin, countLose, countIntegral, countMatch = 0, 0, 0, 0
	if len(list) > 0 {
		for _, v := range list {
			countMatch += 1
			if v.TeamAId == teamId {
				if v.TeamAScore > v.TeamBScore {
					countWin += 1
				} else {
					countLose += 1
				}
				countIntegral += utils.StringToInt(v.TeamAIntegral)
			}
			if v.TeamBId == teamId {
				if v.TeamAScore > v.TeamBScore {
					countLose += 1
				} else {
					countWin += 1
				}
				countIntegral += utils.StringToInt(v.TeamBIntegral)
			}
		}

		data.LeagueName = list[0].LeagueName
		data.SeasonName = list[0].SeasonName
		data.ClubName = list[0].ClubName
		data.ClubLogo = list[0].ClubLogo
		data.TeamName = list[0].TeamName
	}

	data.CountWin = strconv.Itoa(countWin)
	data.CountLose = strconv.Itoa(countLose)
	data.CountIntegral = strconv.Itoa(countIntegral)
	data.CountMatch = strconv.Itoa(countMatch)

	return nil
}

// GetPage 获取OrgMatchEvaluate列表
func (e *OrgPlayerRank) GetTeamInfoPlayerList(teamId string, list *[]dto.OrgPlayerGetPageReply) error {
	var err error

	err = e.Orm.Table("org_player as op").
		Select("op.id,op.player_name,op.player_number,op.player_img,op.position,op.sex,op.status").
		Scopes(
			cDto.PassDel("op"),
		).
		Where("op.team_id=?", teamId).
		Find(list).Error
	if err != nil {
		e.Log.Errorf("OrgPlayerService GetPage error:%s \r\n", err)
		return err
	}
	return nil
}

// GetPage 获取OrgMatchEvaluate列表
func (e *OrgPlayerRank) GetRankTeamInfo(teamId string, seasonId string, data *dto.OrgPlayerRankInfoGetReply) error {
	var err error

	list := make([]dto.OrgPlayerRankGetPageReply, 0)
	err = e.Orm.Table("org_match_team_player as omtp").
		Select("omtp.team_id as id,"+
			"sum(omtp.scoring)as scoring,"+
			"sum(omtp.rebound)as rebound,"+
			"sum(omtp.assist)as assist,"+
			"sum(omtp.steal)as steal,"+
			"sum(omtp.free_throw)as free_throw,"+
			"sum(omtp.block_shot)as block_shot,"+
			"sum(omtp.foul)as foul,"+
			"sum(omtp.two_point_shot)as two_point_shot,"+
			"sum(omtp.three_point_shot)as three_point_shot").
		Joins("left join org_match as om on omtp.match_id = om.id and omtp.rounds = om.rounds").
		Scopes(
			cDto.PassDel("omtp"),
			cDto.SetWhere("om", "season_id", seasonId),
		).
		Group("omtp.team_id").
		Find(&list).Error
	if err != nil {
		e.Log.Errorf("OrgClubPlayer GetPage error:%s \r\n", err)
		return err
	}

	e.rankingScoring(&list)
	for _, v := range list {
		if v.Id == teamId {
			data.ScoringRank = v.Rank
			data.CompositeRank = v.Rank
		}
	}
	e.rankingRebound(&list)
	for _, v := range list {
		if v.Id == teamId {
			data.ReboundRank = v.Rank
		}
	}
	e.rankingSteal(&list)
	for _, v := range list {
		if v.Id == teamId {
			data.ScoringRank = v.Rank
		}
	}
	e.rankingFreeThrow(&list)
	for _, v := range list {
		if v.Id == teamId {
			data.FreeThrowRank = v.Rank
		}
	}
	e.rankingBlockShot(&list)
	for _, v := range list {
		if v.Id == teamId {
			data.BlockShotRank = v.Rank
		}
	}
	e.rankingFoul(&list)
	for _, v := range list {
		if v.Id == teamId {
			data.FoulRank = v.Rank
		}
	}
	e.rankingTwoPointShot(&list)
	for _, v := range list {
		if v.Id == teamId {
			data.TwoPointShotRank = v.Rank
		}
	}
	e.rankingThreePointShot(&list)
	for _, v := range list {
		if v.Id == teamId {
			data.ThreePointShotRank = v.Rank
		}
	}

	return nil
}

func (e *OrgPlayerRank) rankingScoring(list *[]dto.OrgPlayerRankGetPageReply) {
	listData := *list
	sort.Slice(listData, func(i, j int) bool {
		return utils.StringToFloat(listData[i].Scoring) > utils.StringToFloat(listData[j].Scoring)
	})

	//key := 0
	for k := range listData {
		listData[k].Rank = strconv.Itoa(k + 1)
	}

	//listDataA := append(listData[key:key+1], listData[0:key]...)
	//listData = append(listDataA, listData[key+1:]...)
	//*list = listData
	//fmt.Println(listData)
}
func (e *OrgPlayerRank) rankingRebound(list *[]dto.OrgPlayerRankGetPageReply) {
	listData := *list
	sort.Slice(listData, func(i, j int) bool {
		return utils.StringToFloat(listData[i].Rebound) > utils.StringToFloat(listData[j].Rebound)
	})

	for k := range listData {
		listData[k].Rank = strconv.Itoa(k + 1)
	}
}

func (e *OrgPlayerRank) rankingAssist(list *[]dto.OrgPlayerRankGetPageReply) {
	listData := *list
	sort.Slice(listData, func(i, j int) bool {
		return utils.StringToFloat(listData[i].Assist) > utils.StringToFloat(listData[j].Assist)
	})

	for k := range listData {
		listData[k].Rank = strconv.Itoa(k + 1)
	}
}
func (e *OrgPlayerRank) rankingSteal(list *[]dto.OrgPlayerRankGetPageReply) {
	listData := *list
	sort.Slice(listData, func(i, j int) bool {
		return utils.StringToFloat(listData[i].Steal) > utils.StringToFloat(listData[j].Steal)
	})

	for k := range listData {
		listData[k].Rank = strconv.Itoa(k + 1)
	}
}
func (e *OrgPlayerRank) rankingFreeThrow(list *[]dto.OrgPlayerRankGetPageReply) {
	listData := *list
	sort.Slice(listData, func(i, j int) bool {
		return utils.StringToFloat(listData[i].FreeThrow) > utils.StringToFloat(listData[j].FreeThrow)
	})

	for k := range listData {
		listData[k].Rank = strconv.Itoa(k + 1)
	}
}

func (e *OrgPlayerRank) rankingBlockShot(list *[]dto.OrgPlayerRankGetPageReply) {
	listData := *list
	sort.Slice(listData, func(i, j int) bool {
		return utils.StringToFloat(listData[i].BlockShot) > utils.StringToFloat(listData[j].BlockShot)
	})

	for k := range listData {
		listData[k].Rank = strconv.Itoa(k + 1)
	}
}

func (e *OrgPlayerRank) rankingFoul(list *[]dto.OrgPlayerRankGetPageReply) {
	listData := *list
	sort.Slice(listData, func(i, j int) bool {
		return utils.StringToFloat(listData[i].Foul) > utils.StringToFloat(listData[j].Foul)
	})

	for k := range listData {
		listData[k].Rank = strconv.Itoa(k + 1)
	}
}

func (e *OrgPlayerRank) rankingTwoPointShot(list *[]dto.OrgPlayerRankGetPageReply) {
	listData := *list
	sort.Slice(listData, func(i, j int) bool {
		return utils.StringToFloat(listData[i].TwoPointShot) > utils.StringToFloat(listData[j].TwoPointShot)
	})

	for k := range listData {
		listData[k].Rank = strconv.Itoa(k + 1)
	}
}

func (e *OrgPlayerRank) rankingThreePointShot(list *[]dto.OrgPlayerRankGetPageReply) {
	listData := *list
	sort.Slice(listData, func(i, j int) bool {
		return utils.StringToFloat(listData[i].ThreePointShot) > utils.StringToFloat(listData[j].ThreePointShot)
	})

	for k := range listData {
		listData[k].Rank = strconv.Itoa(k + 1)
	}
}
