package http

import (
	"crypto/md5"
	"fmt"
	"netease_control_center/globals"
	"strconv"
	"time"
)

const (
	MUSIC_POST_TRY_MAX = 2

	// server err code
	SERVER_RET_NIL_OR_INVALID_LIST = 4004

	// server code,用于触发服务器的命令是否成功的返回code，成功就返回9000
	SERVER_RET_TRIG_CMD_OK = 9000
)

const (
	//ServerIp = "http://api.multimedia.netease.com/imgtest/yqbot16_7676/"
	//ServerIp     = "http://10.240.92.90:8686/"
	URL_API_INIT = "vbox/init/vboxinit.do"

	Server          = "vbox-server.3.163.com"
	ServerIp_ONLINE = "https://vbox-server.3.163.com/"
	ServerIp_TEST   = "http://api.multimedia.netease.com/imgtest/yqbot31_7676/"
)

var (
	ServerIp = ServerIp_ONLINE
	//ServerIp = ServerIp_TEST
)

const (
	URL_POST_FILE  = "vbox/backupfile/upload"
	URL_MUSIC_VBOX = "vbox/music/"

	// song
	BODY_MUSIC_PLAYINFO = "song/playdetail"
	BODY_MUSIC_DETAIL   = "song/hwdetail"

	// list
	BODY_RED_FM     = "playlist/hwlike"
	BODY_LIST_BY_ID = "playlist/hwtracks"
	BODY_FM_PRIVATE = "radio/hwget"
	BODY_ALBUM_BYID = "album/hwdetail"
	BODY_ARTIST     = "artist/hwsongs"

	BODY_DAILY_PUSH       = "recommend/everyday/hwsongs"
	BODY_NEW_TOPLIST      = "top/new"
	BODY_HOT_TOLIST       = "top/hot"
	BODY_DENON_TOPLIST    = "top/denon"
	BODY_CLASSIC_TOPLIST  = "top/classic"
	BODY_BEATPORT_TOPLIST = "top/beatport "
	BODY_ORIGINAL_TOPLIST = "top/original"
	BODY_SORIGN_TOPLIST   = "top/soaring"
	BODY_TOPLIST_COMMON   = "top/detail"

	BODY_NEWLIST_COMMON = "song/newlist"

	BODY_SONG_SIMILAR = "song/hwsimilar"
	//lists
	BODY_CREATE_LIST      = "playlist/hwcreated"
	BODY_COLLECT_LIST     = "playlist/hwsubed"
	BODY_ALBUM_BYARTIST   = "artist/hwalbumlist"
	BODY_EXTRADATA_LIST   = "common/getlist"
	BODY_WORD_LIST        = "playlist/hwoftag"
	BODY_SEARCH_WORD_LIST = "playlist/hwoftag/search"

	URL_BIRTHDAY_INFO       = "vbox/user/birthday"
	URL_WEATHER_INFO        = "vbox/weather/query"
	URL_CfgListPush_INFO    = "vbox/runtimeConfig/update"
	URL_Update_Info_For_App = "vbox/informationflow/update/data"

	BODY_Server_Rcmd       = "recommend/song/hwget"
	URL_Music_Share_Rcmd   = "vbox/recommend/get"
	URL_Music_Special_Rcmd = "vbox/music/radio/hwget/special"

	//歌单信息通用请求接口
	URL_Common_GetPlaylist_Rcmd = "vbox/music/common/getplaylist"

	//自然声获取list接口
	URL_Next_Song_Get_Rcmd = "vbox/radio/nature/get"

	//电台detail接口
	URL_Radio_Detail_Rcmd = "vbox/radio/geturl"

	//电台detail接口
	URL_Get_Radio_List_Rcmd = "vbox/radio/common/getlist"

	//music play list info接口
	URL_Get_Music_Play_List_Rcmd = "vbox/music/playlist/detail"

	//电台play list info接口
	URL_Get_Radio_Play_List_Rcmd = "vbox/app/radio/info"
)

type HttpReqbase struct {
	Uuid     *string `json:"uuid"`
	DeviceId string  `json:"deviceid"`
	ChipId   string  `json:"chipId"`
	Bizid    string  `json:"bizid"`
	Os       string  `json:"os"`
	Osv      string  `json:"osv,omitempty"`
	Hv       *string `json:"hv,omitempty"`
	V0       *string `json:"v0"`
	V1       *string `json:"v1"`
	Ip       string  `json:"ip,omitempty"`
	Coord    string  `json:"coord, omitempty"`
	Apn      string  `json:"apn, omitempty"`
}

