syntax = "v1"

type (
	MemberMeData {
		TenantID              string `json:"tenant_id"`
		UID                   string `json:"uid"`
		ZitadelEmail          string `json:"zitadel_email,omitempty"`
		DisplayName           string `json:"display_name,omitempty"`
		Avatar                string `json:"avatar,omitempty"`
		Phone                 string `json:"phone,omitempty"`
		Language              string `json:"language,omitempty"`
		Currency              string `json:"currency,omitempty"`
		Status                string `json:"status"`
		Origin                string `json:"origin"`
		BusinessEmail         string `json:"business_email,omitempty"`
		BusinessEmailVerified bool   `json:"business_email_verified"`
		BusinessPhone         string `json:"business_phone,omitempty"`
		BusinessPhoneVerified bool   `json:"business_phone_verified"`
		TOTPEnrolled          bool   `json:"totp_enrolled"`
		CreateAt              int64  `json:"create_at"`
		UpdateAt              int64  `json:"update_at"`
	}

	UpdateMemberMeReq {
		DisplayName string `json:"display_name,optional"` // 顯示名稱（可選）
		Avatar      string `json:"avatar,optional"`       // 頭像 URL（可選）
		Language    string `json:"language,optional"`     // 語系代碼，如 zh-TW / en（可選）
		Currency    string `json:"currency,optional"`     // 幣別代碼，如 TWD / USD（可選）
		Phone       string `json:"phone,optional"`        // 聯絡電話 E.164 格式（可選）
	}

	ChangePasswordReq {
		CurrentPassword string `json:"current_password" validate:"required,min=8,max=128"` // 目前密碼
		NewPassword     string `json:"new_password" validate:"required,min=8,max=128"`     // 新密碼
		StepUpToken     string `json:"step_up_token,optional"`                           // TOTP 已啟用：與 totp_code 二擇一
		TOTPCode        string `json:"totp_code,optional" validate:"omitempty,min=6,max=32"` // TOTP 已啟用：與 step_up_token 二擇一
	}

	ChangePasswordData {
		OK bool `json:"ok"`
	}

	VerificationStartReq {
		Target string `json:"target"` // 驗證目標：email 地址或 E.164 手機號（依端點而定）
	}

	VerificationStartData {
		ChallengeID string `json:"challenge_id"`
		ExpiresIn   int    `json:"expires_in"`
	}

	VerificationConfirmReq {
		ChallengeID string `json:"challenge_id"` // 驗證流程的 OTP challenge ID（由 /start 端點回傳）
		Code        string `json:"code"`         // 6 位數 OTP 驗證碼
	}

	TOTPStatusData {
		Enrolled             bool  `json:"enrolled"`
		EnrolledAt           int64 `json:"enrolled_at,omitempty"`
		BackupCodesRemaining int   `json:"backup_codes_remaining"`
		Digits               int   `json:"digits,omitempty"`
		PeriodSeconds        int   `json:"period_seconds,omitempty"`
	}

	TOTPEnrollStartData {
		OtpauthURL  string `json:"otpauth_url"`
		Issuer      string `json:"issuer"`
		Account     string `json:"account"`
		Digits      int    `json:"digits"`
		PeriodSec   int    `json:"period_seconds"`
		ExpiresIn   int    `json:"expires_in"`
	}

	TOTPEnrollConfirmReq {
		Code string `json:"code"` // Google Authenticator 顯示的 6 位數 TOTP 碼
	}

	TOTPEnrollConfirmData {
		BackupCodes []string `json:"backup_codes"`
	}

	TOTPVerifyReq {
		Code    string `json:"code" validate:"required,min=6,max=32"` // TOTP 6 碼或備援碼
		Purpose string `json:"purpose,optional"`                      // 變更密碼請傳 change_password
	}

	TOTPVerifyData {
		StepUpToken string `json:"step_up_token"`
		ExpiresIn   int    `json:"expires_in"`
	}

	TOTPBackupCodesData {
		BackupCodes []string `json:"backup_codes"`
	}

	// 文件用：成功回應 envelope（HTTP 200, code=102000, message=SUCCESS）
	MemberMeOKStatus {
		Code    int64        `json:"code"`
		Message string       `json:"message"`
		Data    MemberMeData `json:"data"`
	}

	VerificationStartOKStatus {
		Code    int64                 `json:"code"`
		Message string                `json:"message"`
		Data    VerificationStartData `json:"data"`
	}

	TOTPStatusOKStatus {
		Code    int64          `json:"code"`
		Message string         `json:"message"`
		Data    TOTPStatusData `json:"data"`
	}

	TOTPEnrollStartOKStatus {
		Code    int64               `json:"code"`
		Message string              `json:"message"`
		Data    TOTPEnrollStartData `json:"data"`
	}

	TOTPEnrollConfirmOKStatus {
		Code    int64                 `json:"code"`
		Message string                `json:"message"`
		Data    TOTPEnrollConfirmData `json:"data"`
	}

	TOTPBackupCodesOKStatus {
		Code    int64               `json:"code"`
		Message string              `json:"message"`
		Data    TOTPBackupCodesData `json:"data"`
	}
)

