package mtwmapi

import (
	"fmt"
	"net/http"
	"strings"

	"git.rosy.net.cn/baseapi/platformapi"
	"git.rosy.net.cn/baseapi/utils"
)

const (
	userURL  = "http://i.waimai.meituan.com"
	orderURL = "https://shangoue.meituan.com"
	actURL   = "https://waimaieapp.meituan.com"
)

const (
	ResponseCodeSuccess = 0
)

type ListShopItem struct {
	Address         string `json:"address"`
	AveragePriceTip string `json:"averagePriceTip"`
	DeliveryTimeTip string `json:"deliveryTimeTip"`
	DeliveryType    int    `json:"deliveryType"`
	Distance        string `json:"distance"`
	MinPriceTip     string `json:"minPriceTip"`
	MonthSalesTip   string `json:"monthSalesTip"`
	MtWmPoiID       string `json:"mtWmPoiId"`
	PicURL          string `json:"picUrl"`
	PoiTypeIcon     string `json:"poiTypeIcon"`
	ShippingFeeTip  string `json:"shippingFeeTip"`
	ShippingTime    string `json:"shipping_time"`
	ShopName        string `json:"shopName"`
	Status          int    `json:"status"`
	StatusDesc      string `json:"statusDesc"`
	WmPoiScore      int    `json:"wmPoiScore"`
}

var (
	actionHostMap = map[string]string{
		"v2/order/receive/processed/w/distribute/tipAmount/v2":     orderURL,
		"v2/order/receive/processed/r/distribute/list/v2":          orderURL,
		"reuse/sc/product/packageprice/w/update":                   orderURL,
		"reuse/sc/product/packageprice/r/get":                      orderURL,
		"reuse/sc/product/retail/r/getStandardProductListWithCond": orderURL,
		"api/sg/promotion/invite/centerList":                       actURL,
		"api/invite/detail":                                        actURL,
		"v2/logon/setToken":                                        orderURL,
		"reuse/sc/product/retail/r/searchListPage":                 orderURL,
	}
)

func getRootURL(subURL string) (rootURL string) {
	rootURL = actionHostMap[subURL]
	if rootURL == "" {
		rootURL = userURL
	}
	return rootURL
}

func (a *API) AccessUserPage2(subURL string, params map[string]interface{}, isPost bool) (retVal map[string]interface{}, err error) {
	if a.GetCookieCount() == 0 {
		return nil, fmt.Errorf("需要设置User Cookie才能使用此方法")
	}
	rootURL := getRootURL(subURL)
	err = platformapi.AccessPlatformAPIWithRetry(a.client,
		func() *http.Request {
			var request *http.Request
			if isPost {
				fullURL := utils.GenerateGetURL(rootURL, subURL, nil)
				request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(params).Encode()))
				request.Header.Set("charset", "UTF-8")
				request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
				request.Header.Set("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1")
				request.Header.Set("Pragma", "no-cache")
				if subURL == `reuse/sc/product/retail/r/searchListPage` {
					//request.Header.Set("")
				}
			} else {
				request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(rootURL, subURL, params), nil)
			}
			a.FillRequestCookies(request)
			return request
		},
		a.config,
		func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
			if jsonResult1 == nil {
				return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
			}
			retVal = jsonResult1
			if jsonResult1["code"] == nil {
				return platformapi.ErrLevelGeneralFail, fmt.Errorf("返回结果格式不正常")
			}
			code := int(utils.MustInterface2Int64(jsonResult1["code"]))
			if code == ResponseCodeSuccess {
				retVal, _ = jsonResult1["data"].(map[string]interface{})
				return platformapi.ErrLevelSuccess, nil
			}
			newErr := utils.NewErrorIntCode(jsonResult1["msg"].(string), code)
			return platformapi.ErrLevelCodeIsNotOK, newErr
		})
	return retVal, err
}

func (a *API) AccessUserPage(subURL string, params map[string]interface{}) (retVal map[string]interface{}, err error) {
	return a.AccessUserPage2(subURL, params, true)
}

func (a *API) AccessUserPage3(subURL string, params map[string]interface{}) (retVal map[string]interface{}, err error) {
	return a.AccessUserPage2(subURL, params, false)
}

