package controllers

import (
	"58team_blog/internal/application/commands"
	"58team_blog/internal/application/queries"
	"58team_blog/internal/application/services"
	"58team_blog/internal/interfaces/api/dto"
	"58team_blog/internal/interfaces/api/requests"
	"58team_blog/internal/interfaces/api/responses"
	"log"
	"net/http"

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

type PostController struct {
	service *services.PostService
}

func CreatePostController(service *services.PostService) PostController {
	return PostController{
		service: service,
	}
}

// PostPost godoc
//
//	@Summary		Create new post
//	@Description	Create new post in blog
//	@Tags			post
//	@Accept			json
//	@Produce		json
//	@Param request body requests.CreatePostRequest true "Post data"
//	@Success		200	{object}	responses.PostResponse
//	@Failure	400 {object} responses.ErrorResponse
//	@Failure 500 {object} responses.ErrorResponse
//	@Router			/post [post]
func (r *PostController) Post(c *gin.Context) {
	var request requests.CreatePostRequest

	if err := c.BindJSON(&request); err != nil {
		log.Println(err)
		resp := responses.CreateErrorResponse(http.StatusBadRequest, "BadRequest")
		c.IndentedJSON(resp.ErrorCode, resp)
		return
	}

	userId, err := uuid.Parse(request.UserId)
	if err != nil {
		log.Println(err)
		resp := responses.CreateErrorResponse(http.StatusBadRequest, "Incorrect user id")
		c.IndentedJSON(resp.ErrorCode, resp)
		return
	}

	cmd := commands.CreatePostCommand{
		UserId:      userId,
		Title:       request.Title,
		Description: request.Description,
		Content:     request.Content,
	}

	res, err := r.service.Create(cmd)
	if err != nil {
		log.Println(err)
		resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error")
		c.IndentedJSON(resp.ErrorCode, resp)
		return
	}

	response := dto.ResponseFromPostResult(res)

	c.IndentedJSON(http.StatusOK, response)
}

// GetAllPost 	godoc
//
//	@Summary		Get all posts
//	@Description	Return first 5 posts
//	@Tags			post
//	@Produce		json
//	@Success		200	{array}	responses.GetListPostResponseItem
//	@Failure 500 {object} responses.ErrorResponse
//	@Router			/post [get]
func (r *PostController) GetAll(c *gin.Context) {
	result, err := r.service.GetAll()
	if err != nil {
		log.Println(err)
		resp := responses.CreateErrorResponse(http.StatusInternalServerError, "Internal server error")
		c.IndentedJSON(resp.ErrorCode, resp)
		return
	}

	res := dto.ResponseFromPostGetAllResult(result)

	c.JSON(http.StatusOK, res)
}

// GetAllWithOffsetPost godoc
// @Summary		Get posts after offset
// @Description	return 5 posts after first offset posts
// @Tags			post
// @Param			offset	query	int	true	"Offset of posts"
// @Produce		json
// @Success		200	{array}	responses.GetListPostResponseItem
// @Router			/post/{offset} [get]
func (r *PostController) GetAllWithOffset(c *gin.Context) {

}

// GetByIdPost godoc
// @Summary		Get post by id
// @Description	get post by id
// @Tags			post
// @Param			id	query	string	true	"Id of post"
// @Produce		json
// @Success		200	{array}	responses.PostResponse
// @Failure		400 {object} responses.ErrorResponse
// @Router			/post/{id} [get]
func (r *PostController) GetById(c *gin.Context) {
	id := c.Param("id")

	id_valid, err := uuid.Parse(id)
	if err != nil {
		log.Println("User get by id error: ", err)
		resp := responses.CreateErrorResponse(http.StatusBadRequest, "Invalid user id")
		c.JSON(resp.ErrorCode, resp)
		return
	}

	query := queries.PostFindByIdQuery{
		Id: id_valid,
	}

	posts, err := r.service.FindById(query)
	if err != nil {
		log.Println("Post service error: ", err)
		resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request")
		c.JSON(resp.ErrorCode, resp)
		return
	}

	result := dto.ResponseFormPostFindByIdResult(posts)

	c.JSON(http.StatusOK, result)
}

// PutPost godoc
// @Summary		Update post content
// @Description	update post content
// @Tags			post
// @Param			id	query	string	true	"Id of post"
//
//	@Param 		request body requests.PutPostRequest true "Post data"
//
// @Produce		json
// @Success		200	{object}	responses.PostResponse
// @Failure		400 {object}	responses.ErrorResponse
// @Router			/post/{id} [put]
func (r *PostController) Put(c *gin.Context) {
	var request requests.PutPostRequest

	if err := c.BindJSON(request); err != nil {
		log.Println("Post request error: ", err)
		resp := responses.CreateErrorResponse(http.StatusBadRequest, "Bad request")
		c.JSON(resp.ErrorCode, resp)
	}
}

// Delete godoc
// @Summary		Delete post
// @Description	Delete post by id
// @Tags			post
// @Param			id	query	string	true	"Id of post"
// @Produce		json
// @Success		200
// @Router			/post/{id} [delete]

func (r *PostController) Delete(c *gin.Context) {

}
