package admin

import (
	"errors"
	"net/http"

	"codeberg.org/nextgo/dbots/internal/db"
	"codeberg.org/nextgo/dbots/internal/errorutil"
	"codeberg.org/nextgo/dbots/internal/middleware"
	"codeberg.org/nextgo/dbots/internal/paginate"

	"github.com/go-chi/chi/v5"
	"github.com/go-chi/render"
)

type Router struct {
	admin  *Service
	router chi.Router
}

func NewRouter(q *db.Queries) *Router {
	return &Router{
		admin:  NewService(q),
		router: chi.NewRouter(),
	}
}

func (r *Router) Routes() http.Handler {
	r.router.Use(middleware.AuthGuardMiddleware) // todo: admin middleware

	r.router.Route("/bots", func(router chi.Router) {
		router.Get("/", r.listBots)
		router.Route("/{botID}", func(b chi.Router) {
			b.Use(middleware.BotContext(r.admin.q))
			b.Get("/", r.getBot)
			b.Post("/status", r.updateStatus)
		})
	})

	return r.router
}

func (r *Router) updateStatus(w http.ResponseWriter, req *http.Request) {
	var data UpdateBotStatusRequest
	ctx := req.Context()
	bot := middleware.GetBot(ctx)

	if err := render.Bind(req, &data); err != nil {
		render.Render(w, req, errorutil.ErrInvalidRequest(err))
		return
	}

	updatedBot, err := r.admin.UpdateStatus(ctx, bot.ID, data.NewStatus)
	if err != nil {
		if errors.Is(err, errorutil.ErrNotFound.Err) {
			render.Render(w, req, errorutil.ErrNotFound)
		} else {
			render.Render(w, req, errorutil.ErrInternal(err))
		}
		return
	}

	render.JSON(w, req, updatedBot)
}

func (r *Router) getBot(w http.ResponseWriter, req *http.Request) {
	ctx := req.Context()
	bot := middleware.GetBot(ctx)

	render.JSON(w, req, bot)
}

func (r *Router) listBots(w http.ResponseWriter, req *http.Request) {
	ctx := req.Context()
	status := db.BotStatus(req.URL.Query().Get("s"))
	p := paginate.ParseParams(req)

	page, err := r.admin.ListBots(ctx, status, p)
	if err != nil {
		render.Render(w, req, errorutil.ErrInvalidRequest(err))
		return
	}

	render.JSON(w, req, page)
}