@server(
	group:      member
	prefix:     /api/v1/members
	middleware: AuthJWT
	tags:       "Member - 會員"
	summary:    "Profile / 業務 Email 與 Phone 驗證 / TOTP MFA（需 Bearer）"
)
service gateway {
	@doc "取得當前會員 profile（Bearer JWT；本機 dev 可 fallback X-Tenant-ID + X-UID）"
	/*
		@respdoc-200 (MemberMeOKStatus) // 成功（code=102000）
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-404 (
			29301000: (APIErrorStatus) member 不存在
		) // 資源不存在
		@respdoc-500 (
			29201000: (APIErrorStatus) 資料庫錯誤
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler getMemberMe
	get /me returns (MemberMeData)

	@doc "更新當前會員 profile"
	/*
		@respdoc-200 (MemberMeOKStatus) // 成功（code=102000）
		@respdoc-400 (
			10101000: (APIErrorStatus) 參數格式錯誤
		) // 參數錯誤
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-404 (
			29301000: (APIErrorStatus) member 不存在
		) // 資源不存在
		@respdoc-500 (
			29201000: (APIErrorStatus) 資料庫錯誤
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler updateMemberMe
	patch /me (UpdateMemberMeReq) returns (MemberMeData)

	@doc "變更登入密碼（僅 platform_native；須已綁定 TOTP，並帶 step_up_token 或 totp_code）"
	/*
		@respdoc-200 (EmptyOKStatus) // 成功（code=102000）
		@respdoc-400 (
			10101000: (APIErrorStatus) 參數格式錯誤
			10104000: (APIErrorStatus) 缺少必填欄位
		) // 參數錯誤
		@respdoc-401 (
			29501000: (APIErrorStatus) 目前密碼錯誤
		) // 未授權
		@respdoc-403 (
			29505000: (APIErrorStatus) 外部身份帳號不可變更密碼 / TOTP 未驗證（Member scope）
		) // 禁止存取
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
		@respdoc-502 (
			29802000: (APIErrorStatus) ZITADEL 第三方錯誤
		) // 第三方服務錯誤
	*/
	@handler changePassword
	post /me/password (ChangePasswordReq) returns (ChangePasswordData)

	@doc "開始業務 email 驗證"
	/*
		@respdoc-200 (VerificationStartOKStatus) // 成功（code=102000）
		@respdoc-400 (
			10101000: (APIErrorStatus) 參數格式錯誤
			29104000: (APIErrorStatus) target 必填（Member scope）
		) // 參數錯誤
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-429 (
			29604000: (APIErrorStatus) OTP 重送冷卻
			29310000: (APIErrorStatus) 每日驗證上限
		) // 請求過於頻繁
		@respdoc-500 (
			29201000: (APIErrorStatus) 資料庫錯誤
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler startEmailVerification
	post /me/verifications/email/start (VerificationStartReq) returns (VerificationStartData)

	@doc "確認業務 email 驗證"
	/*
		@respdoc-200 (EmptyOKStatus) // 成功（code=102000）
		@respdoc-400 (
			10101000: (APIErrorStatus) 參數格式錯誤
			29104000: (APIErrorStatus) challenge_id / code 必填（Member scope）
		) // 參數錯誤
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-403 (
			29505000: (APIErrorStatus) OTP 無效 / challenge tenant 或 purpose 不符
		) // 禁止存取
		@respdoc-404 (
			29301000: (APIErrorStatus) OTP challenge / member 不存在
		) // 資源不存在
		@respdoc-409 (
			29309000: (APIErrorStatus) OTP challenge 鎖定
		) // 資源狀態衝突
		@respdoc-500 (
			29201000: (APIErrorStatus) 資料庫錯誤
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler confirmEmailVerification
	post /me/verifications/email/confirm (VerificationConfirmReq)

	@doc "開始業務 phone 驗證"
	/*
		@respdoc-200 (VerificationStartOKStatus) // 成功（code=102000）
		@respdoc-400 (
			10101000: (APIErrorStatus) 參數格式錯誤
			29104000: (APIErrorStatus) target 必填（Member scope）
		) // 參數錯誤
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-429 (
			29604000: (APIErrorStatus) OTP 重送冷卻
			29310000: (APIErrorStatus) 每日驗證上限
		) // 請求過於頻繁
		@respdoc-500 (
			29201000: (APIErrorStatus) 資料庫錯誤
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler startPhoneVerification
	post /me/verifications/phone/start (VerificationStartReq) returns (VerificationStartData)

	@doc "確認業務 phone 驗證"
	/*
		@respdoc-200 (EmptyOKStatus) // 成功（code=102000）
		@respdoc-400 (
			10101000: (APIErrorStatus) 參數格式錯誤
			29104000: (APIErrorStatus) challenge_id / code 必填（Member scope）
		) // 參數錯誤
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-403 (
			29505000: (APIErrorStatus) OTP 無效 / challenge tenant 或 purpose 不符
		) // 禁止存取
		@respdoc-404 (
			29301000: (APIErrorStatus) OTP challenge / member 不存在
		) // 資源不存在
		@respdoc-409 (
			29309000: (APIErrorStatus) OTP challenge 鎖定
		) // 資源狀態衝突
		@respdoc-500 (
			29201000: (APIErrorStatus) 資料庫錯誤
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler confirmPhoneVerification
	post /me/verifications/phone/confirm (VerificationConfirmReq)

	@doc "TOTP 狀態"
	/*
		@respdoc-200 (TOTPStatusOKStatus) // 成功（code=102000）
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-500 (
			29201000: (APIErrorStatus) 資料庫錯誤
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler getTOTPStatus
	get /me/totp returns (TOTPStatusData)

	@doc "開始 TOTP 綁定"
	/*
		@respdoc-200 (TOTPEnrollStartOKStatus) // 成功（code=102000）
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-409 (
			29303000: (APIErrorStatus) TOTP 已綁定
		) // 資源衝突
		@respdoc-500 (
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler startTOTPEnroll
	post /me/totp/enroll-start returns (TOTPEnrollStartData)

	@doc "確認 TOTP 綁定"
	/*
		@respdoc-200 (TOTPEnrollConfirmOKStatus) // 成功（code=102000）
		@respdoc-400 (
			10101000: (APIErrorStatus) 參數格式錯誤
			29104000: (APIErrorStatus) code 必填（Member scope）
		) // 參數錯誤
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-403 (
			29505000: (APIErrorStatus) TOTP 碼無效
		) // 禁止存取
		@respdoc-404 (
			29301000: (APIErrorStatus) enroll session / member 不存在
		) // 資源不存在
		@respdoc-409 (
			29303000: (APIErrorStatus) TOTP 已綁定
		) // 資源衝突
		@respdoc-500 (
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler confirmTOTPEnroll
	post /me/totp/enroll-confirm (TOTPEnrollConfirmReq) returns (TOTPEnrollConfirmData)

	@doc "驗證 TOTP（step-up 測試）"
	/*
		@respdoc-200 (EmptyOKStatus) // 成功（code=102000）
		@respdoc-400 (
			10101000: (APIErrorStatus) 參數格式錯誤
			29104000: (APIErrorStatus) code 必填（Member scope）
		) // 參數錯誤
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-403 (
			29505000: (APIErrorStatus) TOTP 碼無效或已使用
		) // 禁止存取
		@respdoc-409 (
			29309000: (APIErrorStatus) TOTP 未綁定
		) // 資源狀態衝突
		@respdoc-500 (
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler verifyTOTP
	post /me/totp/verify (TOTPVerifyReq) returns (TOTPVerifyData)

	@doc "重產 TOTP 備援碼"
	/*
		@respdoc-200 (TOTPBackupCodesOKStatus) // 成功（code=102000）
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-404 (
			29301000: (APIErrorStatus) member 不存在
		) // 資源不存在
		@respdoc-409 (
			29309000: (APIErrorStatus) TOTP 未綁定
		) // 資源狀態衝突
		@respdoc-500 (
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler regenerateTOTPBackupCodes
	post /me/totp/backup-codes returns (TOTPBackupCodesData)

	@doc "解除 TOTP 綁定"
	/*
		@respdoc-200 (EmptyOKStatus) // 成功（code=102000）
		@respdoc-401 (
			29501000: (APIErrorStatus) 缺少 Bearer 或 X-Tenant-ID/X-UID
		) // 未授權
		@respdoc-404 (
			29301000: (APIErrorStatus) member 不存在
		) // 資源不存在
		@respdoc-500 (
			29201000: (APIErrorStatus) 資料庫錯誤
			29601000: (APIErrorStatus) 系統內部錯誤
		) // 內部錯誤
		@respdoc-501 (
			29605000: (APIErrorStatus) 功能未配置
		) // 未實作
	*/
	@handler disableTOTP
	delete /me/totp
}
