package app

import (
	"encoding/json"
	"log/slog"
	"net/http"

	"git.warky.dev/wdevs/amcs/internal/tools"
)

type adminActions struct {
	backfill *tools.BackfillTool
	retry    *tools.EnrichmentRetryer
	logger   *slog.Logger
}

func newAdminActions(backfill *tools.BackfillTool, retry *tools.EnrichmentRetryer, logger *slog.Logger) *adminActions {
	return &adminActions{
		backfill: backfill,
		retry:    retry,
		logger:   logger,
	}
}

func (a *adminActions) backfillHandler() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			w.Header().Set("Allow", http.MethodPost)
			http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
			return
		}

		var in tools.BackfillInput
		if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
			http.Error(w, "invalid request body", http.StatusBadRequest)
			return
		}

		_, out, err := a.backfill.Handle(r.Context(), nil, in)
		if err != nil {
			if a.logger != nil {
				a.logger.Warn("admin backfill failed", slog.String("error", err.Error()))
			}
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		w.Header().Set("Content-Type", "application/json")
		_ = json.NewEncoder(w).Encode(out)
	})
}

func (a *adminActions) retryMetadataHandler() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			w.Header().Set("Allow", http.MethodPost)
			http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
			return
		}

		var in tools.RetryEnrichmentInput
		if err := json.NewDecoder(r.Body).Decode(&in); err != nil {
			http.Error(w, "invalid request body", http.StatusBadRequest)
			return
		}

		_, out, err := a.retry.Handle(r.Context(), nil, in)
		if err != nil {
			if a.logger != nil {
				a.logger.Warn("admin metadata retry failed", slog.String("error", err.Error()))
			}
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}

		w.Header().Set("Content-Type", "application/json")
		_ = json.NewEncoder(w).Encode(out)
	})
}
