package service

import (
	"boss/internal/common"
	"boss/internal/datas"
	"boss/internal/models/order"
	"boss/internal/models/payfor"
	"boss/internal/models/road"
	"boss/internal/models/user"
	"boss/internal/utils/mfa"
	"fmt"
	"math"
	"time"

	"github.com/beego/beego/v2/client/httplib"
	"github.com/beego/beego/v2/core/logs"
	"github.com/beego/beego/v2/server/web"
)

type QueryService struct {
}

func OrderQuery(bankOrderId string) string {
	orderInfo := order.GetOrderByBankOrderId(bankOrderId)
	if orderInfo.BankOrderId == "" || len(orderInfo.BankOrderId) == 0 {
		logs.Error("不存在这样的订单，订单查询结束")
		return "不存在这样的订单"
	}

	if orderInfo.Status != "" && orderInfo.Status != "wait" {
		logs.Error(fmt.Sprintf("该订单=%s，已经处理完毕，", bankOrderId))
		return "该订单已经处理完毕"
	}

	// 向gateway发送请求，请求上游的支付结果
	gUrl, _ := web.AppConfig.String("gateway::host")
	gUrl = gUrl + "gateway/supplier/order/query" + "?" + "bankOrderId=" + bankOrderId
	res, err := httplib.Get(gUrl).String()
	if err != nil {
		logs.Error("获取gateway上游订单查询结果失败：" + err.Error())
	}

	logs.Info("请求远程地址", gUrl, "远程返回结果：", res)
	return res
}

func (c *QueryService) SupplierOrderQuery(bankOrderId string) *datas.KeyDataJSON {
	keyDataJSON := new(datas.KeyDataJSON)
	keyDataJSON.Code = 200
	exist := order.BankOrderIdIsExist(bankOrderId)
	if !exist {
		keyDataJSON.Msg = "该订单不存在"
		keyDataJSON.Code = -1
	}

	msg := OrderQuery(bankOrderId)

	keyDataJSON.Msg = msg
	return keyDataJSON
}

func (c *QueryService) SupplierPayForQuery(bankOrderId string) *datas.KeyDataJSON {
	keyDataJSON := new(datas.KeyDataJSON)
	keyDataJSON.Code = 200

	if bankOrderId == "" {
		keyDataJSON.Code = -1
		keyDataJSON.Msg = "不存在这样的代付订单"
	} else {
		payFor := payfor.GetPayForByBankOrderId(bankOrderId)
		if payFor.RoadUid == "" {
			keyDataJSON.Msg = "该代付订单没有对应的通道uid"
		} else {
			result := querySupplierPayForResult(bankOrderId)
			if result {
				keyDataJSON.Msg = "处理成功！"
			} else {
				keyDataJSON.Msg = "处理失败！"
			}
		}
	}
	return keyDataJSON
}

func querySupplierPayForResult(bankOrderId string) bool {
	payforUrl, _ := web.AppConfig.String("gateway::host")
	u := payforUrl + "gateway/supplier/payfor/query" + "?bankOrderId=" + bankOrderId
	s, err := httplib.Get(u).String()
	if err != nil {
		logs.Error("处理代付查询请求gateway失败：", err)
		return false
	}
	if s == "fail" {
		return false
	} else {
		return true
	}
}

func QueryTotalSummary(params map[string]string) order.Summary {
	orderInfoList := order.GetOrderByMap(params, -1, 0)
	bankIdList := make([]string, 0)
	for _, info := range orderInfoList {
		bankIdList = append(bankIdList, info.BankOrderId)
	}
	orderProfitList := order.GetOrderProfitListByBankOrderIdList(bankIdList)
	supplierAll := 0.0
	platformAll := 0.0
	agentAll := 0.0
	allAmount := 0.0
	totalNum := 0
	succeedNum := 0
	succeedPaidAmount := 0.0
	for _, v := range orderProfitList {
		totalNum += 1
		allAmount += v.ShowAmount //订单总金额
		if v.Status != common.OrderStatusSuccess {
			continue
		}
		succeedNum += 1
		succeedPaidAmount += v.FactAmount
		supplierAll += v.SupplierProfit //上游利润
		platformAll += v.PlatformProfit //平台利润
		agentAll += v.AgentProfit       //代理利润
	}
	succeedRate := 0.0
	if totalNum != 0 {
		succeedRate = math.Round(float64(succeedNum)/float64(totalNum)*100*100) / 100
	} else {
		succeedRate = 0
	}
	return order.Summary{
		TotalNum:       totalNum,
		TotalAmount:    math.Round(allAmount*100) / 100,
		PaidNum:        succeedNum,
		PaidAmount:     math.Round(succeedPaidAmount*100) / 100,
		PlatformIncome: math.Round(platformAll*100) / 100,
		SucceedRate:    succeedRate,
	}
}

