package controller

import (
	"narasi-ahli-be/app/module/education_history/request"
	"narasi-ahli-be/app/module/education_history/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 educationHistoryController struct {
	educationHistoryService service.EducationHistoryService
}

type EducationHistoryController 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
	UploadCertificate(c *fiber.Ctx) error
}

func NewEducationHistoryController(educationHistoryService service.EducationHistoryService) EducationHistoryController {
	return &educationHistoryController{
		educationHistoryService: educationHistoryService,
	}
}

// All Education History
// @Summary      Get all Education History
// @Description  API for getting all Education History for specific user
// @Tags         Education History
// @Param        req query request.EducationHistoryQueryRequest false "query parameters"
// @Param        req query paginator.Pagination false "pagination parameters"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      500  {object}  response.InternalServerError
// @Router       /education-history [get]
func (_i *educationHistoryController) All(c *fiber.Ctx) error {
	paginate, err := paginator.Paginate(c)
	if err != nil {
		return err
	}
	reqContext := request.EducationHistoryQueryRequestContext{
		UserID:         c.Query("userId"),
		SchoolName:     c.Query("schoolName"),
		Major:          c.Query("major"),
		EducationLevel: c.Query("educationLevel"),
		GraduationYear: c.Query("graduationYear"),
	}
	req := reqContext.ToParamRequest()
	req.Pagination = paginate

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

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

// Show Education History
// @Summary      Get one Education History
// @Description  API for getting one Education History
// @Tags         Education History
// @Param        id path int true "Education History ID"
// @Param        userId query uint true "User ID"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      500  {object}  response.InternalServerError
// @Router       /education-history/{id} [get]
func (_i *educationHistoryController) Show(c *fiber.Ctx) error {
	id, err := strconv.ParseUint(c.Params("id"), 10, 0)
	if err != nil {
		return err
	}

	userId, err := strconv.ParseUint(c.Query("userId"), 10, 0)
	if err != nil {
		return utilRes.Resp(c, utilRes.Response{
			Success:  false,
			Messages: utilRes.Messages{"userId parameter is required and must be a valid number"},
		})
	}

	educationData, err := _i.educationHistoryService.Show(uint(userId), uint(id))
	if err != nil {
		return err
	}

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"Education history successfully retrieved"},
		Data:     educationData,
	})
}

// Save Education History
// @Summary      Create Education History
// @Description  API for create Education History
// @Tags         Education History
// @Param        X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param        userId query uint true "User ID"
// @Param        payload body request.EducationHistoryCreateRequest true "Required payload"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      500  {object}  response.InternalServerError
// @Router       /education-history [post]
func (_i *educationHistoryController) Save(c *fiber.Ctx) error {
	userId, err := strconv.ParseUint(c.Query("userId"), 10, 0)
	if err != nil {
		return utilRes.Resp(c, utilRes.Response{
			Success:  false,
			Messages: utilRes.Messages{"userId parameter is required and must be a valid number"},
		})
	}

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

	dataResult, err := _i.educationHistoryService.Save(uint(userId), *req)
	if err != nil {
		return err
	}

	return utilRes.Resp(c, utilRes.Response{
		Success:  true,
		Messages: utilRes.Messages{"Education history successfully created"},
		Data:     dataResult,
	})
}

// Update Education History
// @Summary      Update Education History
// @Description  API for update Education History
// @Tags         Education History
// @Param        X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param        id path int true "Education History ID"
// @Param        userId query uint true "User ID"
// @Param        payload body request.EducationHistoryUpdateRequest true "Required payload"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      500  {object}  response.InternalServerError
// @Router       /education-history/{id} [put]
func (_i *educationHistoryController) Update(c *fiber.Ctx) error {
	id, err := strconv.ParseUint(c.Params("id"), 10, 0)
	if err != nil {
		return err
	}

	userId, err := strconv.ParseUint(c.Query("userId"), 10, 0)
	if err != nil {
		return utilRes.Resp(c, utilRes.Response{
			Success:  false,
			Messages: utilRes.Messages{"userId parameter is required and must be a valid number"},
		})
	}

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

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

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

// Delete Education History
// @Summary      Delete Education History
// @Description  API for delete Education History
// @Tags         Education History
// @Param        X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param        id path int true "Education History ID"
// @Param        userId query uint true "User ID"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      500  {object}  response.InternalServerError
// @Router       /education-history/{id} [delete]
func (_i *educationHistoryController) Delete(c *fiber.Ctx) error {
	id, err := strconv.ParseUint(c.Params("id"), 10, 0)
	if err != nil {
		return err
	}

	userId, err := strconv.ParseUint(c.Query("userId"), 10, 0)
	if err != nil {
		return utilRes.Resp(c, utilRes.Response{
			Success:  false,
			Messages: utilRes.Messages{"userId parameter is required and must be a valid number"},
		})
	}

	err = _i.educationHistoryService.Delete(uint(userId), uint(id))
	if err != nil {
		return err
	}

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

// UploadCertificate Education History
// @Summary      Upload Certificate for Education History
// @Description  API for upload certificate image for Education History
// @Tags         Education History
// @Param        X-Csrf-Token header string true "Insert the X-Csrf-Token"
// @Param        id path int true "Education History ID"
// @Param        userId query uint true "User ID"
// @Param        certificate formData file true "Certificate image file"
// @Success      200  {object}  response.Response
// @Failure      400  {object}  response.BadRequestError
// @Failure      500  {object}  response.InternalServerError
// @Router       /education-history/{id}/certificate [post]
func (_i *educationHistoryController) UploadCertificate(c *fiber.Ctx) error {
	id, err := strconv.ParseUint(c.Params("id"), 10, 0)
	if err != nil {
		return err
	}

	userId, err := strconv.ParseUint(c.Query("userId"), 10, 0)
	if err != nil {
		return utilRes.Resp(c, utilRes.Response{
			Success:  false,
			Messages: utilRes.Messages{"userId parameter is required and must be a valid number"},
		})
	}

	err = _i.educationHistoryService.UploadCertificate(uint(userId), uint(id), c)
	if err != nil {
		return err
	}

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