package userManagement

import (
	"context"
	"fmt"
)

// LoginRequest 登录请求
type LoginRequest struct {
	Username    string `json:"username"`
	Password    string `json:"password"`
	DeviceID    string `json:"device_id,omitempty"`
	DeviceName  string `json:"device_name,omitempty"`
	RememberMe  bool   `json:"remember_me"`
}

// LoginResponse 登录响应
type LoginResponse struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token,omitempty"`
	ExpiresIn    int64  `json:"expires_in"`
	TokenType    string `json:"token_type"`
	User         *User  `json:"user,omitempty"`
}

// RegisterRequest 注册请求
type RegisterRequest struct {
	Username string `json:"username"`
	Email    string `json:"email"`
	Password string `json:"password"`
	Phone    string `json:"phone,omitempty"`
	Nickname string `json:"nickname,omitempty"`
}

// RefreshTokenRequest 刷新令牌请求
type RefreshTokenRequest struct {
	RefreshToken string `json:"refresh_token"`
}

// CapabilitiesResponse 能力响应
type CapabilitiesResponse struct {
	LoginMethods       []string `json:"login_methods"`
	SocialProviders    []string `json:"social_providers,omitempty"`
	CaptchaRequired    bool     `json:"captcha_required"`
	SocialBindRequired bool     `json:"social_bind_required,omitempty"`
}

// TwoFactorVerifyRequest 两因素验证请求
type TwoFactorVerifyRequest struct {
	Code      string `json:"code"`
	DeviceID  string `json:"device_id,omitempty"`
	TrustDevice bool  `json:"trust_device,omitempty"`
}

// PasswordResetRequest 密码重置请求
type PasswordResetRequest struct {
	Token       string `json:"token"`
	NewPassword string `json:"new_password"`
}

// Login 执行登录
func (c *Client) Login(ctx context.Context, req *LoginRequest) (*LoginResponse, error) {
	resp, err := c.doRequest(ctx, "POST", "/api/v1/auth/login", req)
	if err != nil {
		return nil, err
	}

	var result LoginResponse
	if err := c.parseResponse(resp, &result); err != nil {
		return nil, err
	}

	// 自动设置 access token
	if result.AccessToken != "" {
		c.SetAccessToken(result.AccessToken)
	}

	return &result, nil
}

// Register 注册用户
func (c *Client) Register(ctx context.Context, req *RegisterRequest) (*User, error) {
	resp, err := c.doRequest(ctx, "POST", "/api/v1/auth/register", req)
	if err != nil {
		return nil, err
	}

	var result User
	if err := c.parseResponse(resp, &result); err != nil {
		return nil, err
	}

	return &result, nil
}

// GetCapabilities 获取登录能力
func (c *Client) GetCapabilities(ctx context.Context) (*CapabilitiesResponse, error) {
	resp, err := c.doRequest(ctx, "GET", "/api/v1/auth/capabilities", nil)
	if err != nil {
		return nil, err
	}

	var result CapabilitiesResponse
	if err := c.parseResponse(resp, &result); err != nil {
		return nil, err
	}

	return &result, nil
}

// RefreshToken 刷新令牌
func (c *Client) RefreshToken(ctx context.Context, req *RefreshTokenRequest) (*LoginResponse, error) {
	resp, err := c.doRequest(ctx, "POST", "/api/v1/auth/refresh", req)
	if err != nil {
		return nil, err
	}

	var result LoginResponse
	if err := c.parseResponse(resp, &result); err != nil {
		return nil, err
	}

	if result.AccessToken != "" {
		c.SetAccessToken(result.AccessToken)
	}

	return &result, nil
}

// VerifyTwoFactor 验证两因素验证码
func (c *Client) VerifyTwoFactor(ctx context.Context, req *TwoFactorVerifyRequest) error {
	resp, err := c.doRequest(ctx, "POST", "/api/v1/auth/2fa/verify", req)
	if err != nil {
		return err
	}

	return c.parseResponse(resp, nil)
}

// Logout 登出
func (c *Client) Logout(ctx context.Context) error {
	resp, err := c.doRequest(ctx, "POST", "/api/v1/auth/logout", nil)
	if err != nil {
		return err
	}

	c.accessToken = ""
	return c.parseResponse(resp, nil)
}

// RequestPasswordReset 请求密码重置
func (c *Client) RequestPasswordReset(ctx context.Context, email string) error {
	resp, err := c.doRequest(ctx, "POST", "/api/v1/auth/password/reset", map[string]string{"email": email})
	if err != nil {
		return err
	}

	return c.parseResponse(resp, nil)
}

// ResetPassword 重置密码
func (c *Client) ResetPassword(ctx context.Context, req *PasswordResetRequest) error {
	resp, err := c.doRequest(ctx, "POST", "/api/v1/auth/password/reset/confirm", req)
	if err != nil {
		return err
	}

	return c.parseResponse(resp, nil)
}

// SendVerifyCode 发送验证码
func (c *Client) SendVerifyCode(ctx context.Context, phone string) error {
	resp, err := c.doRequest(ctx, "POST", "/api/v1/auth/phone/send-code", map[string]string{"phone": phone})
	if err != nil {
		return err
	}

	return c.parseResponse(resp, nil)
}

// LoginWithPhone 手机号登录
func (c *Client) LoginWithPhone(ctx context.Context, phone, code string) (*LoginResponse, error) {
	req := map[string]string{
		"phone": phone,
		"code":  code,
	}
	resp, err := c.doRequest(ctx, "POST", "/api/v1/auth/login/phone", req)
	if err != nil {
		return nil, err
	}

	var result LoginResponse
	if err := c.parseResponse(resp, &result); err != nil {
		return nil, err
	}

	if result.AccessToken != "" {
		c.SetAccessToken(result.AccessToken)
	}

	return &result, nil
}

// OAuthURL 获取 OAuth 授权 URL
func (c *Client) OAuthURL(provider string, redirectURI, state string) (string, error) {
	params := map[string]string{
		"provider":      provider,
		"redirect_uri":  redirectURI,
	}
	if state != "" {
		params["state"] = state
	}

	query := ""
	for k, v := range params {
		if query != "" {
			query += "&"
		}
		query += k + "=" + v
	}

	return fmt.Sprintf("%s/api/v1/auth/oauth/authorize?%s", c.baseURL, query), nil
}

// HandleOAuthCallback 处理 OAuth 回调
func (c *Client) HandleOAuthCallback(ctx context.Context, provider, code string) (*LoginResponse, error) {
	req := map[string]string{
		"provider": provider,
		"code":     code,
	}
	resp, err := c.doRequest(ctx, "POST", "/api/v1/auth/oauth/callback", req)
	if err != nil {
		return nil, err
	}

	var result LoginResponse
	if err := c.parseResponse(resp, &result); err != nil {
		return nil, err
	}

	if result.AccessToken != "" {
		c.SetAccessToken(result.AccessToken)
	}

	return &result, nil
}