type HttpReq struct {
	Base *HttpReqbase `json:"reqbase"`
	Body interface{}  `json:"reqparam, omitempty"`
}

type ApiContainer struct {
	Url              string
	ReqparamIsString bool
	IsEncrypted      bool
}

type HttpRspBody struct {
	Code       int         `json:"code"`
	Desc       string      `json:"desc"`
	Detail     interface{} `json:"detail"`
	ServerTime int64       `json:"ts"`
}

type HttpReqFirstRun struct {
	BindUser string `json:"bind_user"`
	Mac      string `json:"mac"`
}

type HttpRspFirstRun struct {
	VboxId  string `json:"vboxid"`
	AesKey  string `json:"aes_key"`
	YxToken string `json:"yxtoken"`
}

type HttpReqInit struct {
	BindUser  string `json:"bind_user"`
	Mac       string `json:"mac"`
	Timestamp string `json:"timestamp"`
	Signature string `json:"signature"`
	NewBoard  bool   `json:"isFirst"`
	VboxName  string `json:"vboxName"`
}

type HttpRspInit struct {
	Vboxid      string `json:"vboxid"`
	AesKey      string `json:"aes_key"`
	YxToken     string `json:"yxtoken"`
	SongUrl     string `json:"songUrl"`
	Channel     int    `json:"channel"`
	ChannelInfo string `json:"channelInfo"`
}

func (this *HttpReqInit) Init(newboard bool, bindUser string, chipId string) {
	this.Timestamp = strconv.FormatInt(time.Now().Unix()*1000, 10)
	this.Mac = "unknow"
	this.BindUser = bindUser
	this.NewBoard = newboard
	this.VboxName = globals.BTNAME

	md5orig := chipId + "|" + this.BindUser + "|" + this.Mac + "|" + this.Timestamp
	this.Signature = fmt.Sprintf("%x", md5.Sum([]byte(md5orig)))
}

type HttpReqRebindUser struct {
	AppUuid string `json:"uuid"`
}

type HttpRspRebindUser struct {
	VboxId  string `json:"vboxid"`
	AesKey  string `json:"aes_key"`
	YxToken string `json:"yxtoken"`
}

type HttpReqQueryBindUser struct {
}
type HttpRspQueryBindUser = globals.AccountInfo

/*IOT*/
type HttpReqDevDiscovery struct {
	DeviceId   string `json:"deviceId"`
	DeviceInfo string `json:"deviceInfo"`
	Challenge  string `json:"challenge"`
}
type HttpRspDeviceDiscovery struct {
	DeviceId   string `json:"deviceId"`
	DeviceInfo string `json:"deviceInfo"`
	Challenge  string `json:"challenge"`
	Signature  string `json:"signature"`
	Tts        string `json:"tts"`
}

type HttpReqDeviceSharedKey struct {
	DeviceId   string `json:"deviceId"`
	DeviceInfo string `json:"deviceInfo"`
	Signature  string `json:"signature"`
}
type HttpRspDeviceSharedKey struct {
	DeviceId   string `json:"deviceId"`
	DeviceInfo string `json:"deviceInfo"`
	SharedKey  string `json:"shareKey"`
}

type HttpReqDeviceRegiste struct {
	DeviceId   string `json:"deviceId"`
	DeviceInfo string `json:"deviceInfo"`
	TokenInfo  string `json:"tokenInfo"`
}
type HttpRspDeviceRegiste struct {
	Tts string `json:"tts"`
}

/*OTA related*/
type HttpReqNewestVersion struct {
	Version string `json:"version"`
}
type HttpRspNewestVersion struct {
	VersionInfo globals.VersionInfo `json:"versionInfo"`
	Upgrade     bool                `json:"upgrade"`
}

type HttpReqLastNormalVersion struct {
}

type HttpRspLastNormalVersion struct {
	NewestVersionInfo globals.VersionInfo `json:"newestVersionInfo"`
	LastVersionInfo   globals.VersionInfo `json:"lastVersionInfo"`
}

type HttpReqGetVersionInfo struct {
	Version string `json:"version"`
}
type HttpRspGetVersionInfo struct {
	VersionInfo globals.VersionInfo `json:"versionInfo"`
}

type HttpReqGetBackupFile struct {
	VboxMac string `json:"vboxMac"`
}
type HttpRspGetBackupFile struct {
	Id            int    `json:"id"`
	VboxMac       string `json:"vboxMac"`
	BackupFileUrl string `json:"backupFileUrl"`
	CreateTime    int    `json:"createTime"`
}

type HttpReqHotfix struct {
	OsType     int    `json:"os_type"` //0 音箱 1 ios 2 安卓
	CurVersion string `json:"cur_version"`
}
type HttpRspHotfix []interface{}

