package controller

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

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

type chatScheduleFileController struct {
	chatScheduleFileService service.ChatScheduleFileService
}

type ChatScheduleFileController interface {
	// File upload endpoints
	UploadChatScheduleFile(c *fiber.Ctx) error
	GetChatScheduleFiles(c *fiber.Ctx) error
	GetChatScheduleFileByID(c *fiber.Ctx) error
	UpdateChatScheduleFile(c *fiber.Ctx) error
	DeleteChatScheduleFile(c *fiber.Ctx) error
	Viewer(c *fiber.Ctx) error
}

func NewChatScheduleFileController(chatScheduleFileService service.ChatScheduleFileService) ChatScheduleFileController {
	return &chatScheduleFileController{
		chatScheduleFileService: chatScheduleFileService,
	}
}

// UploadChatScheduleFile - Upload file for chat schedule
// @Summary      Upload chat schedule file
// @Description  API for uploading file for chat schedule
// @Tags         Chat Schedule File
// @Security     Bearer
// @Produce      json
// @Param        X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param        Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param        files formData file true "Upload file" multiple true
// @Param        chatScheduleId path int true "Chat Schedule ID"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /chat/schedule-files/{chatScheduleId} [post]
func (_i *chatScheduleFileController) UploadChatScheduleFile(c *fiber.Ctx) error {
	// Get chat schedule ID from path
	id, err := strconv.ParseUint(c.Params("chatScheduleId"), 10, 0)
	if err != nil {
		return err
	}

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

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"Chat schedule files successfully uploaded"},
	})
}

// GetChatScheduleFiles - Get files for a chat schedule
// @Summary      Get chat schedule files
// @Description  API for getting files for a specific chat schedule
// @Tags         Chat Schedule File
// @Security     Bearer
// @Param        Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param        chatScheduleId query uint true "Chat Schedule ID"
// @Param        fileType query string false "File type filter"
// @Param        isRequired query bool false "Required file filter"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /chat/schedule-files [get]
func (_i *chatScheduleFileController) GetChatScheduleFiles(c *fiber.Ctx) error {
	authToken := c.Get("Authorization")

	req := request.ChatScheduleFileQueryRequest{}

	// Parse chat schedule ID
	if chatScheduleIdStr := c.Query("chatScheduleId"); chatScheduleIdStr != "" {
		if chatScheduleId, err := strconv.ParseUint(chatScheduleIdStr, 10, 0); err == nil {
			chatScheduleIdUint := uint(chatScheduleId)
			req.ChatScheduleID = &chatScheduleIdUint
		}
	}

	// Parse file type
	if fileType := c.Query("fileType"); fileType != "" {
		req.FileType = &fileType
	}

	// Parse is required
	if isRequiredStr := c.Query("isRequired"); isRequiredStr != "" {
		if isRequired, err := strconv.ParseBool(isRequiredStr); err == nil {
			req.IsRequired = &isRequired
		}
	}

	files, err := _i.chatScheduleFileService.GetChatScheduleFiles(authToken, req)
	if err != nil {
		return err
	}

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"Chat schedule files successfully retrieved"},
		Data:     files,
	})
}

// GetChatScheduleFileByID - Get one chat schedule file
// @Summary      Get one chat schedule file
// @Description  API for getting one chat schedule file
// @Tags         Chat Schedule File
// @Security     Bearer
// @Param        Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param        id path int true "Chat Schedule File ID"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /chat/schedule-files/{id} [get]
func (_i *chatScheduleFileController) GetChatScheduleFileByID(c *fiber.Ctx) error {
	id, err := strconv.ParseUint(c.Params("id"), 10, 0)
	if err != nil {
		return err
	}

	authToken := c.Get("Authorization")

	file, err := _i.chatScheduleFileService.GetChatScheduleFileByID(authToken, uint(id))
	if err != nil {
		return err
	}

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"Chat schedule file successfully retrieved"},
		Data:     file,
	})
}

// UpdateChatScheduleFile - Update chat schedule file
// @Summary      Update chat schedule file
// @Description  API for updating chat schedule file
// @Tags         Chat Schedule File
// @Security     Bearer
// @Param        X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param        Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param        id path int true "Chat Schedule File ID"
// @Param        payload body request.ChatScheduleFileUpdateRequest true "Required payload"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /chat/schedule-files/{id} [put]
func (_i *chatScheduleFileController) UpdateChatScheduleFile(c *fiber.Ctx) error {
	id, err := strconv.ParseUint(c.Params("id"), 10, 0)
	if err != nil {
		return err
	}

	authToken := c.Get("Authorization")

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

	err = _i.chatScheduleFileService.UpdateChatScheduleFile(authToken, uint(id), *req)
	if err != nil {
		return err
	}

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

// DeleteChatScheduleFile - Delete chat schedule file
// @Summary      Delete chat schedule file
// @Description  API for deleting chat schedule file
// @Tags         Chat Schedule File
// @Security     Bearer
// @Param        X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param        Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param        id path int true "Chat Schedule File ID"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /chat/schedule-files/{id} [delete]
func (_i *chatScheduleFileController) DeleteChatScheduleFile(c *fiber.Ctx) error {
	id, err := strconv.ParseUint(c.Params("id"), 10, 0)
	if err != nil {
		return err
	}

	authToken := c.Get("Authorization")

	err = _i.chatScheduleFileService.DeleteChatScheduleFile(authToken, uint(id))
	if err != nil {
		return err
	}

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

// Viewer - View chat schedule file
// @Summary      View chat schedule file
// @Description  API for viewing chat schedule file
// @Tags         Chat Schedule File
// @Security     Bearer
// @Param        Authorization header string false "Insert your access token" default(Bearer <Add access token here>)
// @Param        filename path string true "Chat Schedule File Name"
// @Success      200  {file}  file
// @Failure      400  {object}  response.BadRequestError
// @Failure      401  {object}  response.UnauthorizedError
// @Failure      500  {object}  response.InternalServerError
// @Router       /chat/schedule-files/viewer/{filename} [get]
func (_i *chatScheduleFileController) Viewer(c *fiber.Ctx) error {
	return _i.chatScheduleFileService.Viewer(c)
}
