package controller

import (
	"fmt"
	"narasi-ahli-be/app/module/ai_chat_files/request"
	"narasi-ahli-be/app/module/ai_chat_files/service"
	"narasi-ahli-be/utils/paginator"
	utilRes "narasi-ahli-be/utils/response"
	utilVal "narasi-ahli-be/utils/validator"
	"strconv"

	"github.com/gofiber/fiber/v2"
)

type aiChatFilesController struct {
	aiChatFilesService service.AiChatFilesService
}

type AiChatFilesController interface {
	All(c *fiber.Ctx) error
	Show(c *fiber.Ctx) error
	Save(c *fiber.Ctx) error
	Update(c *fiber.Ctx) error
	Delete(c *fiber.Ctx) error
	Viewer(c *fiber.Ctx) error
	GetUploadStatus(c *fiber.Ctx) error
	GetByMessageId(c *fiber.Ctx) error


}

func NewAiChatFilesController(aiChatFilesService service.AiChatFilesService) AiChatFilesController {
	return &aiChatFilesController{
		aiChatFilesService: aiChatFilesService,
	}
}

// All AIChatFiles
// @Summary      Get all AiChatFiles
// @Description  API for getting all AiChatFiles
// @Tags         AiChat Files
// @Security     Bearer
// @Param 	     req query request.AiChatFilesQueryRequest false "query parameters"
// @Param 	     req query paginator.Pagination false "pagination parameters"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /ai-chat-files [get]
func (_i *aiChatFilesController) All(c *fiber.Ctx) error {
	// Get from context
	paginate, err := paginator.Paginate(c)
	if err != nil {
		return err
	}

	reqContext := request.AiChatFilesQueryRequestContext{
		MessageId: c.Query("messageId"),
		FileName:  c.Query("fileName"),
	}
	req := reqContext.ToParamRequest()
	req.Pagination = paginate

	aiChatFilesData, paging, err := _i.aiChatFilesService.All(req)
	if err != nil {
		return err
	}

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"AiChatFiles list successfully retrieved"},
		Data:     aiChatFilesData,
		Meta:     paging,
	})
}

// Show AiChatFiles
// @Summary      Get one AiChatFiles
// @Description  API for getting one AiChatFiles
// @Tags         AiChat Files
// @Security     Bearer
// @Param        id path int true "AiChatFiles ID"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /ai-chat-files/{id} [get]
func (_i *aiChatFilesController) Show(c *fiber.Ctx) error {
	// Get from context
	id, err := strconv.ParseUint(c.Params("id"), 10, 0)
	if err != nil {
		return err
	}

	aiChatFilesData, err := _i.aiChatFilesService.Show(uint(id))
	if err != nil {
		return err
	}

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"AiChatFiles successfully retrieved"},
		Data:     aiChatFilesData,
	})
}

// Save AiChatFiles
// @Summary      Upload AiChatFiles
// @Description  API for create AiChatFiles
// @Tags         AiChat Files
// @Security     Bearer
// @Produce      json
// @Param        X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param        files formData file true "Upload file" multiple true
// @Param        messageId path int true "Message Id"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /ai-chat-files/{messageId} [post]
func (_i *aiChatFilesController) Save(c *fiber.Ctx) error {
	// Get from context
	id, err := strconv.ParseUint(c.Params("messageId"), 10, 0)
	if err != nil {
		return err
	}

	err = _i.aiChatFilesService.Save(c, uint(id))
	if err != nil {
		return err
	}

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"AiChatFiles successfully upload"},
	})
}

// Update AiChatFiles
// @Summary      Update AiChatFiles
// @Description  API for update AiChatFiles
// @Tags         AiChat Files
// @Security     Bearer
// @Param        X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param 	     payload body request.AiChatFilesUpdateRequest true "Required payload"
// @Param        id path int true "AiChatFiles ID"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /ai-chat-files/{id} [put]
func (_i *aiChatFilesController) Update(c *fiber.Ctx) error {
	// Get from context
	id, err := strconv.ParseUint(c.Params("id"), 10, 0)
	if err != nil {
		return err
	}

	req := new(request.AiChatFilesUpdateRequest)
	if err := utilVal.ParseAndValidate(c, req); err != nil {
		return err
	}

	err = _i.aiChatFilesService.Update(uint(id), *req)
	if err != nil {
		return err
	}

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"AiChatFiles successfully updated"},
	})
}

// Delete AiChatFiles
// @Summary      Delete AiChatFiles
// @Description  API for delete AiChatFiles
// @Tags         AiChat Files
// @Security     Bearer
// @Param        X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param        id path int true "AiChatFiles ID"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /ai-chat-files/{id} [delete]
func (_i *aiChatFilesController) Delete(c *fiber.Ctx) error {
	// Get from context
	id, err := strconv.ParseUint(c.Params("id"), 10, 0)
	if err != nil {
		return err
	}

	err = _i.aiChatFilesService.Delete(uint(id))
	if err != nil {
		return err
	}

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"AiChatFiles successfully deleted"},
	})
}

// Viewer AiChatFiles
// @Summary      Viewer AiChatFiles
// @Description  API for Viewer AiChatFiles
// @Tags         AiChat Files
// @Security     Bearer
// @Param        filename path string true "AiChat File Name"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /ai-chat-files/viewer/{filename} [get]
func (_i *aiChatFilesController) Viewer(c *fiber.Ctx) error {
	// Get from context
	return _i.aiChatFilesService.Viewer(c)
}

// GetUploadStatus AiChatFiles
// @Summary      GetUploadStatus AiChatFiles
// @Description  API for GetUploadStatus AiChatFiles
// @Tags         AiChat Files
// @Security     Bearer
// @Param        uploadId path string true "Upload ID of AiChatFiles"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /ai-chat-files/upload-status/{uploadId} [get]
func (_i *aiChatFilesController) GetUploadStatus(c *fiber.Ctx) error {
	progress, _ := _i.aiChatFilesService.GetUploadStatus(c)
	progressMessage := fmt.Sprintf("Upload Progress: %d%%", progress)

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"Upload Status Retrieve"},
		Data:     progressMessage,
	})
}

// Show AiChatFiles
// @Summary      Get one AiChatFiles
// @Description  API for getting one AiChatFiles by messageId
// @Tags         AiChat Files
// @Security     Bearer
// @Param        messageId path int true "AiChatFiles MessageId"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /ai-chat-files/by-message/{messageId} [get]
func (_i *aiChatFilesController) GetByMessageId(c *fiber.Ctx) error {
	// ambil messageId dari path
	messageId, err := strconv.ParseUint(c.Params("messageId"), 10, 0)
	if err != nil {
		return utilRes.Resp(c, utilRes.Response{
			Success:  false,
			Messages: utilRes.Messages{"messageId must be numeric"},
		})
	}

	// pagination (SAMA DENGAN All)
	paginate, err := paginator.Paginate(c)
	if err != nil {
		return err
	}

	// bangun request context (reuse pattern All)
	reqContext := request.AiChatFilesQueryRequestContext{
		MessageId: fmt.Sprint(messageId),
	}

	req := reqContext.ToParamRequest()
	req.Pagination = paginate

	// panggil service
	data, paging, err := _i.aiChatFilesService.GetByMessageId(req)
	if err != nil {
		return err
	}

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"AiChatFiles successfully retrieved by messageId"},
		Data:     data,
		Meta:     paging, 
	})
}
