package nostr

import (
	"encoding/json"
	"net"
	"net/http"
	"strings"

	"git.devvul.com/asara/gologger"
	"git.devvul.com/asara/well-goknown/config"
)

func GetNostrAddr(w http.ResponseWriter, r *http.Request) {
	l := gologger.Get(config.GetConfig().LogLevel).With().Caller().Logger()

	// get query string for username
	r.ParseForm()
	name := strings.ToLower(r.FormValue("name"))
	if name == "_" {
		name = ""
	}

	// normalize domain
	domain, _, err := net.SplitHostPort(r.Host)
	if err != nil {
		domain = r.Host
	}

	// get owner id for nip05 request
	var uid int
	err = DB.QueryRow("SELECT owner_id FROM nip05s WHERE name=$1 AND domain=$2", name, domain).Scan(&uid)
	if err != nil {
		l.Debug().Msgf("user (%s@%s) doesn't exist: %s", name, domain, err.Error())
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}

	// get the pubkey and relays associated with the nip05
	user := nostrUser{}
	err = DB.QueryRow("SELECT pubkey, relays FROM users WHERE id=$1", uid).Scan(&user.Pubkey, &user.Relays)
	if err != nil {
		l.Debug().Msgf("unable to get user info for uid %v: %s", uid, err.Error())
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}

	// get all names associated with the pubkey
	names := []string{}
	err = DB.Select(&names, "SELECT nip05s.name FROM nip05s JOIN users ON nip05s.owner_id = users.id WHERE nip05s.owner_id = $1", uid)
	if err != nil {
		l.Debug().Msgf("unable to get nip05 names for uid %v: %s", uid, err.Error())
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}

	// map of names
	n := make(map[string]string)
	for _, name := range names {
		if name == "" {
			n["_"] = user.Pubkey
		} else {
			n[name] = user.Pubkey
		}
	}

	// map of relays
	s := make(map[string][]string)
	if user.Relays != nil {
		if strings.Contains(*user.Relays, ",") {
			s[user.Pubkey] = strings.Split(*user.Relays, ",")
		} else {
			s[user.Pubkey] = []string{*user.Relays}
		}
	}

	// map of nip46
	t := make(map[string][]string)
	t[user.Pubkey] = []string{"wss://relay.devvul.com"}

	ret := nostrWellKnown{
		Names:  n,
		Relays: s,
		NIP46:  t,
	}

	j, err := json.Marshal(ret)
	if err != nil {
		l.Error().Msgf("unable to marshal nip05 response: %s", err.Error())
		http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
		return
	}

	l.Debug().Msgf("returning nip05 for %s@%s: %s", name, domain, user.Pubkey)
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write(j)
	return
}