func QuerySummaryByOrderInfo(infoInfoList []order.OrderInfo) order.Summary {
	orderProfitInfoList := make([]order.OrderProfitInfo, 0)

	for _, info := range infoInfoList {
		orderProfitInfoList = append(orderProfitInfoList, order.GetOrderProfitByBankOrderId(info.BankOrderId))
	}

	totalNum := 0
	todayAllAmount := 0.0
	todaySupplierAll := 0.0
	todayPlatformAll := 0.0
	todayAgentAll := 0.0
	TodaySuccessNum := 0

	for _, info := range orderProfitInfoList {
		totalNum += 1
		todayAllAmount += info.FactAmount

		if info.Status != common.OrderStatusSuccess {
			continue
		}

		todaySupplierAll += info.SupplierProfit
		todayPlatformAll += info.PlatformProfit
		todayAgentAll += info.AgentProfit
		TodaySuccessNum += 1
	}

	succeedRate := 0.0

	if totalNum != 0 {
		succeedRate = math.Round(float64(TodaySuccessNum)/float64(totalNum)*100*100) / 100
	} else {
		succeedRate = 0
	}

	return order.Summary{
		TotalNum:       totalNum,
		TotalAmount:    math.Round(todayAllAmount*100) / 100,
		PaidNum:        TodaySuccessNum,
		PlatformIncome: math.Round(todayPlatformAll*100) / 100,
		AgencyIncome:   todayAgentAll,
		SucceedRate:    succeedRate,
	}
}

func QueryTodaySummary(params map[string]string) order.Summary {
	now := time.Now()
	todayAtMidnight := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
	tomorrowAtMidNight := time.Date(now.Year(), now.Month(), now.Day(), 59, 59, 59, 0, now.Location())
	st := todayAtMidnight.Format("2006-01-02 15:04:05")
	end := tomorrowAtMidNight.Format("2006-01-02 15:04:05")
	paramsProfit := params
	if startTimeStr, exists := paramsProfit["create_time__gte"]; exists {
		startTime, err := time.Parse("2006-01-02 15:04:05", startTimeStr)
		if err != nil {
			paramsProfit["create_time__gte"] = st
		} else {
			if tomorrowAtMidNight.Before(startTime) || todayAtMidnight.After(startTime) {
				paramsProfit["create_time__gte"] = st
			}
		}
	} else {
		paramsProfit["create_time__gte"] = st
	}

	if endTimeStr, exists := paramsProfit["create_time__lte"]; exists {
		endTime, err := time.Parse("2006-01-02 15:04:05", endTimeStr)
		if err != nil {
			paramsProfit["create_time__gte"] = st
		} else {
			if tomorrowAtMidNight.Before(endTime) || todayAtMidnight.After(endTime) {
				paramsProfit["create_time__gte"] = st
			}
		}
	} else {
		paramsProfit["create_time__lte"] = end
	}
	orderInfoList := order.GetOrderByMap(paramsProfit, -1, 0)
	bankIdList := make([]string, 0)

	for _, info := range orderInfoList {
		bankIdList = append(bankIdList, info.BankOrderId)
	}
	dataInfo := order.GetOrderProfitListByBankOrderIdList(bankIdList)
	totalNum := 0
	todaySuccessNum := 0
	todayAllAmount := 0.0
	todaySupplierAll := 0.0
	todayPlatformAll := 0.0
	todayAgentAll := 0.0
	todayPaidAmount := 0.0
	for _, info := range dataInfo {
		totalNum += 1
		todayAllAmount += info.FactAmount
		if info.Status != common.OrderStatusSuccess {
			continue
		}
		todaySupplierAll += info.SupplierProfit
		todayPlatformAll += info.PlatformProfit
		todayAgentAll += info.AgentProfit
		todayPaidAmount += info.FactAmount
		todaySuccessNum += 1
	}
	succeedRate := 0.0
	if totalNum != 0 {
		succeedRate = math.Round(float64(todaySuccessNum)/float64(totalNum)*100*100) / 100
	}
	return order.Summary{
		TotalNum:       totalNum,
		TotalAmount:    math.Round(todayAllAmount*100) / 100,
		PaidNum:        todaySuccessNum,
		PaidAmount:     todayPaidAmount,
		PlatformIncome: math.Round(todayPlatformAll*100) / 100,
		AgencyIncome:   todayAgentAll,
		SucceedRate:    succeedRate,
	}
}

func ValidTotp(accountUid, totpCode string) bool {
	userInfo := user.GetUserInfoByUserID(accountUid)
	if userInfo.Id == 0 {
		return false
	}
	if userInfo.OtpSecret == "" {
		return true
	}
	return mfa.ValidCode(totpCode, userInfo.OtpSecret)
}

func QueryRoad() []road.RoadInfo {
	roadInfoList := road.GetAllRoad(map[string]string{})
	return roadInfoList
}
