package handlers

import (
	"Yimaru-Backend/internal/domain"
	"Yimaru-Backend/internal/services/authentication"
	jwtutil "Yimaru-Backend/internal/web_server/jwt"
	"Yimaru-Backend/internal/web_server/response"
	"errors"
	"fmt"
	"time"

	"github.com/gofiber/fiber/v2"
	"github.com/google/uuid"
	"go.uber.org/zap"
)

// loginUserReq represents the request body for the Loginuser endpoint.
type loginUserReq struct {
	Email       string `json:"email"`
	PhoneNumber string `json:"phone_number"`
	Password    string `json:"password"`
	OtpCode     string `json:"otp_code"`
	// UserName string `json:"user_name" validate:"required" example:"johndoe"`
	// Password string `json:"password" validate:"required" example:"password123"`
}

// loginUserRes represents the response body for the Loginuser endpoint.
type loginUserRes struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	Role         string `json:"role"`
	UserID       int64  `json:"user_id"`
}

// GoogleAndroidLogin godoc
// @Summary Login via Google Android ID Token
// @Tags auth
// @Param idToken body string true "Google ID Token from Android"
// @Router /api/v1/auth/google/android [post]
func (h *Handler) GoogleAndroidLogin(c *fiber.Ctx) error {
	var req struct {
		IDToken string `json:"id_token" validate:"required" example:"<google-id-token>"`
	}

	if err := c.BodyParser(&req); err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
			Message: "Invalid request body",
			Error:   err.Error(),
		})
	}

	loginRes, err := h.authSvc.LoginWithGoogleAndroid(c.Context(), req.IDToken, h.Cfg.GoogleOAuthClientID)
	if err != nil {
		return c.Status(fiber.StatusUnauthorized).JSON(domain.ErrorResponse{
			Message: "Google login failed",
			Error:   err.Error(),
		})
	}

	// Issue backend JWT
	accessToken, err := jwtutil.CreateJwt(
		loginRes.UserId,
		loginRes.Role,
		h.jwtConfig.JwtAccessKey,
		h.jwtConfig.JwtAccessExpiry,
	)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
			Message: "Token generation failed",
			Error:   err.Error(),
		})
	}

	return c.Status(fiber.StatusOK).JSON(domain.Response{
		Message: "Login successful",
		Data: loginUserRes{
			AccessToken:  accessToken,
			RefreshToken: loginRes.RfToken,
			Role:         string(loginRes.Role),
			UserID:       loginRes.UserId,
		},
	})
}

// GoogleLogin godoc
// @Summary Google login redirect
// @Tags auth
// @Router /api/v1/auth/google/login [get]
func (h *Handler) GoogleLogin(c *fiber.Ctx) error {
	state := uuid.NewString()
	url := h.authSvc.GenerateGoogleLoginURL(state)
	if url == "" {
		return c.Status(fiber.StatusServiceUnavailable).JSON(domain.ErrorResponse{
			Message: "Google OAuth is not configured",
			Error:   "Google OAuth client credentials are not set",
		})
	}
	return c.Redirect(url)
}

// GoogleCallback godoc
// @Summary Google login callback
// @Tags auth
// @Router /api/v1/auth/google/callback [get]
func (h *Handler) GoogleCallback(c *fiber.Ctx) error {

	code := c.Query("code")

	token, err := h.authSvc.ExchangeGoogleCode(c.Context(), code)
	if err != nil {
		return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
			Message: "Google authentication failed",
			Error:   err.Error(),
		})
	}

	gUser, err := h.authSvc.FetchGoogleUser(c.Context(), token)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
			Message: "Failed to fetch Google user",
			Error:   err.Error(),
		})
	}

	loginRes, err := h.authSvc.LoginWithGoogle(c.Context(), *gUser)
	if err != nil {
		return c.Status(fiber.StatusUnauthorized).JSON(domain.ErrorResponse{
			Message: "Login failed",
			Error:   err.Error(),
		})
	}

	accessToken, err := jwtutil.CreateJwt(
		loginRes.UserId,
		loginRes.Role,
		h.jwtConfig.JwtAccessKey,
		h.jwtConfig.JwtAccessExpiry,
	)
	if err != nil {
		return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
			Message: "Token generation failed",
			Error:   err.Error(),
		})
	}

	return c.Status(fiber.StatusOK).JSON(domain.Response{
		Message: "Login successful",
		Data: loginUserRes{
			AccessToken:  accessToken,
			RefreshToken: loginRes.RfToken,
			Role:         string(loginRes.Role),
			UserID:       loginRes.UserId,
		},
	})
}

