syntax = "v1"

info (
	title:   "User API"
	desc:    "API for ppanel"
	author:  "Tension"
	email:   "tension@ppanel.com"
	version: "0.0.1"
)

import "../types.api"

type (
	UpdateUserNotifyRequest {
		EnableBalanceNotify   *bool `json:"enable_balance_notify"`
		EnableLoginNotify     *bool `json:"enable_login_notify"`
		EnableSubscribeNotify *bool `json:"enable_subscribe_notify"`
		EnableTradeNotify     *bool `json:"enable_trade_notify"`
	}
	UpdateUserPasswordRequest {
		Password string `json:"password" validate:"required"`
	}
	QueryUserSubscribeListResponse {
		List  []UserSubscribe `json:"list"`
		Total int64           `json:"total"`
	}
	QueryUserBalanceLogListResponse {
		List  []BalanceLog `json:"list"`
		Total int64        `json:"total"`
	}
	QueryUserCommissionLogListRequest {
		Page int `form:"page"`
		Size int `form:"size"`
	}
	QueryUserCommissionLogListResponse {
		List  []CommissionLog `json:"list"`
		Total int64           `json:"total"`
	}
	BindTelegramResponse {
		Url       string `json:"url"`
		ExpiredAt int64  `json:"expired_at"`
	}
	PreUnsubscribeRequest {
		Id int64 `json:"id"`
	}
	PreUnsubscribeResponse {
		DeductionAmount int64 `json:"deduction_amount"`
	}
	UnsubscribeRequest {
		Id int64 `json:"id"`
	}
	BindOAuthRequest {
		Method   string `json:"method"`
		Redirect string `json:"redirect"`
	}
	BindOAuthResponse {
		Redirect string `json:"redirect"`
	}
	BindOAuthCallbackRequest {
		Method   string      `json:"method"`
		Callback interface{} `json:"callback"`
	}
	GetOAuthMethodsResponse {
		Methods []UserAuthMethod `json:"methods"`
	}
	UnbindOAuthRequest {
		Method string `json:"method"`
	}
	GetLoginLogRequest {
		Page int `form:"page"`
		Size int `form:"size"`
	}
	GetLoginLogResponse {
		List  []UserLoginLog `json:"list"`
		Total int64          `json:"total"`
	}
	GetSubscribeLogRequest {
		Page int `form:"page"`
		Size int `form:"size"`
	}
	GetSubscribeLogResponse {
		List  []UserSubscribeLog `json:"list"`
		Total int64              `json:"total"`
	}
	UpdateBindMobileRequest {
		AreaCode string `json:"area_code" validate:"required"`
		Mobile   string `json:"mobile" validate:"required"`
		Code     string `json:"code" validate:"required"`
	}
	UpdateBindEmailRequest {
		Email string `json:"email" validate:"required"`
	}
	VerifyEmailRequest {
		Email string `json:"email" validate:"required"`
		Code  string `json:"code" validate:"required"`
	}
	GetDeviceListResponse {
		List  []UserDevice `json:"list"`
		Total int64        `json:"total"`
	}
	UnbindDeviceRequest {
		Id int64 `json:"id" validate:"required"`
	}
	UpdateUserSubscribeNoteRequest {
		UserSubscribeId int64  `json:"user_subscribe_id" validate:"required"`
		Note            string `json:"note" validate:"max=500"`
	}
	UpdateUserRulesRequest {
		Rules []string `json:"rules" validate:"required"`
	}
	CommissionWithdrawRequest {
		Amount    int64  `json:"amount"`
		Content   string `json:"content"`
		Method    uint8  `json:"method" validate:"oneof=0 1 2 3"`
		Account   string `json:"account,omitempty"`
		QrCodeUrl string `json:"qr_code_url,omitempty"`
	}
	WithdrawalLog {
		Id        int64  `json:"id"`
		BizType   string `json:"biz_type"`
		UserId    int64  `json:"user_id"`
		Amount    int64  `json:"amount"`
		Content   string `json:"content"`
		Status    uint8  `json:"status"`
		Reason    string `json:"reason,omitempty"`
		Method    uint8  `json:"method"`
		Account   string `json:"account"`
		QrCodeUrl string `json:"qr_code_url"`
		CreatedAt int64  `json:"created_at"`
		UpdatedAt int64  `json:"updated_at"`
	}
	CancelWithdrawalRequest {
		WithdrawalId int64 `json:"withdrawal_id" validate:"required,gt=0"`
	}
	QueryWithdrawalLogListRequest {
		Page    int    `form:"page"`
		Size    int    `form:"size"`
		BizType string `form:"biz_type" validate:"omitempty,oneof=withdrawal commission_refund"`
	}
	QueryWithdrawalLogListResponse {
		List  []WithdrawalLog `json:"list"`
		Total int64           `json:"total"`
	}
	QueryCommissionReturnLogRequest {
		Page int `form:"page"`
		Size int `form:"size"`
	}
	CommissionReturnLog {
		Id        int64  `json:"id"`
		UserId    int64  `json:"user_id"`
		Amount    int64  `json:"amount"`
		EventType uint16 `json:"event_type"`
		Content   string `json:"content"`
		CreatedAt int64  `json:"created_at"`
		UpdatedAt int64  `json:"updated_at"`
	}
	QueryCommissionReturnLogResponse {
		List  []CommissionReturnLog `json:"list"`
		Total int64                 `json:"total"`
	}
	GetDeviceOnlineStatsResponse {
		WeeklyStats       []WeeklyStat      `json:"weekly_stats"`
		ConnectionRecords ConnectionRecords `json:"connection_records"`
	}
	WeeklyStat {
		Day     int     `json:"day"`
		DayName string  `json:"day_name"`
		Hours   float64 `json:"hours"`
	}
	ConnectionRecords {
		CurrentContinuousDays   int64 `json:"current_continuous_days"`
		HistoryContinuousDays   int64 `json:"history_continuous_days"`
		LongestSingleConnection int64 `json:"longest_single_connection"`
	}
	BindEmailWithVerificationRequest {
		Email string `json:"email" form:"email" validate:"required,email"`
		Code  string `json:"code" form:"code" validate:"required"`
	}
	BindEmailWithVerificationResponse {
		Success      bool   `json:"success"`
		Message      string `json:"message"`
		Token        string `json:"token,omitempty"`
		UserId       int64  `json:"user_id"`
		FamilyJoined bool   `json:"family_joined,omitempty"`
		FamilyId     int64  `json:"family_id,omitempty"`
		OwnerUserId  int64  `json:"owner_user_id,omitempty"`
	}
	BindInviteCodeRequest {
		InviteCode string `json:"invite_code" form:"invite_code" validate:"required"`
	}
	DeleteAccountRequest {
		Email string `json:"email" validate:"required,email"`
		Code  string `json:"code" validate:"required"`
	}
	DeleteAccountResponse {
		Success bool   `json:"success"`
		Message string `json:"message"`
		UserId  int64  `json:"user_id"`
		Code    int64  `json:"code"`
	}
	GetAgentDownloadsRequest  {}
	PlatformDownloads {
		IOS     int64 `json:"ios"`
		Android int64 `json:"android"`
		Windows int64 `json:"windows"`
		Mac     int64 `json:"mac"`
	}
	GetAgentDownloadsResponse {
		Total          int64             `json:"total"`
		Platforms      PlatformDownloads `json:"platforms"`
		ComparisonRate string            `json:"comparison_rate,omitempty"`
	}
	GetAgentRealtimeRequest  {}
	GetAgentRealtimeResponse {
		Total          int64  `json:"total"`
		Clicks         int64  `json:"clicks"`
		Views          int64  `json:"views"`
		Installs       int64  `json:"installs"`
		PaidCount      int64  `json:"paid_count"`
		GrowthRate     string `json:"growth_rate"`
		PaidGrowthRate string `json:"paid_growth_rate"`
	}
	GetInviteRecordsRequest {
		Page      int   `form:"page"`
		Size      int   `form:"size"`
		StartTime int64 `form:"start_time"`
		EndTime   int64 `form:"end_time"`
	}
	InviteRecord {
		Role      string `json:"role"`
		PeerHash  string `json:"peer_hash"`
		GiftDays  int64  `json:"gift_days"`
		OrderNo   string `json:"order_no"`
		CreatedAt int64  `json:"created_at"`
	}
	GetInviteRecordsResponse {
		Total int64          `json:"total"`
		List  []InviteRecord `json:"list"`
	}
	GetInviteSalesRequest {
		Page      int   `form:"page"`
		Size      int   `form:"size"`
		StartTime int64 `form:"start_time"`
		EndTime   int64 `form:"end_time"`
	}
	InvitedUserSale {
		Amount      float64 `json:"amount"`
		UpdatedAt   int64   `json:"updated_at"`
		UserHash    string  `json:"user_hash"`
		ProductName string  `json:"product_name"`
	}
	GetInviteSalesResponse {
		Total int64             `json:"total"`
		List  []InvitedUserSale `json:"list"`
	}
	GetSubscribeStatusRequest {
		Email string `form:"email" json:"email" validate:"omitempty,email"`
	}
	GetSubscribeStatusResponse {
		DeviceStatus bool `json:"device_status"`
		EmailStatus  bool `json:"email_status"`
	}
	GetUserInviteStatsRequest  {}
	GetUserInviteStatsResponse {
		FriendlyCount int64 `json:"friendly_count"`
		HistoryCount  int64 `json:"history_count"`
	}
	GetUserTrafficStatsRequest {
		UserSubscribeId string `form:"user_subscribe_id" validate:"required"`
		Days            int    `form:"days" validate:"required,oneof=7 30"`
	}
	DailyTrafficStats {
		Date     string `json:"date"`
		Upload   int64  `json:"upload"`
		Download int64  `json:"download"`
		Total    int64  `json:"total"`
	}
	GetUserTrafficStatsResponse {
		List          []DailyTrafficStats `json:"list"`
		TotalUpload   int64               `json:"total_upload"`
		TotalDownload int64               `json:"total_download"`
		TotalTraffic  int64               `json:"total_traffic"`
	}
)

