syntax = "v1"



// =================================================================
// Type: 授權與驗證 (Auth)
// =================================================================
type (
    // CredentialsPayload 傳統帳號密碼註冊的資料
    CredentialsPayload {
        Password        string `json:"password" validate:"required,min=8,max=128"`   // 密碼 (後端應使用 bcrypt 進行雜湊)
        PasswordConfirm string `json:"password_confirm" validate:"eqfield=Password"` // 確認密碼
        AccountType string `json:"account_type" validate:"required,oneof=email phone any"` // 帳號型別 email phone any
    }

    // PlatformPayload 第三方平台註冊的資料
    PlatformPayload {
        Provider string `json:"provider" validate:"required,oneof=google line apple"` // 平台名稱，目前支援 google line apple
        Token    string `json:"token" validate:"required"`                            // 平台提供的 Access Token 或 ID Token
    }

    // RegisterReq 註冊請求 (整合了兩種方式)
    LoginReq {
        AuthMethod  string                      `json:"auth_method" validate:"required,oneof=credentials platform"`// 驗證類型  credentials platform
        LoginID     string                      `json:"login_id" validate:"required,min=3,max=50"` // 信箱或手機號碼
        Credentials *CredentialsPayload         `json:"credentials,optional"`                      // AuthMethod 為 'credentials' 時使用
        Platform    *PlatformPayload            `json:"platform,optional"`                         // AuthMethod 為 'platform' 時使用
    }

    // LoginResp 登入/註冊成功後的響應
    LoginResp {
        UID          string `json:"uid"`
        AccessToken  string `json:"access_token"`
        RefreshToken string `json:"refresh_token"`
        TokenType    string `json:"token_type"` // 通常固定為 "Bearer"
    }
    // --- 密碼重設流程 ---

    // RequestPasswordResetReq 請求發送「忘記密碼」的驗證碼
    RequestPasswordResetReq {
        Identifier  string `json:"identifier" validate:"required,email|phone"` // 使用者帳號 (信箱或手機)
        AccountType string `json:"account_type" validate:"required,oneof=email phone"`
    }

   // VerifyCodeReq 驗證碼校驗 (通用)
    VerifyCodeReq {
        Identifier string `json:"identifier" validate:"required"`
        VerifyCode string `json:"verify_code" validate:"required,len=6"`
    }

   // ResetPasswordReq 使用已驗證的 Code 來重設密碼 只有用帳號密碼的才能發送重設密碼
    ResetPasswordReq {
        Identifier      string `json:"identifier" validate:"required"`
        VerifyCode      string `json:"verify_code" validate:"required"`               // 來自上一步驗證通過的 Code，作為一種「票證」
        Password        string `json:"password" validate:"required,min=8,max=128"`    // 新密碼
        PasswordConfirm string `json:"password_confirm" validate:"eqfield=Password"`  // 確認新密碼
    }

    // --- 4. 權杖刷新 ---
    // RefreshTokenReq 更新 AccessToken
    RefreshTokenReq {
        RefreshToken string `json:"refresh_token" validate:"required"`
    }

        // RefreshTokenResp 刷新權杖後的響應
    RefreshTokenResp {
        AccessToken  string `json:"access_token"`
        RefreshToken string `json:"refresh_token"` // 可選：某些策略下刷新後也會換發新的 Refresh Token
        TokenType    string `json:"token_type"`
    }
)