// Loginuser godoc
// @Summary Login user
// @Description Login user
// @Tags auth
// @Accept json
// @Produce json
// @Param login body domain.LoginRequest true "Login user"
// @Success 200 {object} loginUserRes
// @Failure 400 {object} response.APIResponse
// @Failure 401 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /api/v1/{tenant_slug}/user-login [post]
func (h *Handler) LoginUser(c *fiber.Ctx) error {
	var req domain.LoginRequest
	if err := c.BodyParser(&req); err != nil {
		h.mongoLoggerSvc.Info("Failed to parse LoginUser request",
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
			Message: "Failed to login",
			Error:   "Invalid request body: " + err.Error(),
		})
	}

	if valErrs, ok := h.validator.Validate(c, req); !ok {
		var errMsg string
		for field, msg := range valErrs {
			errMsg += fmt.Sprintf("%s: %s; ", field, msg)
		}
		return c.Status(fiber.StatusBadRequest).JSON(domain.ErrorResponse{
			Message: "Failed to login",
			Error:   errMsg,
		})
	}

	successRes, err := h.authSvc.Login(c.Context(), req)
	if err != nil {
		switch {
		case errors.Is(err, authentication.ErrInvalidPassword), errors.Is(err, authentication.ErrUserNotFound):
			h.mongoLoggerSvc.Info("Login attempt failed: Invalid credentials",
				zap.Int("status_code", fiber.StatusUnauthorized),
				zap.String("email", req.Email),
				zap.String("phone_number", req.PhoneNumber),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return c.Status(fiber.StatusUnauthorized).JSON(domain.ErrorResponse{
				Message: "Failed to login",
				Error:   fmt.Sprintf("Invalid credentials: %v", err),
			})
		case errors.Is(err, authentication.ErrUserSuspended):
			h.mongoLoggerSvc.Info("Login attempt failed: User login has been locked",
				zap.Int("status_code", fiber.StatusUnauthorized),
				zap.String("email", req.Email),
				zap.String("phone_number", req.PhoneNumber),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return c.Status(fiber.StatusUnauthorized).JSON(domain.ErrorResponse{
				Message: "Failed to login",
				Error:   fmt.Sprintf("User login has been locked: %v", err),
			})
		default:
			h.mongoLoggerSvc.Error("Login failed",
				zap.Int("status_code", fiber.StatusInternalServerError),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
				Message: "Failed to login",
				Error:   err.Error(),
			})
		}
	}

	// if successRes.Role != domain.RoleStudent {
	// 	h.mongoLoggerSvc.Info("Login attempt: user login of other role",
	// 		zap.Int("status_code", fiber.StatusForbidden),
	// 		zap.String("role", string(successRes.Role)),
	// 		zap.String("email", req.Email),
	// 		zap.String("phone_number", req.PhoneNumber),
	// 		zap.Time("timestamp", time.Now()),
	// 	)
	// 	return c.Status(fiber.StatusForbidden).JSON(domain.ErrorResponse{
	// 		Message: "Failed to login",
	// 		Error:   "Only users are allowed to login",
	// 	})
	// }

	accessToken, err := jwtutil.CreateJwt(
		successRes.UserId,
		successRes.Role,
		h.jwtConfig.JwtAccessKey,
		h.jwtConfig.JwtAccessExpiry,
	)
	if err != nil {
		h.mongoLoggerSvc.Error("Failed to create access token",
			zap.Int("status_code", fiber.StatusInternalServerError),
			zap.Int64("user_id", successRes.UserId),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return c.Status(fiber.StatusInternalServerError).JSON(domain.ErrorResponse{
			Message: "Failed to login",
			Error:   "Failed to generate access token",
		})
	}

	res := loginUserRes{
		AccessToken:  accessToken,
		RefreshToken: successRes.RfToken,
		Role:         string(successRes.Role),
		UserID:       successRes.UserId,
	}

	h.mongoLoggerSvc.Info("Login successful",
		zap.Int("status_code", fiber.StatusOK),
		zap.Int64("user_id", successRes.UserId),
		zap.String("role", string(successRes.Role)),
		zap.Time("timestamp", time.Now()),
	)

	return c.Status(fiber.StatusOK).JSON(domain.Response{
		Message: "Login successful",
		Data:    res,
	})
}

// loginAdminReq represents the request body for the LoginAdmin endpoint.
type loginAdminReq struct {
	Email    string `json:"email" validate:"required" example:"adminuser"`
	Password string `json:"password" validate:"required" example:"password123"`
}

// loginAdminRes represents the response body for the LoginAdmin endpoint.
type LoginAdminRes struct {
	AccessToken  string `json:"access_token"`
	RefreshToken string `json:"refresh_token"`
	Role         string `json:"role"`
}

// LoginAdmin godoc
// @Summary Login user
// @Description Login user
// @Tags auth
// @Accept json
// @Produce json
// @Param login body domain.LoginRequest true "Login admin"
// @Success 200 {object} LoginAdminRes
// @Failure 400 {object} response.APIResponse
// @Failure 401 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /api/v1/{tenant_slug}/admin-login [post]
func (h *Handler) LoginAdmin(c *fiber.Ctx) error {
	var req domain.LoginRequest
	if err := c.BodyParser(&req); err != nil {
		h.mongoLoggerSvc.Info("Failed to parse LoginAdmin request",
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusBadRequest, "Invalid request body"+err.Error())
	}

	if valErrs, ok := h.validator.Validate(c, req); !ok {
		var errMsg string
		for field, msg := range valErrs {
			errMsg += fmt.Sprintf("%s: %s; ", field, msg)
		}
		return fiber.NewError(fiber.StatusBadRequest, errMsg)
	}

	successRes, err := h.authSvc.Login(c.Context(), domain.LoginRequest(req))
	if err != nil {
		switch {
		case errors.Is(err, authentication.ErrInvalidPassword), errors.Is(err, authentication.ErrUserNotFound):
			h.mongoLoggerSvc.Info("Login attempt failed: Invalid credentials",
				zap.Int("status_code", fiber.StatusBadRequest),
				zap.String("email", req.Email),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusBadRequest, "Invalid credentials")
		case errors.Is(err, authentication.ErrUserSuspended):
			h.mongoLoggerSvc.Info("Login attempt failed: User login has been locked",
				zap.Int("status_code", fiber.StatusForbidden),
				zap.String("email", req.Email),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusForbidden, "User login has been locked")
		default:
			h.mongoLoggerSvc.Error("Login failed",
				zap.Int("status_code", fiber.StatusInternalServerError),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusInternalServerError, "Internal server error")
		}
	}

	if successRes.Role == domain.RoleStudent || successRes.Role == domain.RoleInstructor {
		h.mongoLoggerSvc.Warn("Login attempt: admin login of user",
			zap.Int("status_code", fiber.StatusForbidden),
			zap.String("role", string(successRes.Role)),
			zap.String("email", req.Email),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusForbidden, "Only admin roles are allowed")
	}

	accessToken, err := jwtutil.CreateJwt(successRes.UserId, successRes.Role, h.jwtConfig.JwtAccessKey, h.jwtConfig.JwtAccessExpiry)
	if err != nil {
		h.mongoLoggerSvc.Error("Failed to create access token",
			zap.Int("status_code", fiber.StatusInternalServerError),
			zap.Int64("user_id", successRes.UserId),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusInternalServerError, "Failed to generate access token")
	}

	res := loginUserRes{
		AccessToken:  accessToken,
		RefreshToken: successRes.RfToken,
		Role:         string(successRes.Role),
		UserID:       successRes.UserId,
	}

	h.mongoLoggerSvc.Info("Login successful",
		zap.Int("status_code", fiber.StatusOK),
		zap.Int64("user_id", successRes.UserId),
		zap.String("role", string(successRes.Role)),
		zap.Time("timestamp", time.Now()),
	)

	return response.WriteJSON(c, fiber.StatusOK, "Login successful", res, nil)
}

// LoginSuper godoc
// @Summary Login super-admin
// @Description Login super-admin
// @Tags auth
// @Accept json
// @Produce json
// @Param login body domain.LoginRequest true "Login super-admin"
// @Success 200 {object} LoginAdminRes
// @Failure 400 {object} response.APIResponse
// @Failure 401 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /api/v1/super-login [post]
func (h *Handler) LoginSuper(c *fiber.Ctx) error {
	var req domain.LoginRequest
	if err := c.BodyParser(&req); err != nil {
		h.mongoLoggerSvc.Info("Failed to parse LoginAdmin request",
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusBadRequest, "Invalid request body"+err.Error())
	}

	if valErrs, ok := h.validator.Validate(c, req); !ok {
		var errMsg string
		for field, msg := range valErrs {
			errMsg += fmt.Sprintf("%s: %s; ", field, msg)
		}
		return fiber.NewError(fiber.StatusBadRequest, errMsg)
	}

	successRes, err := h.authSvc.Login(c.Context(), domain.LoginRequest(req))
	if err != nil {
		switch {
		case errors.Is(err, authentication.ErrInvalidPassword), errors.Is(err, authentication.ErrUserNotFound):
			h.mongoLoggerSvc.Info("Login attempt failed: Invalid credentials",
				zap.Int("status_code", fiber.StatusBadRequest),
				zap.String("email", req.Email),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusBadRequest, "Invalid credentials")
		case errors.Is(err, authentication.ErrUserSuspended):
			h.mongoLoggerSvc.Info("Login attempt failed: User login has been locked",
				zap.Int("status_code", fiber.StatusForbidden),
				zap.String("email", req.Email),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusForbidden, "User login has been locked")
		default:
			h.mongoLoggerSvc.Error("Login failed",
				zap.Int("status_code", fiber.StatusInternalServerError),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusInternalServerError, "Internal server error")
		}
	}

	if successRes.Role != domain.RoleSuperAdmin {
		h.mongoLoggerSvc.Warn("Login attempt: super-admin login of non-super-admin",
			zap.Int("status_code", fiber.StatusForbidden),
			zap.String("role", string(successRes.Role)),
			zap.String("email", req.Email),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusForbidden, "Only admin roles are allowed")
	}

	accessToken, err := jwtutil.CreateJwt(successRes.UserId, successRes.Role, h.jwtConfig.JwtAccessKey, h.jwtConfig.JwtAccessExpiry)
	if err != nil {
		h.mongoLoggerSvc.Error("Failed to create access token",
			zap.Int("status_code", fiber.StatusInternalServerError),
			zap.Int64("user_id", successRes.UserId),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusInternalServerError, "Failed to generate access token")
	}

	res := loginUserRes{
		AccessToken:  accessToken,
		RefreshToken: successRes.RfToken,
		Role:         string(successRes.Role),
	}

	h.mongoLoggerSvc.Info("Login successful",
		zap.Int("status_code", fiber.StatusOK),
		zap.Int64("user_id", successRes.UserId),
		zap.String("role", string(successRes.Role)),
		zap.Time("timestamp", time.Now()),
	)

	return response.WriteJSON(c, fiber.StatusOK, "Login successful", res, nil)
}

type refreshToken struct {
	AccessToken  string `json:"access_token" validate:"required" example:"<jwt-token>"`
	RefreshToken string `json:"refresh_token" validate:"required" example:"<refresh-token>"`
}

// RefreshToken godoc
// @Summary Refresh token
// @Description Refresh token
// @Tags auth
// @Accept json
// @Produce json
// @Param refresh body refreshToken true "tokens"
// @Success 200 {object} loginUserRes
// @Failure 400 {object} response.APIResponse
// @Failure 401 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /api/v1/auth/refresh [post]
func (h *Handler) RefreshToken(c *fiber.Ctx) error {

	type loginUserRes struct {
		AccessToken  string `json:"access_token"`
		RefreshToken string `json:"refresh_token"`
		Role         string `json:"role"`
		UserID       int64  `json:"user_id"`
	}

	var req refreshToken
	if err := c.BodyParser(&req); err != nil {
		h.mongoLoggerSvc.Info("Failed to parse RefreshToken request",
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusBadRequest, "Invalid request body"+err.Error())
	}

	if valErrs, ok := h.validator.Validate(c, req); !ok {
		var errMsg string
		for field, msg := range valErrs {
			errMsg += fmt.Sprintf("%s: %s; ", field, msg)
		}

		h.mongoLoggerSvc.Info("Failed to validate request",
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.Any("validation_errors", valErrs),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusBadRequest, errMsg)
	}

	refreshToken, err := h.authSvc.RefreshToken(c.Context(), req.RefreshToken)
	if err != nil {

		switch {
		case errors.Is(err, authentication.ErrExpiredToken):
			h.mongoLoggerSvc.Info("Refresh token attempt failed: The refresh token has expired",
				zap.Int("status_code", fiber.StatusUnauthorized),
				zap.String("refresh_token", req.RefreshToken),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusUnauthorized, "The refresh token has expired")
		case errors.Is(err, authentication.ErrRefreshTokenNotFound):
			h.mongoLoggerSvc.Info("Refresh token attempt failed: Refresh token not found",
				zap.Int("status_code", fiber.StatusUnauthorized),
				zap.String("refresh_token", req.RefreshToken),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusUnauthorized, "Refresh token not found")
		default:
			h.mongoLoggerSvc.Error("Refresh token failed",
				zap.Int("status_code", fiber.StatusInternalServerError),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusInternalServerError, "Internal server error")
		}
	}

	user, err := h.userSvc.GetUserByID(c.Context(), refreshToken.UserID)
	if err != nil {
		h.mongoLoggerSvc.Error("Failed to get user by ID during refresh",
			zap.Int("status_code", fiber.StatusInternalServerError),
			zap.Int64("user_id", refreshToken.UserID),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusInternalServerError, "Failed to retrieve user information:"+err.Error())
	}

	accessToken, err := jwtutil.CreateJwt(user.ID, user.Role, h.jwtConfig.JwtAccessKey, h.jwtConfig.JwtAccessExpiry)
	if err != nil {
		h.mongoLoggerSvc.Error("Failed to create new access token",
			zap.Int("status_code", fiber.StatusInternalServerError),
			zap.Int64("user_id", user.ID),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusInternalServerError, "Failed to generate access token:"+err.Error())
	}

	res := loginUserRes{
		AccessToken:  accessToken,
		RefreshToken: req.RefreshToken,
		Role:         string(user.Role),
		UserID:       user.ID,
	}

	h.mongoLoggerSvc.Info("Token Refreshed Successfully",
		zap.Int("status_code", fiber.StatusOK),
		zap.Int64("user_id", user.ID),
		zap.String("role", string(user.Role)),
		zap.Time("timestamp", time.Now()),
	)

	return c.Status(fiber.StatusOK).JSON(domain.Response{
		Message:    "Token refreshed successfully",
		Data:       res,
		StatusCode: fiber.StatusOK,
	})
}

type logoutReq struct {
	RefreshToken string `json:"refresh_token" validate:"required" example:"<refresh-token>"`
	DeviceToken  string `json:"device_token" example:"<fcm-device-token>"`
}

// LogOutuser godoc
// @Summary Logout user
// @Description Logout user
// @Tags auth
// @Accept json
// @Produce json
// @Param logout body logoutReq true "Logout user"
// @Success 200 {object} response.APIResponse
// @Failure 400 {object} response.APIResponse
// @Failure 401 {object} response.APIResponse
// @Failure 500 {object} response.APIResponse
// @Router /api/v1/auth/logout [post]
func (h *Handler) LogOutuser(c *fiber.Ctx) error {
	var req logoutReq
	if err := c.BodyParser(&req); err != nil {
		h.mongoLoggerSvc.Info("Failed to parse LogOutuser request",
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.Error(err),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusBadRequest, "Invalid request body"+err.Error())
	}

	if valErrs, ok := h.validator.Validate(c, req); !ok {

		var errMsg string
		for field, msg := range valErrs {
			errMsg += fmt.Sprintf("%s: %s; ", field, msg)
		}

		h.mongoLoggerSvc.Info("LogOutuser validation failed",
			zap.String("errMsg", errMsg),
			zap.Int("status_code", fiber.StatusBadRequest),
			zap.Any("validation_errors", valErrs),
			zap.Time("timestamp", time.Now()),
		)
		return fiber.NewError(fiber.StatusBadRequest, errMsg)
	}

	err := h.authSvc.Logout(c.Context(), req.RefreshToken)
	if err != nil {

		switch {
		case errors.Is(err, authentication.ErrExpiredToken):
			h.mongoLoggerSvc.Info("Logout attempt failed:The refresh token has expired",
				zap.Int("status_code", fiber.StatusUnauthorized),
				zap.String("refresh_token", req.RefreshToken),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusUnauthorized, "The refresh token has expired")
		case errors.Is(err, authentication.ErrRefreshTokenNotFound):
			h.mongoLoggerSvc.Info("Logout attempt failed: Refresh token not found",
				zap.Int("status_code", fiber.StatusUnauthorized),
				zap.String("refresh_token", req.RefreshToken),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusUnauthorized, "Refresh token not found")
		default:
			h.mongoLoggerSvc.Error("Logout failed",
				zap.Int("status_code", fiber.StatusInternalServerError),
				zap.Error(err),
				zap.Time("timestamp", time.Now()),
			)
			return fiber.NewError(fiber.StatusInternalServerError, "Internal server error"+err.Error())
		}
	}

	// Deactivate device token if provided
	if req.DeviceToken != "" {
		userID, ok := c.Locals("user_id").(int64)
		if ok && userID > 0 {
			if err := h.userSvc.DeactivateDevice(c.Context(), userID, req.DeviceToken); err != nil {
				h.mongoLoggerSvc.Warn("Failed to deactivate device token during logout",
					zap.Int64("userID", userID),
					zap.Error(err),
					zap.Time("timestamp", time.Now()),
				)
			}
		}
	}

	h.mongoLoggerSvc.Info("Logout successful",
		zap.Int("status_code", fiber.StatusOK),
		zap.Time("timestamp", time.Now()),
	)

	return response.WriteJSON(c, fiber.StatusOK, "Logout successful", nil, nil)
}
