package handlers

import (
	"net/http"
	"os"
	"strings"

	"gauth-central/internal/database"
	"gauth-central/internal/models"
	"gauth-central/pkg/utils"

	"github.com/gin-gonic/gin"
)

type AvatarHandler struct{}

func NewAvatarHandler() *AvatarHandler {
	return &AvatarHandler{}
}

// UploadAvatar godoc
// @Summary Upload user avatar
// @Tags User
// @Security ApiKeyAuth
// @Accept multipart/form-data
// @Produce json
// @Param avatar formData file true "Avatar image file"
// @Success 200 {object} map[string]interface{}
// @Router /user/avatar [post]
func (h *AvatarHandler) UploadAvatar(c *gin.Context) {
	userID := c.GetString("user_id")
	if userID == "" {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
		return
	}

	// Parse multipart form
	file, err := c.FormFile("avatar")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "No file uploaded"})
		return
	}

	// Validate file size (max 5MB)
	if file.Size > 5*1024*1024 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "File size exceeds 5MB limit"})
		return
	}

	// Get user to check for old avatar
	var user models.User
	if err := database.DB.Where("id = ?", userID).First(&user).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
		return
	}

	// Delete old avatar file if exists and is not from OAuth
	if user.Avatar != "" && strings.HasPrefix(user.Avatar, "/uploads/") {
		oldPath := "." + user.Avatar
		os.Remove(oldPath) // Ignore error if file doesn't exist
	}

	// Use utils.SaveOptimizedImage
	avatarURL, err := utils.SaveOptimizedImage(file, "./uploads/avatars", userID, nil)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save avatar: " + err.Error()})
		return
	}

	// Update avatar URL
	if err := database.DB.Model(&user).Update("avatar", avatarURL).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update avatar"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message":    "Avatar uploaded successfully",
		"avatar_url": avatarURL,
		"user": gin.H{
			"id":       user.ID,
			"username": user.UserName,
			"email":    user.Email,
			"avatar":   avatarURL,
		},
	})
}

// DeleteAvatar godoc
// @Summary Delete user avatar
// @Tags User
// @Security ApiKeyAuth
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Router /user/avatar [delete]
func (h *AvatarHandler) DeleteAvatar(c *gin.Context) {
	userID := c.GetString("user_id")
	if userID == "" {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
		return
	}

	var user models.User
	if err := database.DB.Where("id = ?", userID).First(&user).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
		return
	}

	// Delete avatar file if it's a local upload
	if user.Avatar != "" && strings.HasPrefix(user.Avatar, "/uploads/") {
		filepath := "." + user.Avatar
		os.Remove(filepath) // Ignore error if file doesn't exist
	}

	// Set avatar to empty string
	if err := database.DB.Model(&user).Update("avatar", "").Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete avatar"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "Avatar deleted successfully",
		"user": gin.H{
			"id":       user.ID,
			"username": user.UserName,
			"email":    user.Email,
			"avatar":   "",
		},
	})
}

// AdminUploadAvatar godoc
// @Summary Upload avatar for any user (Admin only)
// @Tags Admin - User Management
// @Security ApiKeyAuth
// @Accept multipart/form-data
// @Produce json
// @Param id path string true "User ID"
// @Param avatar formData file true "Avatar image file"
// @Success 200 {object} map[string]interface{}
// @Router /admin/users/{id}/avatar [post]
func (h *AvatarHandler) AdminUploadAvatar(c *gin.Context) {
	userID := c.Param("id")

	// Parse multipart form
	file, err := c.FormFile("avatar")
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "No file uploaded"})
		return
	}

	// Validate file size (max 5MB)
	if file.Size > 5*1024*1024 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "File size exceeds 5MB limit"})
		return
	}

	// Get user to check for old avatar
	var user models.User
	if err := database.DB.Where("id = ?", userID).First(&user).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
		return
	}

	// Delete old avatar file if exists and is not from OAuth
	if user.Avatar != "" && strings.HasPrefix(user.Avatar, "/uploads/") {
		oldPath := "." + user.Avatar
		os.Remove(oldPath) // Ignore error if file doesn't exist
	}

	// Use utils.SaveOptimizedImage
	avatarURL, err := utils.SaveOptimizedImage(file, "./uploads/avatars", userID, nil)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save avatar: " + err.Error()})
		return
	}

	// Update avatar URL
	if err := database.DB.Model(&user).Update("avatar", avatarURL).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update avatar"})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message":    "Avatar uploaded successfully",
		"avatar_url": avatarURL,
		"user": gin.H{
			"id":       user.ID,
			"username": user.UserName,
			"email":    user.Email,
			"avatar":   avatarURL,
		},
	})
}
