package user

import (
	"context"
	httplib "dev.tandem.ws/tandem/camper/pkg/http"
	"fmt"
	"net/http"
	"time"

	"dev.tandem.ws/tandem/camper/pkg/auth"
	"dev.tandem.ws/tandem/camper/pkg/database"
	"dev.tandem.ws/tandem/camper/pkg/template"
)

func serveLoginAttemptIndex(w http.ResponseWriter, r *http.Request, loginAttempt *auth.User, company *auth.Company, conn *database.Conn) {
	filters := newFilterForm()
	if err := filters.Parse(r); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}
	loginAttempts, err := collectLoginAttemptEntries(r.Context(), conn, filters)
	if err != nil {
		panic(err)
	}
	index := &loginAttemptIndex{
		Attempts: filters.buildCursor(loginAttempts),
		Filters:  filters,
	}
	index.MustRender(w, r, loginAttempt, company)
}

func collectLoginAttemptEntries(ctx context.Context, conn *database.Conn, filters *filterForm) ([]*loginAttemptEntry, error) {
	where, args := filters.BuildQuery(nil)
	rows, err := conn.Query(ctx, fmt.Sprintf(`
		select attempt_id
		     , user_name
		     , host(ip_address)
		     , attempted_at
		     , success
		from company_login_attempt
		where (%s)
		order by attempted_at desc, attempt_id desc
		limit %d
	`, where, filters.PerPage()+1), args...)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	var entries []*loginAttemptEntry
	for rows.Next() {
		entry := &loginAttemptEntry{}
		if err = rows.Scan(&entry.ID, &entry.UserName, &entry.IPAddress, &entry.Date, &entry.Success); err != nil {
			return nil, err
		}
		entries = append(entries, entry)
	}

	return entries, nil
}

type loginAttemptEntry struct {
	ID        int
	UserName  string
	IPAddress string
	Date      time.Time
	Success   bool
}

type loginAttemptIndex struct {
	Attempts []*loginAttemptEntry
	Filters  *filterForm
}

func (page *loginAttemptIndex) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) {
	if httplib.IsHTMxRequest(r) && page.Filters.Paginated() {
		template.MustRenderAdminNoLayout(w, r, user, company, "user/results.gohtml", page)
	} else {
		template.MustRenderAdminFiles(w, r, user, company, page, "user/login-attempts.gohtml", "user/results.gohtml")
	}
}
