package webdebug

import (
	"database/sql"
	"encoding/json"
	"errors"
	"net/http"

	webutils "git.mstar.dev/mstar/goutils/http"
	"git.mstar.dev/mstar/goutils/sliceutils"
	"github.com/rs/zerolog/hlog"
	"gorm.io/gorm"

	"git.mstar.dev/mstar/linstrom/storage-new"
	"git.mstar.dev/mstar/linstrom/storage-new/dbgen"
	"git.mstar.dev/mstar/linstrom/storage-new/models"
	webshared "git.mstar.dev/mstar/linstrom/web/shared"
)

func postAs(w http.ResponseWriter, r *http.Request) {
	type Inbound struct {
		Username string `json:"username"`
		Content  string `json:"content"`
	}
	log := hlog.FromRequest(r)
	dec := json.NewDecoder(r.Body)
	data := Inbound{}
	err := dec.Decode(&data)
	if err != nil {
		webutils.ProblemDetails(
			w,
			http.StatusBadRequest,
			"/errors/bad-request-data",
			"bad request data",
			nil,
			map[string]any{
				"sample": Inbound{
					Username: "bob",
					Content:  "Heya there, this is sample data",
				},
			},
		)
		return
	}
	user, err := dbgen.User.GetByUsername(data.Username)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			webutils.ProblemDetailsStatusOnly(w, http.StatusNotFound)
		} else {
			log.Error().Err(err).Str("name", data.Username).Msg("Failed to find user")
			webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
		}
		return
	}
	n := dbgen.Note
	note := models.Note{
		Creator:        *user,
		CreatorId:      user.ID,
		RawContent:     data.Content,
		Remote:         false,
		ContentWarning: sql.NullString{Valid: false},
		RepliesTo:      sql.NullString{Valid: false},
		Quotes:         sql.NullString{Valid: false},
		AccessLevel:    models.NOTE_TARGET_PUBLIC,
		OriginId:       1,
	}
	n.Select(
		n.CreatorId,
		n.RawContent,
		n.Remote,
		n.ContentWarning,
		n.RepliesTo,
		n.Quotes,
		n.AccessLevel,
		n.OriginId,
	).Create(&note)
}

func notesFrom(w http.ResponseWriter, r *http.Request) {
	log := hlog.FromRequest(r)
	username := r.FormValue("username")
	user, err := dbgen.User.GetByUsername(username)
	if err != nil {
		log.Error().Err(err).Str("name", username).Msg("Failed to get user")
		storage.HandleReconnectError(err)
		webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
		return
	}
	notes, err := dbgen.Note.GetNotesPaged(user.ID, 0, uint8(models.NOTE_TARGET_PUBLIC))
	if err != nil {
		log.Error().Err(err).Str("name", username).Msg("Failed to get notes")
		webutils.ProblemDetailsStatusOnly(w, http.StatusInternalServerError)
		return
	}
	publicNotes := sliceutils.Map(notes, func(t models.Note) webshared.Note {
		n := webshared.Note{}
		n.FromModel(&t)
		return n
	})
	webutils.SendJson(w, publicNotes)
}
