package red_packet_service

import (
	"bwallet/models"
	"bwallet/pkg/util"
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

type RedPacketInfoResult struct {
	UserId     string  `json:"user_id"`
	UserName   string  `json:"user_name"`
	UserMobile string  `json:"user_mobile"`
	PlatformId string  `json:"platform_id"`
	Type       uint8   `json:"type"`
	CoinId     int32   `json:"coin_id"`
	CoinName   string  `json:"coin_name"`
	Amount     float32 `json:"amount"`
	Size       uint8   `json:"size"`
	To         string  `json:"to"`
	Remain     uint8   `json:"remain"`
	Status     uint8   `json:"status"`
	Remark     string  `json:"remark"`
	CreateAt   int32   `json:"create_at"`
	UpdateAt   int32   `json:"update_at"`
	ExpireAt   int32   `json:"expire_at"`
}

type RedPacketInfoError struct {
	Code    int32  `json:"code"`
	Message string `json:"message"`
}

type RedPacketInfoResp struct {
	Id     int32
	Result RedPacketInfoResult
	Error  RedPacketInfoError
}

type RedPacketReceiveDetailResp struct {
	Id     int32
	Result RedPacketReceiveDetailResult
	Error  RedPacketInfoError
}

type RedPacketReceiveDetailResult struct {
	Rows []RedPacketReceiveDetailRowResult `json:"rows"`
}

type RedPacketReceiveDetailRowResult struct {
	Id         int32   `json:"id"`
	UserId     string  `json:"user_id"`
	UserName   string  `json:"user_name"`
	UserMobile string  `json:"user_mobile"`
	PlatformId string  `json:"platform_id"`
	CoinId     int32   `json:"coin_id"`
	CoinName   string  `json:"coin_name"`
	Amount     float32 `json:"amount"`
	Status     uint8   `json:"status"`
	CreateAt   int32   `json:"create_at"`
}

type Params struct {
	PacketId string `json:"packet_id"`
}

type RedPacketInfoReq struct {
	Method string `json:"method"`
	Params Params `json:"params"`
}

type RedPacket struct {
	PacketId      string `json:"packet_id"`
	LiveId        int32  `json:"live_id"`
	Avatar        string `json:"avatar"`
	Receive       string `json:"receive"`
	UserId        int32  `json:"user_id"`
	Status        uint8  `json:"status"`
	RedPacketInfo RedPacketInfoResp
}

type RedPacketResp struct {
	PacketId      string  `json:"packet_id"`
	UserId        string  `json:"user_id"`
	CoinName      string  `json:"coin_name"`
	Amount        float32 `json:"amount"`
	Size          uint8   `json:"size"`
	Remain        uint8   `json:"remain"`
	Avatar        string  `json:"avatar"`
	UserName      string  `json:"user_name"`
	UserMobile    string  `json:"user_mobile"`
	ReceiveStatus uint8   `json:"receive_status"`
}

func (r *RedPacket) ExistByPacketInfoId() (bool, error) {
	return models.ExistByPacketInfoId(r.PacketId)
}

func (r *RedPacket) GetRedPackets() ([]*RedPacketResp, error) {
	redPacketsInfo, err := models.GetRedPackets(r.getMaps())
	if err != nil {
		return nil, err
	}

	var redPacketResp = []*RedPacketResp{}
	for _, val := range redPacketsInfo {
		if strings.Contains(util.ToString(val.Receive), util.ToString(r.UserId)) {
			continue
		}
		tmp := &RedPacketResp{}
		tmp.PacketId = val.PacketId
		tmp.UserId = val.UserId
		tmp.CoinName = val.CoinName
		tmp.Amount = val.Amount
		tmp.Size = val.Size
		tmp.Remain = val.Remain
		tmp.Avatar = val.Avatar
		tmp.UserName = val.UserName
		tmp.UserMobile = val.UserMobile
		redPacketResp = append(redPacketResp, tmp)
	}

	return redPacketResp, nil
}

func (r *RedPacket) Add() error {
	url := "https://redback.biqianbao.net/red-packet"

	var params RedPacketInfoReq
	params.Method = "Info"
	params.Params.PacketId = r.PacketId
	jsonStr, err := json.Marshal(params)
	if err != nil {
		return err
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	body, _ := ioutil.ReadAll(resp.Body)

	var redPacketResp RedPacketInfoResp
	err = json.Unmarshal(body, &redPacketResp)
	if err != nil {
		return err
	}
	if redPacketResp.Error.Code != 0 {
		fmt.Println(redPacketResp.Error.Message)
	}

	redPacket := map[string]interface{}{
		"packet_id":   r.PacketId,
		"live_id":     r.LiveId,
		"avatar":      r.Avatar,
		"receive":     "[]",
		"user_id":     redPacketResp.Result.UserId,
		"user_name":   redPacketResp.Result.UserName,
		"user_mobile": redPacketResp.Result.UserMobile,
		"platform_id": redPacketResp.Result.PlatformId,
		"type":        redPacketResp.Result.Type,
		"coin_id":     redPacketResp.Result.CoinId,
		"coin_name":   redPacketResp.Result.CoinName,
		"amount":      redPacketResp.Result.Amount,
		"size":        redPacketResp.Result.Size,
		"to":          redPacketResp.Result.To,
		"remain":      redPacketResp.Result.Remain,
		"status":      redPacketResp.Result.Status,
		"remark":      redPacketResp.Result.Remark,
		"create_at":   redPacketResp.Result.CreateAt,
		"update_at":   redPacketResp.Result.UpdateAt,
		"expire_at":   redPacketResp.Result.ExpireAt,
	}

	if err := models.AddRedPacket(redPacket); err != nil {
		return err
	}

	return nil
}

func (r *RedPacket) Edit() error {
	return models.EditRedPacket(r.getMaps(), map[string]interface{}{
		"remain":    r.RedPacketInfo.Result.Remain,
		"status":    r.RedPacketInfo.Result.Status,
		"update_at": r.RedPacketInfo.Result.UpdateAt,
	})
}

func UpdateReceive() error {
	redPacketsInfo, err := models.GetRedPacketsForReceive()
	if err != nil {
		return err
	}
	url := "https://redback.biqianbao.net/red-packet"
	for _, val := range redPacketsInfo {
		var params RedPacketInfoReq
		params.Method = "ReceiveDetail"
		params.Params.PacketId = val.PacketId
		jsonStr, _ := json.Marshal(params)
		if err != nil {
			continue
		}

		req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
		req.Header.Set("Content-Type", "application/json")

		client := &http.Client{}
		resp, err := client.Do(req)
		if err != nil {
			continue
		}
		defer resp.Body.Close()

		body, _ := ioutil.ReadAll(resp.Body)

		var redPacketReceiveDetailResp RedPacketReceiveDetailResp
		err = json.Unmarshal(body, &redPacketReceiveDetailResp)
		if err != nil {
			continue
		}
		if redPacketReceiveDetailResp.Error.Code != 0 {
			continue
		}
		var receive = []int{}
		for _, item := range redPacketReceiveDetailResp.Result.Rows {
			receive = append(receive, util.ToInt(item.UserId))
		}

		jsonString, err := json.Marshal(receive)
		if err != nil {
			continue
		}

		maps := make(map[string]interface{})
		maps["packet_id"] = val.PacketId
		models.EditRedPacket(maps, map[string]interface{}{
			"receive": string(jsonString),
		})
	}

	return nil
}

func UpdateInfo() error {
	maps := make(map[string]interface{})
	maps["status"] = 1
	redPacketsInfo, err := models.GetRedPackets(maps)
	if err != nil {
		return err
	}
	url := "https://redback.biqianbao.net/red-packet"
	for _, val := range redPacketsInfo {
		var params RedPacketInfoReq
		params.Method = "Info"
		params.Params.PacketId = val.PacketId
		jsonStr, _ := json.Marshal(params)
		if err != nil {
			continue
		}

		req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
		req.Header.Set("Content-Type", "application/json")

		client := &http.Client{}
		resp, err := client.Do(req)
		if err != nil {
			continue
		}
		defer resp.Body.Close()

		body, _ := ioutil.ReadAll(resp.Body)

		var redPacketInfoResp RedPacketInfoResp
		err = json.Unmarshal(body, &redPacketInfoResp)
		if err != nil {
			continue
		}
		var redPacketResp RedPacketInfoResp
		err = json.Unmarshal(body, &redPacketResp)
		if err != nil {
			return err
		}
		if redPacketResp.Error.Code != 0 {
			fmt.Println(redPacketResp.Error.Message)
		}
		//if val.UpdateAt != redPacketResp.Result.UpdateAt {
		redPacket := map[string]interface{}{
			"remain":    redPacketResp.Result.Remain,
			"status":    redPacketResp.Result.Status,
			"update_at": redPacketResp.Result.UpdateAt,
		}
		condition := make(map[string]interface{})
		condition["id"] = val.ID
		models.EditRedPacket(condition, redPacket)
		//}
	}

	return nil
}

func (r *RedPacket) getMaps() (map[string]interface{}) {
	maps := make(map[string]interface{})

	if r.LiveId != 0 {
		maps["live_id"] = r.LiveId
	}

	if r.Status != 0 {
		maps["status"] = r.Status
	}
	return maps
}