/*Alarm*/
type HttpReqAddAlarm struct {
	Type       int    `json:"type"`
	VoiceType  int    `json:"voiceType"`
	Second     string `json:"second"`
	Minute     string `json:"minute"`
	Hour       string `json:"hour"`
	DayOfMonth string `json:"dayofMonth"`
	Month      string `json:"month"`
	DayofWeek  string `json:"dayofWeek"`
	Year       string `json:"year"`
}
type HttpRspAddAlarm struct {
	AlarmClock globals.AlarmClockInfo `json:"alarmClock"`
}

type HttpReqMultiDelAlarms struct {
	Ids string `json:"ids"`
}
type HttpRspMultiDelAlarms bool

type HttpReqGetRefleshedAlarmList struct {
}
type HttpRspGetRefleshedAlarmList struct {
	Data []globals.AlarmClockInfo `json:"data"`
}

type HttpReqUpdateAlarmClocks struct {
	Ids    string `json:"ids"`
	Status int    `json:"status"`
}
type HttpRspUpdateAlarmClocks bool

//音箱端进行闹钟响起时上报通知
type HttpReqAlarmClockRing struct {
	Id         uint64 `json:"clock_id"`
	InformType int    `json:"informType"`
	Tts        string `json:"tts"`
}
type HttpRspAlarmClockRing bool

/*Remind interfaces*/
//获取提醒列表
type HttpReqRemindGetList struct {
}
type HttpRspRemindGetList struct {
	Data []globals.RemindInfo `json:"data"`
}

//批量删除提醒列表
type HttpReqBatchDeleteReminds struct {
	Ids string `json:"ids"`
}
type HttpRspBatchDeleteReminds bool

//批量更新提醒列表
type HttpReqBatchUpdateReminds struct {
	Ids    string `json:"ids"`
	Status int    `json:"status"`
}
type HttpRspBatchUpdateReminds bool

//硬件端进行刷新获取提醒列表接口
type HttpReqRefreshReminds struct {
}
type HttpRspRefreshReminds struct {
	RemindsList []globals.RemindInfo `json:"data"`
}

//提醒响起时上报通知
type HttpReqRemindRing struct {
	Id         uint64 `json:"remind_id"`
	InformType int    `json:"informType"`
	Tts        string `json:"tts"`
}
type HttpRspRemindRing bool

// 获取一年的节假日
type HttpReqGetHoliday struct {
	Year uint32 `json:"year"`
}
type HttpRspGetHoliday interface{}

/*Common interfaces*/
type HttpReqGetTimeStamp struct {
}
type HttpRspGetTimeStamp struct {
}

/*Player song*/
type reqSongPlayInfo struct {
	SongId string `json:"song_id,omitempty"`
}

type reqMusicInfo struct {
	SongId string `json:"song_id,omitempty"`
}

type reqRadioDetailInfo struct {
	SongId    string             `json:"songId,omitempty"`
	AlbumId   string             `json:"albumId"`
	BizType   globals.BizTypeDef `json:"bizType"`
	ExtraData string             `json:"extraData"`
}