// =================================================================
// Type: 使用者資訊與管理 (User)
// =================================================================
type (
    // --- 1. 會員資訊 ---

    // UserInfoResp 用於獲取會員資訊的標準響應結構
    UserInfoResp {
        Platform          string `json:"platform"`              // 註冊平台
        UID               string `json:"uid"`                   // 用戶 UID
        AvatarURL         string `json:"avatar_url"`            // 頭像 URL
        FullName          string `json:"full_name"`             // 用戶全名
        Nickname          string `json:"nickname"`              // 暱稱
        GenderCode        string `json:"gender_code"`           // 性別代碼
        Birthdate         string `json:"birthdate"`             // 生日 (格式: 1993-04-17)
        PhoneNumber       string `json:"phone_number"`          // 電話
        IsPhoneVerified   bool   `json:"is_phone_verified"`     // 手機是否已驗證
        Email             string `json:"email"`                 // 信箱
        IsEmailVerified   bool   `json:"is_email_verified"`     // 信箱是否已驗證
        Address           string `json:"address"`               // 地址
        UserStatus        string `json:"user_status"`           // 用戶狀態
        PreferredLanguage string `json:"preferred_language"`    // 偏好語言
        Currency          string `json:"currency"`              // 偏好幣種
        National          string `json:"national"`              // 國家
        PostCode          string `json:"post_code"`             // 郵遞區號
        Carrier           string `json:"carrier"`               // 載具
        Role              string `json:"role"`                  // 角色
        UpdateAt          string `json:"update_at"`
        CreateAt          string `json:"create_at"`
        Authorization
    }

        // UpdateUserInfoReq 更新會員資訊的請求結構
    UpdateUserInfoReq {
        AvatarURL         *string `json:"avatar_url,optional"`         // 頭像 URL
        FullName          *string `json:"full_name,optional"`          // 用戶全名
        Nickname          *string `json:"nickname,optional"`           // 暱稱
        GenderCode        *string `json:"gender_code,optional" validate:"omitempty,oneof=secret male female"` // 性別
        Birthdate         *string `json:"birthdate,optional"`          // 生日 (格式: 1993-04-17)
        Address           *string `json:"address,optional"`            // 地址
        PreferredLanguage *string `json:"preferred_language,optional" validate:"omitempty,oneof=zh-tw en-us"` // 語言
        Currency          *string `json:"currency,optional" validate:"omitempty,oneof=TWD USD"` // 貨幣代號
        National          *string `json:"national,optional"`           // 國家
        PostCode          *string `json:"post_code,optional"`          // 郵遞區號
        Carrier           *string `json:"carrier,optional"`            // 載具
    }

    // --- 2. 修改密碼 (已登入狀態) ---
    // UpdatePasswordReq 修改密碼的請求
    UpdatePasswordReq {
        CurrentPassword    string `json:"current_password" validate:"required"`
        NewPassword        string `json:"new_password" validate:"required,min=8,max=128"`
        NewPasswordConfirm string `json:"new_password_confirm" validate:"eqfield=NewPassword"`
        Authorization
    }

    // --- 3. 通用驗證碼 (已登入狀態) ---
    // RequestVerificationCodeReq 請求發送驗證碼
    RequestVerificationCodeReq {
        // 驗證目的：'email_verification' 或 'phone_verification'
        Purpose string `json:"purpose" validate:"required,oneof=email_verification phone_verification"`
        Authorization
    }

        // SubmitVerificationCodeReq 提交驗證碼以完成驗證
    SubmitVerificationCodeReq {
        Purpose    string `json:"purpose" validate:"required,oneof=email_verification phone_verification"`
        VerifyCode string `json:"verify_code" validate:"required,len=6"`
        Authorization
    }
)

// =================================================================
// Service: 公開 API - 無需登入 (Auth Service)
// =================================================================
@server(
    group: auth
    prefix: /api/v1/auth
    schemes: https
    timeout: 10s
)
service gateway {
    @doc(
        summary: "註冊新帳號"
        description: "使用傳統帳號密碼或第三方平台進行註冊。成功後直接返回登入後的 Token 資訊。"
    )
    /*
        @respdoc-200 (LoginResp) // 註冊成功，並返回 Token
        @respdoc-400 (ErrorResp) "請求參數格式錯誤"
        @respdoc-409 (ErrorResp) "帳號已被註冊" // 409 Conflict: 資源衝突
        @respdoc-500 (ErrorResp) // 伺服器內部錯誤
    */
    @handler register
    post /register (LoginReq) returns (LoginResp)

    @doc(
        summary: "使用者登入"
        description: "使用傳統帳號密碼或第三方平台 Token 進行登入，以創建一個新的會話(Session)。"
    )
    /*
        @respdoc-200 (LoginResp) // 登入成功
        @respdoc-400 (ErrorResp) "請求參數格式錯誤"
        @respdoc-401 (ErrorResp) "帳號或密碼錯誤 / 無效的平台 Token" // 401 Unauthorized
        @respdoc-500 (ErrorResp) // 伺服器內部錯誤
    */
    @handler login
    post /sessions (LoginReq) returns (LoginResp)

    @doc(
        summary: "刷新 Access Token"
        description: "使用有效的 Refresh Token 來獲取一組新的 Access Token 和 Refresh Token。"
    )
    /*
        @respdoc-200 (RefreshTokenResp) // 刷新成功
        @respdoc-400 (ErrorResp) "請求參數格式錯誤"
        @respdoc-401 (ErrorResp) "無效或已過期的 Refresh Token" // 401 Unauthorized
        @respdoc-500 (ErrorResp) // 伺服器內部錯誤
    */
    @handler refreshToken
    post /sessions/refresh (RefreshTokenReq) returns (RefreshTokenResp)

    @doc(
        summary: "請求發送密碼重設驗證碼"
        description: "為指定的 email 或 phone 發送一個一次性的密碼重設驗證碼。"
    )
    /*
        @respdoc-200 (RespOK) // 請求成功 (為安全起見，即使帳號不存在也應返回成功)
        @respdoc-400 (ErrorResp) "請求參數格式錯誤"
        @respdoc-429 (ErrorResp) "請求過於頻繁" // 429 Too Many Requests
        @respdoc-500 (ErrorResp) // 伺服器內部錯誤
    */
    @handler requestPasswordReset
    post /password-resets/request (RequestPasswordResetReq) returns (RespOK)

    @doc(
        summary: "校驗密碼重設驗證碼"
        description: "在實際重設密碼前，先驗證使用者輸入的驗證碼是否正確。"
    )
    /*
        @respdoc-200 (RespOK) // 驗證碼正確
        @respdoc-400 (ErrorResp) "驗證碼無效或已過期"
        @respdoc-500 (ErrorResp) // 伺服器內部錯誤
    */
    @handler verifyPasswordResetCode
    post /password-resets/verify (VerifyCodeReq) returns (RespOK)

    @doc(
        summary: "執行密碼重設"
        description: "使用有效的驗證碼來設定新的密碼。"
    )
    /*
        @respdoc-200 (RespOK) // 密碼重設成功
        @respdoc-400 (ErrorResp) "驗證碼無效或請求參數錯誤"
        @respdoc-500 (ErrorResp) // 伺服器內部錯誤
    */
    @handler resetPassword
    put /password-resets (ResetPasswordReq) returns (RespOK)
}

