package handlers

import (
	"net/http"
	"strconv"
	"strings"
	"time"

	"abuse_registration_poc/internal/models"
)

func (h *Handler) DemoRegistrations(writer http.ResponseWriter, request *http.Request) {
	WriteJSON(writer, http.StatusOK, h.store.List(filterFromQuery(request)))
}

func (h *Handler) ListRegistrations(writer http.ResponseWriter, request *http.Request) {
	WriteJSON(writer, http.StatusOK, h.store.List(filterFromQuery(request)))
}

func (h *Handler) GetRegistration(writer http.ResponseWriter, request *http.Request, id string) {
	registration, ok := h.store.Get(id)
	if !ok {
		WriteJSON(writer, http.StatusNotFound, map[string]string{"message": "Registration not found."})
		return
	}
	WriteJSON(writer, http.StatusOK, registration)
}

func (h *Handler) CreateRegistration(writer http.ResponseWriter, request *http.Request) {
	var input models.Registration
	if err := DecodeJSON(request, &input); err != nil {
		WriteJSON(writer, http.StatusBadRequest, map[string]string{"message": "Could not parse request data."})
		return
	}
	created, err := h.store.Create(input)
	if err != nil {
		WriteJSON(writer, http.StatusBadRequest, map[string]string{"message": err.Error()})
		return
	}
	WriteJSON(writer, http.StatusCreated, created)
}

func (h *Handler) UpdateRegistration(writer http.ResponseWriter, request *http.Request, id string) {
	var input models.Registration
	if err := DecodeJSON(request, &input); err != nil {
		WriteJSON(writer, http.StatusBadRequest, map[string]string{"message": "Could not parse request data."})
		return
	}
	updated, ok, err := h.store.Replace(id, input)
	if err != nil {
		WriteJSON(writer, http.StatusBadRequest, map[string]string{"message": err.Error()})
		return
	}
	if !ok {
		WriteJSON(writer, http.StatusNotFound, map[string]string{"message": "Registration not found."})
		return
	}
	WriteJSON(writer, http.StatusOK, updated)
}

func (h *Handler) DeleteRegistration(writer http.ResponseWriter, request *http.Request, id string) {
	if !h.store.Delete(id) {
		WriteJSON(writer, http.StatusNotFound, map[string]string{"message": "Registration not found."})
		return
	}
	WriteJSON(writer, http.StatusOK, map[string]any{"message": "Registration deleted successfully.", "id": id})
}

func (h *Handler) ResetRegistrations(writer http.ResponseWriter, request *http.Request) {
	h.store.Reset()
	rows, _, nextReset := h.store.Snapshot()
	WriteJSON(writer, http.StatusOK, map[string]any{
		"message":       "Dataset reset to base sample data.",
		"dataset_count": len(rows),
		"next_reset":    nextReset.Format(time.RFC3339),
	})
}

func (h *Handler) Categories(writer http.ResponseWriter, request *http.Request) {
	WriteJSON(writer, http.StatusOK, models.AbuseCategories)
}

func (h *Handler) Locations(writer http.ResponseWriter, request *http.Request) {
	WriteJSON(writer, http.StatusOK, models.FaroeLocations)
}

func filterFromQuery(request *http.Request) models.RegistrationFilter {
	query := request.URL.Query()
	filter := models.RegistrationFilter{
		Location:  query.Get("location"),
		AbuseType: query.Get("abuse_type"),
		Gender:    query.Get("gender"),
		Status:    query.Get("status"),
		Search:    query.Get("search"),
		Limit:     queryInt(query.Get("limit"), 0),
		Offset:    queryInt(query.Get("offset"), 0),
	}

	if from, ok := queryTime(query.Get("from")); ok {
		filter.From = from
		filter.HasFrom = true
	}
	if to, ok := queryTime(query.Get("to")); ok {
		filter.To = to
		filter.HasTo = true
	}
	return filter
}

func queryInt(value string, fallback int) int {
	value = strings.TrimSpace(value)
	if value == "" {
		return fallback
	}
	parsed, err := strconv.Atoi(value)
	if err != nil || parsed < 0 {
		return fallback
	}
	return parsed
}

func queryTime(value string) (time.Time, bool) {
	parsed, err := models.ParseInputTime(value)
	if err != nil {
		return time.Time{}, false
	}
	return parsed, true
}
