package shortcodes

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"reflect"
	"strings"

	core "fr.latosa-escrima/core"
	"fr.latosa-escrima/core/models"
	"github.com/google/uuid"
)

type UpdateShortcodeArgs struct {
	ID      *int64                `json:"id,omitempty"`
	Code    *string               `json:"code,omitempty"` // The shortcode value
	Type    *models.ShortcodeType `bun:"shortcode_type" json:"type,omitempty"`
	Value   *string               `json:"value,omitempty"`
	MediaID *uuid.UUID            `json:"media_id,omitempty"` // Nullable reference to another table's ID
}

func HandleUpdate(w http.ResponseWriter, r *http.Request) {
	var updateArgs UpdateShortcodeArgs
	err := json.NewDecoder(r.Body).Decode(&updateArgs)
	if err != nil {
		core.JSONError{
			Status:  core.Error,
			Message: err.Error(),
		}.Respond(w, http.StatusInternalServerError)
		return
	}

	var shortcode models.Shortcode
	updateQuery := core.DB.NewUpdate().Model(&shortcode)
	val := reflect.ValueOf(updateArgs)
	typ := reflect.TypeOf(updateArgs)

	for i := 0; i < val.NumField(); i++ {
		field := val.Field(i)

		tag := typ.Field(i).Tag.Get("bun")
		if tag == "" {
			tag = typ.Field(i).Tag.Get("json")
		}

		// Only add fields that are non-nil and non-zero
		if field.IsValid() && !field.IsNil() && !field.IsZero() {
			updateQuery.Set(fmt.Sprintf("%s = ?", strings.Split(tag, ",")[0]), field.Interface())
		}
	}

	code := r.PathValue("shortcode")
	_, err = updateQuery.
		Where("id = ? OR code = ?", updateArgs.ID, code).
		Returning("*").
		Exec(context.Background())

	if err != nil {
		core.JSONError{
			Status:  core.Error,
			Message: err.Error(),
		}.Respond(w, http.StatusInternalServerError)
		return
	}

	core.JSONSuccess{
		Status:  core.Success,
		Message: "Shortcode updated.",
		Data:    shortcode,
	}.Respond(w, http.StatusOK)
}