func (a *API) GetStoreList(lng, lat float64) (shopList []*ListShopItem, err error) {
	params := map[string]interface{}{
		"sortId":           1,
		"navigateType":     101578,
		"firstCategoryId":  101578,
		"secondCategoryId": 101578,
		"initialLng":       lng,
		"initialLat":       lat,
		"geoType":          2,
		"wm_longitude":     int(lng * 1000000),
		"wm_latitude":      int(lat * 1000000),
	}
	startIndex := 0
	for {
		params["startIndex"] = startIndex
		result, err := a.AccessUserPage("openh5/channel/kingkongshoplist", params)
		if err != nil {
			return shopList, err
		}
		var batchShopList []*ListShopItem
		if err = utils.Map2StructByJson(result["shopList"], &batchShopList, false); err != nil {
			return shopList, err
		}
		shopList = append(shopList, batchShopList...)
		if poiHasNextPage, ok := result["poiHasNextPage"].(bool); !ok || !poiHasNextPage {
			break
		}
		startIndex++
	}
	return shopList, nil
}

func (a *API) GetStoreInfo(storeID string) (storeInfo map[string]interface{}, err error) {
	params := map[string]interface{}{
		"mtWmPoiId": storeID,
	}
	retVal, err := a.AccessUserPage("openh5/poi/info", params)
	return retVal, err
}

