package admin

import (
	"context"
	"errors"
	"log/slog"
	"strings"

	"codeberg.org/nextgo/dbots/internal/db"
	"codeberg.org/nextgo/dbots/internal/errorutil"
	"codeberg.org/nextgo/dbots/internal/paginate"
	"github.com/jackc/pgx/v5"
)

type Service struct {
	q *db.Queries
}

func NewService(q *db.Queries) *Service {
	return &Service{q: q}
}

func (s *Service) UpdateStatus(ctx context.Context, id string, status db.BotStatus) (*db.Bot, error) {
	bot, err := s.q.UpdateBotStatus(ctx, db.UpdateBotStatusParams{
		ID:     id,
		Status: status,
	})
	if err != nil {
		if errors.Is(err, pgx.ErrNoRows) {
			return nil, errorutil.ErrNotFound.Err
		} else {
			return nil, err
		}
	}

	return bot, nil
}

func (s *Service) Get(ctx context.Context, id string) (*db.Bot, error) {
	bot, err := s.q.GetBot(ctx, id)
	if err != nil {
		slog.Error("error getting bot", "err", err, "id", id)
		if errors.Is(err, pgx.ErrNoRows) {
			return nil, errorutil.ErrNotFound.Err
		} else {
			return nil, err
		}
	}

	return bot, nil
}

func (s *Service) ListBots(ctx context.Context, status db.BotStatus, p paginate.Params) (paginate.Page[*db.Bot], error) {
	status = db.BotStatus(strings.ToLower(status.String()))
	total, err := s.q.CountBotsByUsername(ctx, db.CountBotsByUsernameParams{
		Status: status,
	})
	if err != nil {
		slog.Error("error counting bots", "err", err)
		return paginate.Page[*db.Bot]{}, errorutil.ErrSearchFailed
	}

	bots, err := s.q.ListBotsByStatus(ctx, db.ListBotsByStatusParams{
		Status: status,
		Limit:  p.Limit,
		Offset: p.Offset,
	})
	if err != nil {
		slog.Error("error listing bots", "err", err)
		return paginate.Page[*db.Bot]{}, errorutil.ErrSearchFailed
	}

	return paginate.NewPage(bots, int(total), p), nil
}