@server (
	prefix:     v1/public/user
	group:      public/user
	middleware: AuthMiddleware,DeviceMiddleware
)
service ppanel {
	@doc "Query User Info"
	@handler QueryUserInfo
	get /info returns (User)

	@doc "Update User Notify"
	@handler UpdateUserNotify
	put /notify (UpdateUserNotifyRequest)

	@doc "Update User Password"
	@handler UpdateUserPassword
	put /password (UpdateUserPasswordRequest)

	@doc "Query User Subscribe"
	@handler QueryUserSubscribe
	get /subscribe returns (QueryUserSubscribeListResponse)

	@doc "Pre Unsubscribe"
	@handler PreUnsubscribe
	post /unsubscribe/pre (PreUnsubscribeRequest) returns (PreUnsubscribeResponse)

	@doc "Unsubscribe"
	@handler Unsubscribe
	post /unsubscribe (UnsubscribeRequest)

	@doc "Query User Balance Log"
	@handler QueryUserBalanceLog
	get /balance_log returns (QueryUserBalanceLogListResponse)

	@doc "Query User Affiliate Count"
	@handler QueryUserAffiliate
	get /affiliate/count returns (QueryUserAffiliateCountResponse)

	@doc "Query User Affiliate List"
	@handler QueryUserAffiliateList
	get /affiliate/list (QueryUserAffiliateListRequest) returns (QueryUserAffiliateListResponse)

	@doc "Bind Telegram"
	@handler BindTelegram
	get /bind_telegram returns (BindTelegramResponse)

	@doc "Unbind Telegram"
	@handler UnbindTelegram
	post /unbind_telegram

	@doc "Query User Commission Log"
	@handler QueryUserCommissionLog
	get /commission_log (QueryUserCommissionLogListRequest) returns (QueryUserCommissionLogListResponse)

	@doc "Bind OAuth"
	@handler BindOAuth
	post /bind_oauth (BindOAuthRequest) returns (BindOAuthResponse)

	@doc "Bind OAuth Callback"
	@handler BindOAuthCallback
	post /bind_oauth/callback (BindOAuthCallbackRequest)

	@doc "Get OAuth Methods"
	@handler GetOAuthMethods
	get /oauth_methods returns (GetOAuthMethodsResponse)

	@doc "Unbind OAuth"
	@handler UnbindOAuth
	post /unbind_oauth (UnbindOAuthRequest)

	@doc "Reset User Subscribe Token"
	@handler ResetUserSubscribeToken
	put /subscribe_token (ResetUserSubscribeTokenRequest)

	@doc "Get Login Log"
	@handler GetLoginLog
	get /login_log (GetLoginLogRequest) returns (GetLoginLogResponse)

	@doc "Get Subscribe Log"
	@handler GetSubscribeLog
	get /subscribe_log (GetSubscribeLogRequest) returns (GetSubscribeLogResponse)

	@doc "Verify Email"
	@handler VerifyEmail
	post /verify_email (VerifyEmailRequest)

	@doc "Update Bind Mobile"
	@handler UpdateBindMobile
	put /bind_mobile (UpdateBindMobileRequest)

	@doc "Update Bind Email"
	@handler UpdateBindEmail
	put /bind_email (UpdateBindEmailRequest)

	@doc "Get Device List"
	@handler GetDeviceList
	get /devices returns (GetDeviceListResponse)

	@doc "Unbind Device"
	@handler UnbindDevice
	put /unbind_device (UnbindDeviceRequest)

	@doc "Update User Subscribe Note"
	@handler UpdateUserSubscribeNote
	put /subscribe_note (UpdateUserSubscribeNoteRequest)

	@doc "Update User Rules"
	@handler UpdateUserRules
	put /rules (UpdateUserRulesRequest)

	@doc "Commission Withdraw"
	@handler CommissionWithdraw
	post /commission_withdraw (CommissionWithdrawRequest) returns (WithdrawalLog)

	@doc "Cancel pending withdrawal"
	@handler CancelWithdrawal
	post /withdrawal_cancel (CancelWithdrawalRequest) returns (WithdrawalLog)

	@doc "Query Withdrawal Log (biz_type=commission_refund deprecated, use /commission_return_log)"
	@handler QueryWithdrawalLog
	get /withdrawal_log (QueryWithdrawalLogListRequest) returns (QueryWithdrawalLogListResponse)

	@doc "Query Commission Return Log"
	@handler QueryCommissionReturnLog
	get /commission_return_log (QueryCommissionReturnLogRequest) returns (QueryCommissionReturnLogResponse)

	@doc "Device Online Statistics"
	@handler DeviceOnlineStatistics
	get /device_online_statistics returns (GetDeviceOnlineStatsResponse)

	@doc "Delete Current User Account"
	@handler DeleteCurrentUserAccount
	delete /current_user_account

	@doc "Bind Email With Verification"
	@handler BindEmailWithVerification
	post /bind_email_with_verification (BindEmailWithVerificationRequest) returns (BindEmailWithVerificationResponse)

	@doc "Bind Invite Code"
	@handler BindInviteCode
	post /bind_invite_code (BindInviteCodeRequest)

	@doc "Delete Account"
	@handler DeleteAccount
	post /delete_account (DeleteAccountRequest) returns (DeleteAccountResponse)

	@doc "Get Agent Downloads"
	@handler GetAgentDownloads
	get /agent_downloads (GetAgentDownloadsRequest) returns (GetAgentDownloadsResponse)

	@doc "Get Agent Realtime"
	@handler GetAgentRealtime
	get /agent_realtime (GetAgentRealtimeRequest) returns (GetAgentRealtimeResponse)

	@doc "Get Invite Records"
	@handler GetInviteRecords
	get /invite_records (GetInviteRecordsRequest) returns (GetInviteRecordsResponse)

	@doc "Get Invite Sales"
	@handler GetInviteSales
	get /invite_sales (GetInviteSalesRequest) returns (GetInviteSalesResponse)

	@doc "Get Subscribe Status"
	@handler GetSubscribeStatus
	post /subscribe_status (GetSubscribeStatusRequest) returns (GetSubscribeStatusResponse)

	@doc "Get User Invite Stats"
	@handler GetUserInviteStats
	get /invite_stats (GetUserInviteStatsRequest) returns (GetUserInviteStatsResponse)

	@doc "Get User Traffic Statistics"
	@handler GetUserTrafficStats
	get /traffic_stats (GetUserTrafficStatsRequest) returns (GetUserTrafficStatsResponse)
}

@server (
	prefix:     v1/public/user
	group:      public/user/ws
	middleware: AuthMiddleware
)
service ppanel {
	@doc "Webosocket Device Connect"
	@handler DeviceWsConnect
	get /device_ws_connect
}