type GetStandardProductListWithCondResult struct {
	IsMedicare   bool        `json:"isMedicare"`
	SpVideoVo    interface{} `json:"spVideoVo"`
	LockStatus   int         `json:"lockStatus"`
	LockTips     interface{} `json:"lockTips"`
	SpPicContent string      `json:"spPicContent"`
	ExistInPoi   bool        `json:"existInPoi"`
	MonthSale    int         `json:"monthSale"`
	Skus         []struct {
		ShelfNum      string      `json:"shelfNum"`
		ItemNum       string      `json:"itemNum"`
		LimitStock    int         `json:"limitStock"`
		Sequence      int         `json:"sequence"`
		Weight        float64     `json:"weight"`
		Price         interface{} `json:"price"`
		WeightUnit    string      `json:"weightUnit"`
		SkuAttrs      interface{} `json:"skuAttrs"`
		Spec          string      `json:"spec"`
		Stock         interface{} `json:"stock"`
		MinOrderCount int         `json:"minOrderCount"`
		Unit          string      `json:"unit"`
		UpcCode       string      `json:"upcCode"`
		BizValue      interface{} `json:"bizValue"`
		ProductName   interface{} `json:"productName"`
		BoxPrice      float64     `json:"boxPrice"`
		BoxNum        int         `json:"boxNum"`
		ID            int         `json:"id"`
	} `json:"skus"`
	CategoryAttrMap struct {
		Num1200000088 struct {
			SupportFilter int    `json:"supportFilter"`
			Application   string `json:"application"`
			OptionMaxSize int    `json:"optionMaxSize"`
			TextMaxLength int    `json:"textMaxLength"`
			CharacterType string `json:"characterType"`
			SupportExtend string `json:"supportExtend"`
			AttrName      string `json:"attrName"`
			Sequence      int    `json:"sequence"`
			Level         int    `json:"level"`
			InputType     int    `json:"inputType"`
			WmPoiID       int    `json:"wmPoiId"`
			CategoryID    int    `json:"categoryId"`
			IsLeaf        int    `json:"isLeaf"`
			SpuID         int    `json:"spuId"`
			ValueList     []struct {
				Sequence    int         `json:"sequence"`
				Text        interface{} `json:"text"`
				IsLeaf      int         `json:"isLeaf"`
				ValueID     int         `json:"valueId"`
				ValueIDPath string      `json:"valueIdPath"`
				ValuePath   string      `json:"valuePath"`
				Selected    int         `json:"selected"`
				Value       string      `json:"value"`
			} `json:"valueList"`
			AttrID     int `json:"attrId"`
			AttrType   int `json:"attrType"`
			TemplateID int `json:"templateId"`
			IsRequired int `json:"isRequired"`
			ID         int `json:"id"`
		} `json:"1200000088"`
		Num1200000094 struct {
			SupportFilter int    `json:"supportFilter"`
			Application   string `json:"application"`
			OptionMaxSize int    `json:"optionMaxSize"`
			TextMaxLength int    `json:"textMaxLength"`
			CharacterType string `json:"characterType"`
			SupportExtend string `json:"supportExtend"`
			AttrName      string `json:"attrName"`
			Sequence      int    `json:"sequence"`
			Level         int    `json:"level"`
			InputType     int    `json:"inputType"`
			WmPoiID       int    `json:"wmPoiId"`
			CategoryID    int    `json:"categoryId"`
			IsLeaf        int    `json:"isLeaf"`
			SpuID         int    `json:"spuId"`
			ValueList     []struct {
				Sequence    int         `json:"sequence"`
				Text        interface{} `json:"text"`
				IsLeaf      int         `json:"isLeaf"`
				ValueID     int         `json:"valueId"`
				ValueIDPath string      `json:"valueIdPath"`
				ValuePath   string      `json:"valuePath"`
				Selected    int         `json:"selected"`
				Value       string      `json:"value"`
			} `json:"valueList"`
			AttrID     int `json:"attrId"`
			AttrType   int `json:"attrType"`
			TemplateID int `json:"templateId"`
			IsRequired int `json:"isRequired"`
			ID         int `json:"id"`
		} `json:"1200000094"`
		Num1200000135 struct {
			SupportFilter int    `json:"supportFilter"`
			Application   string `json:"application"`
			OptionMaxSize int    `json:"optionMaxSize"`
			TextMaxLength int    `json:"textMaxLength"`
			CharacterType string `json:"characterType"`
			SupportExtend string `json:"supportExtend"`
			AttrName      string `json:"attrName"`
			Sequence      int    `json:"sequence"`
			Level         int    `json:"level"`
			InputType     int    `json:"inputType"`
			WmPoiID       int    `json:"wmPoiId"`
			CategoryID    int    `json:"categoryId"`
			IsLeaf        int    `json:"isLeaf"`
			SpuID         int    `json:"spuId"`
			ValueList     []struct {
				Sequence    int         `json:"sequence"`
				Text        interface{} `json:"text"`
				IsLeaf      int         `json:"isLeaf"`
				ValueID     int         `json:"valueId"`
				ValueIDPath interface{} `json:"valueIdPath"`
				ValuePath   interface{} `json:"valuePath"`
				Selected    int         `json:"selected"`
				Value       string      `json:"value"`
			} `json:"valueList"`
			AttrID     int `json:"attrId"`
			AttrType   int `json:"attrType"`
			TemplateID int `json:"templateId"`
			IsRequired int `json:"isRequired"`
			ID         int `json:"id"`
		} `json:"1200000135"`
		Num1200000210 struct {
			SupportFilter int    `json:"supportFilter"`
			Application   string `json:"application"`
			OptionMaxSize int    `json:"optionMaxSize"`
			TextMaxLength int    `json:"textMaxLength"`
			CharacterType string `json:"characterType"`
			SupportExtend string `json:"supportExtend"`
			AttrName      string `json:"attrName"`
			Sequence      int    `json:"sequence"`
			Level         int    `json:"level"`
			InputType     int    `json:"inputType"`
			WmPoiID       int    `json:"wmPoiId"`
			CategoryID    int    `json:"categoryId"`
			IsLeaf        int    `json:"isLeaf"`
			SpuID         int    `json:"spuId"`
			ValueList     []struct {
				Sequence    int         `json:"sequence"`
				Text        interface{} `json:"text"`
				IsLeaf      int         `json:"isLeaf"`
				ValueID     int         `json:"valueId"`
				ValueIDPath interface{} `json:"valueIdPath"`
				ValuePath   interface{} `json:"valuePath"`
				Selected    int         `json:"selected"`
				Value       string      `json:"value"`
			} `json:"valueList"`
			AttrID     int `json:"attrId"`
			AttrType   int `json:"attrType"`
			TemplateID int `json:"templateId"`
			IsRequired int `json:"isRequired"`
			ID         int `json:"id"`
		} `json:"1200000210"`
	} `json:"categoryAttrMap"`
	SpuSaleAttrMap      interface{} `json:"spuSaleAttrMap"`
	OriginName          string      `json:"originName"`
	SetOrigin           bool        `json:"setOrigin"`
	SetWeightUnit       bool        `json:"setWeightUnit"`
	AvgPrice            int         `json:"avgPrice"`
	SetAvgPrice         bool        `json:"setAvgPrice"`
	SetEan              bool        `json:"setEan"`
	SetShelfStatus      bool        `json:"setShelfStatus"`
	ShelfStatus         int         `json:"shelfStatus"`
	RefCount            int         `json:"refCount"`
	SetRefCount         bool        `json:"setRefCount"`
	IsReceipt           int         `json:"is_receipt"`
	SetPic              bool        `json:"setPic"`
	CheckerID           int         `json:"checkerId"`
	SetCheckerID        bool        `json:"setCheckerId"`
	CheckerName         string      `json:"checkerName"`
	SetCheckerName      bool        `json:"setCheckerName"`
	CheckRemark         interface{} `json:"checkRemark"`
	SetCheckRemark      bool        `json:"setCheckRemark"`
	CheckTime           int         `json:"checkTime"`
	SetCheckTime        bool        `json:"setCheckTime"`
	IsMulitEan          int         `json:"isMulitEan"`
	SetIsMulitEan       bool        `json:"setIsMulitEan"`
	SetCategoryNamePath bool        `json:"setCategoryNamePath"`
	CategoryIDPath      string      `json:"categoryIdPath"`
	SetCategoryIDPath   bool        `json:"setCategoryIdPath"`
	SetBrandNamePath    bool        `json:"setBrandNamePath"`
	SuggestedPrice      int         `json:"suggestedPrice"`
	SetSuggestedPrice   bool        `json:"setSuggestedPrice"`
	SetRiseMax          bool        `json:"setRiseMax"`
	SetDropMax          bool        `json:"setDropMax"`
	ExpPeriod           int         `json:"expPeriod"`
	SetExpPeriod        bool        `json:"setExpPeriod"`
	ExpUnit             int         `json:"expUnit"`
	SetExpUnit          bool        `json:"setExpUnit"`
	SuppleFact          string      `json:"suppleFact"`
	SetSuppleFact       bool        `json:"setSuppleFact"`
	SubOrigin           int         `json:"subOrigin"`
	SetSubOrigin        bool        `json:"setSubOrigin"`
	SalePriceWeight     int         `json:"salePriceWeight"`
	SetSalePriceWeight  bool        `json:"setSalePriceWeight"`
	SrcPic              string      `json:"srcPic"`
	SetSrcPic           bool        `json:"setSrcPic"`
	BrandZhName         interface{} `json:"brandZhName"`
	SetBrandZhName      bool        `json:"setBrandZhName"`
	BrandEnName         interface{} `json:"brandEnName"`
	SetBrandEnName      bool        `json:"setBrandEnName"`
	SetIsReceipt        bool        `json:"setIs_receipt"`
	ReceiptorID         int         `json:"receiptorId"`
	SetReceiptorID      bool        `json:"setReceiptorId"`
	SpecNew             float64     `json:"specNew"`
	SetSpecNew          bool        `json:"setSpecNew"`
	SpecUnit            string      `json:"specUnit"`
	SetSpecUnit         bool        `json:"setSpecUnit"`
	SpecCount           int         `json:"specCount"`
	SetSpecCount        bool        `json:"setSpecCount"`
	SpecCountUnit       string      `json:"specCountUnit"`
	SetSpecCountUnit    bool        `json:"setSpecCountUnit"`
	IsBigSpec           int         `json:"isBigSpec"`
	SetIsBigSpec        bool        `json:"setIsBigSpec"`
	WeightNew           float64     `json:"weightNew"`
	SetWeightNew        bool        `json:"setWeightNew"`
	Description         string      `json:"description"`
	Sequence            int         `json:"sequence"`
	SetSize             bool        `json:"setSize"`
	Source              int         `json:"source"`
	Origin              int         `json:"origin"`
	OriginType          int         `json:"originType"`
	SetName             bool        `json:"setName"`
	SetID               bool        `json:"setId"`
	Weight              int         `json:"weight"`
	SetWeight           bool        `json:"setWeight"`
	Valid               int         `json:"valid"`
	BrandID             int         `json:"brandId"`
	CategoryName        string      `json:"categoryName"`
	CategoryID          int         `json:"categoryId"`
	WeightUnit          interface{} `json:"weightUnit"`
	Pic                 string      `json:"pic"`
	Spec                string      `json:"spec"`
	Ctime               int         `json:"ctime"`
	EanList             []string    `json:"eanList"`
	CategoryNamePath    string      `json:"categoryNamePath"`
	Utime               int         `json:"utime"`
	Unit                string      `json:"unit"`
	IsSp                int         `json:"isSp"`
	Ean                 string      `json:"ean"`
	CheckStatus         int         `json:"checkStatus"`
	SpName              string      `json:"spName"`
	BrandNamePath       string      `json:"brandNamePath"`
	Cuid                int         `json:"cuid"`
	RiseMax             int         `json:"riseMax"`
	DropMax             int         `json:"dropMax"`
	SetSpName           bool        `json:"setSpName"`
	SetOriginType       bool        `json:"setOriginType"`
	SetIsSp             bool        `json:"setIsSp"`
	SetBrandID          bool        `json:"setBrandId"`
	SetCheckStatus      bool        `json:"setCheckStatus"`
	EanListSize         int         `json:"eanListSize"`
	EanListIterator     []string    `json:"eanListIterator"`
	SetEanList          bool        `json:"setEanList"`
	SetCategoryID       bool        `json:"setCategoryId"`
	SetSpec             bool        `json:"setSpec"`
	Muid                int         `json:"muid"`
	SetMuid             bool        `json:"setMuid"`
	SetSource           bool        `json:"setSource"`
	SetUnit             bool        `json:"setUnit"`
	SetSequence         bool        `json:"setSequence"`
	SetCtime            bool        `json:"setCtime"`
	SetUtime            bool        `json:"setUtime"`
	SetValid            bool        `json:"setValid"`
	SetDescription      bool        `json:"setDescription"`
	Cuname              interface{} `json:"cuname"`
	SetCuname           bool        `json:"setCuname"`
	Muname              interface{} `json:"muname"`
	SetMuname           bool        `json:"setMuname"`
	SetCuid             bool        `json:"setCuid"`
	SetCategoryName     bool        `json:"setCategoryName"`
	Name                string      `json:"name"`
	ID                  int         `json:"id"`
	Size                string      `json:"size"`
}

