package coach_client

import (
	"context"
	"crypto/tls"
	"fmt"
	"time"

	"github.com/bytedance/sonic"
	"github.com/cloudwego/hertz/pkg/app/client"
	"github.com/cloudwego/hertz/pkg/network/standard"
	"github.com/cloudwego/hertz/pkg/protocol"
	"github.com/corpix/uarand"
)

type XMacHeader string

const (
	XMac_Coach  XMacHeader = "e6d4b3d780db4251bc4b6b54f41ee7b0"
	XMac_Outlet XMacHeader = "b55d4769f3e768630046291ee2ee26f0"
)

type CN struct {
	c    *client.Client
	xmac XMacHeader
}

func CNClient(xmac XMacHeader) (cli *CN, err error) {
	cli = new(CN)
	clientCfg := &tls.Config{
		InsecureSkipVerify: true,
	}
	cli.c, err = client.NewClient(
		client.WithTLSConfig(clientCfg),
		client.WithDialer(standard.NewDialer()),
	)
	cli.xmac = xmac
	return
}

type CNData interface {
	ItemListData
}

type CNResponse[data CNData] struct {
	Data       data   `json:"data"`
	Msg        string `json:"msg"`
	Rid        string `json:"rid"`
	StatusCode string `json:"statusCode"`
}

type ItemListData struct {
	Count       int      `json:"count"`
	CurrentPage int      `json:"currentPage"`
	Items       []CNItem `json:"items"`
	Size        int      `json:"size"`
	TotalPages  int      `json:"totalPages"`
}

type CNItem struct {
	Code            string  `json:"code"`
	DiscountRateMin float64 `json:"discountRateMin"`
	Id              int     `json:"id"`
	Images          []struct {
		Imgs []struct {
			Config   string `json:"config"`
			Img      string `json:"img"`
			Position int    `json:"position"`
			Resource string `json:"resource"`
			Type     int    `json:"type"`
		} `json:"imgs"`
		ItemPropId int `json:"itemPropId"`
	} `json:"images"`
	ListPrice   float64 `json:"listPrice"`
	SalePrice   float64 `json:"salePrice"`
	SkuMaxPrice float64 `json:"skuMaxPrice"`
	Stock       int     `json:"stock"`
	Style       string  `json:"style"`
	Title       string  `json:"title"`
}

func (c *CN) ListItems(_ctx context.Context, page, size int) (ItemListData, error) {
	req, resp := protocol.AcquireRequest(), protocol.AcquireResponse()
	defer func() {
		protocol.ReleaseRequest(req)
		protocol.ReleaseResponse(resp)
	}()
	page = max(page, 1)
	size = max(size, 50)
	req.SetRequestURI("https://ec-api.coach.com.cn/api/v2/item/search")
	req.SetMethod("GET")
	req.SetHeader("X-Ma-C", string(c.xmac))
	req.SetHeader("User-Agent", uarand.GetRandom())
	req.SetQueryString(fmt.Sprintf("scope=shop&pageNo=%d&pageSize=%d", page, size))

	ctx, cancel := context.WithTimeout(_ctx, time.Second*30)
	defer cancel()
	err := c.c.Do(ctx, req, resp)
	if err != nil {
		return ItemListData{}, err
	}
	var respData CNResponse[ItemListData]
	if err = sonic.Unmarshal(resp.Body(), &respData); err != nil {
		return ItemListData{}, err
	}
	if respData.StatusCode != "100010" {
		return ItemListData{}, fmt.Errorf("status code: %s, msg: %s", respData.StatusCode, respData.Msg)
	}
	return respData.Data, nil
}