package web

import (
	"net/http"
	"strings"

	"github.com/gofiber/fiber/v3"
	"github.com/pkg/errors"
)

type ListResponse[E any] struct {
	Total int64 `json:"total"`
	List  []E   `json:"list"`
}

func (l *ListResponse[E]) SetTotal(total int64) *ListResponse[E] {
	l.Total = total
	return l
}
func (l *ListResponse[E]) SetList(list []E) *ListResponse[E] {
	l.List = list
	return l
}

func NewListResponse[E any](total int64, list []E) *ListResponse[E] {
	return &ListResponse[E]{
		Total: total,
		List:  list,
	}
}

type Response struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg,omitempty"`
	Data interface{} `json:"data,omitempty"`
}

func (r *Response) SetCode(code int) *Response {
	r.Code = code
	return r
}

func NewResponse(data interface{}, msg ...string) *Response {
	return &Response{
		Code: http.StatusOK,
		Msg:  strings.Join(msg, ","),
		Data: data,
	}
}

func ErrHandle(ctx fiber.Ctx, err error) error {
	// Status code defaults to 500
	code := fiber.StatusInternalServerError
	// Retrieve the custom status code if it's a *fiber.Error
	var e *fiber.Error
	if errors.As(err, &e) {
		code = e.Code
	}

	// Send custom error page
	err = ctx.JSON(Response{
		Code: code,
		Msg:  err.Error(),
	})
	if err != nil {
		// In case the SendFile fails
		return ctx.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
	}

	// Return from handler
	return nil
}