package User

import (
	config "astrology-api/configs"
	dto "astrology-api/dto"
	repositories "astrology-api/repositories"
	services "astrology-api/services"
	"net/http"

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

type FollowerController struct {
	followerService services.FollowerService
}

func NewFollowerController() *FollowerController {
	db := config.DB
	followerRepository := repositories.NewFollowerRepository()

	astrologerRepository := repositories.NewAstrologerRepository(db)

	followerService := services.NewFollowerService(
		followerRepository,
		astrologerRepository,
	)

	return &FollowerController{
		followerService: followerService,
	}
}

func (fc *FollowerController) AddFollowing(c *gin.Context) {

	var req dto.FollowAstrologerRequest

	if err := c.ShouldBindJSON(&req); err != nil {

		c.JSON(http.StatusBadRequest, gin.H{
			"status":  400,
			"message": err.Error(),
		})
		return
	}

	userIDValue, exists := c.Get("user_id")
	if !exists {

		c.JSON(http.StatusUnauthorized, gin.H{
			"status":  401,
			"message": "Unauthorized",
		})
		return
	}

	userID := userIDValue.(uint)

	record, err := fc.followerService.FollowAstrologer(
		userID,
		req.AstrologerID,
	)

	if err != nil {

		c.JSON(http.StatusBadRequest, gin.H{
			"status":  400,
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"status":     200,
		"message":    "Astrologer follower added successfully",
		"recordList": record,
	})
}

func (fc *FollowerController) UpdateFollowing(c *gin.Context) {

	var req dto.FollowAstrologerRequest

	if err := c.ShouldBindJSON(&req); err != nil {

		c.JSON(http.StatusBadRequest, gin.H{
			"status":  400,
			"message": err.Error(),
		})
		return
	}

	userIDValue, exists := c.Get("user_id")
	if !exists {

		c.JSON(http.StatusUnauthorized, gin.H{
			"status":  401,
			"message": "Unauthorized",
		})
		return
	}

	userID := userIDValue.(uint)

	err := fc.followerService.UnfollowAstrologer(
		userID,
		req.AstrologerID,
	)

	if err != nil {

		c.JSON(http.StatusBadRequest, gin.H{
			"status":  400,
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"status":  200,
		"message": "Follower removed successfully",
	})
}

func (fc *FollowerController) GetFollowing(c *gin.Context) {

	var req dto.GetFollowerRequest

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"status":  400,
			"message": err.Error(),
		})
		return
	}

	// Get logged-in user
	userIDValue, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, gin.H{
			"status":  401,
			"message": "Unauthorized",
		})
		return
	}

	userID := userIDValue.(uint)

	recordList, totalFollower, err := fc.followerService.GetFollowingList(userID, req)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"status":  500,
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"status":        200,
		"recordList":    recordList,
		"totalFollower": totalFollower,
	})
}

func (fc *FollowerController) GetAstrologerFollower(c *gin.Context) {

	var req dto.GetFollowerRequest

	if err := c.ShouldBindJSON(&req); err != nil {

		c.JSON(http.StatusBadRequest, gin.H{
			"status":  400,
			"message": err.Error(),
		})
		return
	}

	if req.AstrologerID == 0 {

		c.JSON(http.StatusBadRequest, gin.H{
			"status":  400,
			"message": "astrologerId is required",
		})
		return
	}

	recordList, totalCount, err := fc.followerService.GetAstrologerFollowers(req.AstrologerID)

	if err != nil {

		c.JSON(http.StatusInternalServerError, gin.H{
			"status":  500,
			"message": err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"status":     200,
		"message":    "Get Follower Successfully",
		"recordList": recordList,
		"totalCount": totalCount,
	})
}