//https://shangoue.meituan.com/reuse/sc/product/retail/r/getStandardProductListWithCond
func (a *API) GetStandardProductListWithCond(upc string) (getStandardProductListWithCondResult *GetStandardProductListWithCondResult, err error) {
	params := map[string]interface{}{
		"keyword":  upc,
		"pageNo":   1,
		"pageSize": 20,
	}
	result, err := a.AccessUserPage("reuse/sc/product/retail/r/getStandardProductListWithCond", params)
	if err == nil {
		if len(result["list"].([]interface{})) == 0 {
			return nil, err
		} else {
			utils.Map2StructByJson(result["list"].([]interface{})[0], &getStandardProductListWithCondResult, false)
		}
	}
	return getStandardProductListWithCondResult, err
}

func (a *API) SetTokenPage() (err error) {
	params := map[string]interface{}{
		"acctId":         57396785,
		"wmPoiId":        -1,
		"bsid":           "y-5VaK3uFxP705tpXsnJPee2sJc9dJ23LmGwYmg2kCO81d9EjD7TJrUeflcJRrqRxg9DFCNGhrJSaWYSCgXvxg",
		"device_uuid":    "!ac34e5d7-5472-47fd-b7c4-029c1f7e7576",
		"token":          "1bWbK5VbK50E2BmIhIH2zHB-am_y7mB37yXHm6RLZWx4*",
		"region_version": 0,
		"region_id":      "",
	}
	a.SetCookieWithStr(`
		uuid=350a86177dd64c43b875.1619071312.1.0.0; _lxsdk_cuid=178f88ba3cec8-0db6e384ebfa36-5b1f321a-1fa400-178f88ba3cec8; _lxsdk=178f88ba3cec8-0db6e384ebfa36-5b1f321a-1fa400-178f88ba3cec8; uuid_update=true; _ga=GA1.2.2092976141.1619502287; pushToken=04OVj3PayJdT62H_Irz4BXYfNQHh9N33gDO_WFnGaovs*; device_uuid=!ac34e5d7-5472-47fd-b7c4-029c1f7e7576; mtcdn=K; lsu=; e_u_id_3299326472=e5ae16afe444349d24af7d33b66620a1; wpush_server_url=wss://wpush.meituan.com; shopCategory=food; _lxsdk_s=17b15442f31-e81-89b-533%7C%7C187
	`)
	_, err = a.AccessUserPage3("v2/logon/setToken", params)
	return err
}