type reqRedFm struct {
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqListId struct {
	PlayListId string                `json:"playlist_id,omitempty"`
	Size       globals.MusicLenType  `json:"size"`
	Start      globals.MusicLenType  `json:"start,omitempty"`
	PlayMode   globals.MusicPlayMode `json:"playMode"`
}

type reqPrivateFM struct {
	Size     globals.MusicLenType  `json:"size"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}

type reqServerRcmd struct {
	PlayMode globals.MusicPlayMode `json:"playMode"`
	WantTts  bool                  `json:"isTts"`
}

type reqMusicShareRcmd struct {
}

type reqMusicSpecialRcmd struct {
	Type     globals.MusicSrcType  `json:"type"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}

type reqCommonGetPlayListRcmd struct {
	Type     globals.MusicSrcType  `json:"type"`
	Id       string                `json:"id"`
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start"`
	ModeId   int64                 `json:"modeId"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}

type reqGetNextSongRcmd struct {
	SongId     string `json:"id"`
	ExtraData  string `json:"extraData"`
	PlaySource int    `json:"playSource,omitempty"`
	Cmd        int    `json:"cmd,omitempty"`
}

type reqGetRadioPlayListRcmd struct {
	SongId    string               `json:"songId,omitempty"`
	AlbumId   string               `json:"albumId"`
	BizType   globals.BizTypeDef   `json:"bizType"`
	Offset    globals.MusicLenType `json:"offset"`
	Limit     globals.MusicLenType `json:"limit"`
	Order     globals.MusicLenType `json:"order"`
	ExtraData string               `json:"extraData"`
}

type reqGetRadioPlayListInfoRcmd struct {
	RadioId string `json:"radioId"`
	ModeId  int64  `json:"modeId"`
}

type reqGetMusicPlayListInfoRcmd struct {
	PlaylistId string `json:"playlist_id"`
	ModeId     int64  `json:"modeId"`
}

type reqAlbumByID struct {
	AlbumId  string                `json:"id,omitempty"`
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqArtist struct {
	Artist   string                `json:"artist_id,omitempty"`
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}

type reqCreateLists struct {
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqCollectLists struct {
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqAlbumByArtist struct {
	Artist   string                `json:"artist_id,omitempty"`
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqByExtraData string
type reqWordLists struct {
	TagName  string                `json:"name,omitempty"`
	Order    string                `json:"order,omitempty"`
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqSearchWordLists struct {
	TagName  string                `json:"name,omitempty"`
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}

type reqSongSimilarList struct {
	Size   globals.MusicLenType `json:"size"`
	SongId string               `json:"song_id"`
	ModeId int64                `json:"modeId"`
}

// 榜单以及每日推荐的请求参数
type reqNewTopList struct {
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqHotTopList struct {
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqDailyPush struct {
	Size     globals.MusicLenType  `json:"size"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqDenonTopList struct {
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqClassicTopList struct {
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqBeatPortTopList struct {
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqOriginalTopList struct {
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}
type reqSorignTopList struct {
	Size     globals.MusicLenType  `json:"size"`
	Start    globals.MusicLenType  `json:"start,omitempty"`
	PlayMode globals.MusicPlayMode `json:"playMode"`
}

type reqTopList struct {
	Size      globals.MusicLenType  `json:"size"`
	Start     globals.MusicLenType  `json:"start,omitempty"`
	PlayMode  globals.MusicPlayMode `json:"playMode"`
	TopListId string                `json:"topListId"`
}

type reqNewList struct {
	Size      globals.MusicLenType  `json:"size"`
	Start     globals.MusicLenType  `json:"start,omitempty"`
	PlayMode  globals.MusicPlayMode `json:"playMode"`
	NewListId string                `json:"newListId"`
}

type reqBirthdayInfo struct {
}

type reqWeather struct {
}

type reqScenesMusic struct {
	TaskType  uint8    `json:"taskType"`
	TaskName  string   `json:"taskName"`
	TaskValue []string `json:"taskValue"`
	Size      uint16   `json:"size"`
	Start     uint16   `json:"start"`
}

type HttpReqInform struct {
	Data       interface{} `json:"data"`
	InformType InformType  `json:"informType"`
}

type HttpReqInform109 struct {
	Cmd        int        `json:"cmd"`
	Content    string     `json:"content"`
	Data       string     `json:"data"`
	InformType InformType `json:"informType"`
}

type HttpRspInform bool

type reqCfgList struct {
	Key string `json:"key,omitempty"`
}

type reqCfgList2 struct {
	Key string `json:"key,omitempty"`
}
type RespCfgList2 = globals.CfgListType

type reqCfgListPush struct {
	Value string `json:"value"`
}
type rspCfgListPush bool

type MusicListServerType struct {
	Src     globals.MusicSrcType
	Id      *string
	Params  *string
	Start   globals.MusicLenType
	Size    globals.MusicLenType
	WantTts bool

	/* 主动请求时，这些字段，服务端不会回传，设备端自己处理 */
	Oftag        *string
	OftagForShow *string
	Mode         globals.MusicPlayMode
	CloudId      string
	ModeId       int64

	ExtraData string
	AlbumID   string

	BizType globals.BizTypeDef
	Order   globals.MusicLenType

	//内部用，主要用于区别自然声的下一首还是获取list
	TrigServer bool
	Cmd        int //需要当前触发服务器的命令，便于以后扩展，当前只有下一首
	Source     int //play Source
}

//获取歌单信息
type PlayListServerType struct {
	Id     *string
	ModeId int64
}

type DataType uint8

const (
	DATA_TYPE_STRING DataType = iota + 1
	DATA_TYPE_SONG
	DATA_TYPE_LIST
	DATA_TYPE_LISTS
)

type InfoForApp struct {
	ResponseId string                `json:"responseId"`
	Cmd        int                   `json:"cmd"`
	DataType   DataType              `json:"dataType"`
	Data       interface{}           `json:"data"`
	Tts        string                `json:"tts"`
	Oftag      string                `json:"oftag"`
	ShowTag    string                `json:"showTag"`
	PlayMode   globals.MusicPlayMode `json:"playMode"`
}