// =================================================================
// Service: 授權 API - 需要登入 (User Service)
// =================================================================
@server(
    group: user
    prefix: /api/v1/user
    schemes: https
    timeout: 10s
    middleware: AuthMiddleware // 所有此 group 的路由都需要經過 JWT 驗證
)
service gateway {
    @doc(
        summary: "取得當前登入的會員資訊(自己)"
    )
    /*
        @respdoc-200 (UserInfoResp) // 成功獲取
        @respdoc-401 (ErrorResp) "未授權或 Token 無效"
        @respdoc-404 (ErrorResp) "找不到使用者"
        @respdoc-500 (ErrorResp) // 伺服器內部錯誤
    */
    @handler getUserInfo
    get /me (Authorization) returns (UserInfoResp)

    @doc(
        summary: "更新當前登入的會員資訊"
        description: "只更新傳入的欄位，未傳入的欄位將保持不變。"
    )
    /*
        @respdoc-200 (UserInfoResp) // 更新成功，並返回更新後的使用者資訊
        @respdoc-400 (ErrorResp) "請求參數格式錯誤"
        @respdoc-401 (ErrorResp) "未授權或 Token 無效"
        @respdoc-500 (ErrorResp) // 伺服器內部錯誤
    */
    @handler updateUserInfo
    put /me (UpdateUserInfoReq) returns (UserInfoResp)

    @doc(
        summary: "修改當前登入使用者的密碼"
        description: "必須提供當前密碼以進行驗證。"
    )
    /*
        @respdoc-200 (RespOK) // 密碼修改成功
        @respdoc-400 (ErrorResp) "請求參數格式錯誤或新舊密碼不符"
        @respdoc-401 (ErrorResp) "未授權或 Token 無效"
        @respdoc-403 (ErrorResp) "當前密碼不正確" // 403 Forbidden
        @respdoc-500 (ErrorResp) // 伺服器內部錯誤
    */
    @handler updatePassword
    put /me/password (UpdatePasswordReq) returns (RespOK)

    @doc(
        summary: "請求發送驗證碼 (用於驗證信箱/手機)"
        description: "根據傳入的 `purpose` 發送對應的驗證碼。"
    )
    /*
        @respdoc-200 (RespOK) // 請求已受理
        @respdoc-400 (ErrorResp) "請求參數格式錯誤"
        @respdoc-401 (ErrorResp) "未授權或 Token 無效"
        @respdoc-429 (ErrorResp) "請求過於頻繁" // 429 Too Many Requests
        @respdoc-500 (ErrorResp) // 伺服器內部錯誤
    */
    @handler requestVerificationCode
    post /me/verifications (RequestVerificationCodeReq) returns (RespOK)

    @doc(
        summary: "提交驗證碼以完成驗證"
        description: "提交收到的驗證碼，以完成特定目的的驗證，例如綁定手機或 Email。"
    )
    /*
        @respdoc-200 (RespOK) // 驗證成功
        @respdoc-400 (ErrorResp) "驗證碼無效或已過期"
        @respdoc-401 (ErrorResp) "未授權或 Token 無效"
        @respdoc-500 (ErrorResp) // 伺服器內部錯誤
    */
    @handler submitVerificationCode
    put /me/verifications (SubmitVerificationCodeReq) returns (RespOK)
}