package handlers

import (
	"net/http"

	"warpbox.dev/backend/libs/helpers"
	"warpbox.dev/backend/libs/services"
	"warpbox.dev/backend/libs/web"
)

type managePageData struct {
	Box             boxView
	Token           string
	FileCount       int
	TotalSize       string
	ExpiresLabel    string
	DownloadCount   int
	MaxDownloads    int
	Protected       bool
	DeleteActionURL string
}

func (a *App) ManageBox(w http.ResponseWriter, r *http.Request) {
	box, ok := a.loadManagedBox(w, r)
	if !ok {
		return
	}

	a.renderPage(w, r, http.StatusOK, "manage.html", web.PageData{
		Title:       "Manage upload",
		Description: "Delete this anonymous Warpbox upload.",
		Data:        a.managePageData(box, r.PathValue("token")),
	})
	a.logger.Info("anonymous manage page viewed", withRequestLogAttrs(r, "source", "anonymous-delete", "severity", "user_activity", "code", 2102, "box_id", box.ID)...)
}

func (a *App) ManageDeleteBox(w http.ResponseWriter, r *http.Request) {
	box, ok := a.loadManagedBox(w, r)
	if !ok {
		return
	}

	if err := a.uploadService.DeleteBoxWithToken(box.ID, r.PathValue("token")); err != nil {
		a.logger.Warn("anonymous delete failed", withRequestLogAttrs(r, "source", "anonymous-delete", "severity", "warn", "code", 4102, "box_id", box.ID, "error", err.Error())...)
		http.NotFound(w, r)
		return
	}
	a.logger.Info("anonymous box deleted", withRequestLogAttrs(r, "source", "anonymous-delete", "severity", "user_activity", "code", 2103, "box_id", box.ID)...)
	http.Redirect(w, r, "/d/"+box.ID+"/deleted", http.StatusSeeOther)
}

func (a *App) ManageDeleted(w http.ResponseWriter, r *http.Request) {
	a.renderPage(w, r, http.StatusOK, "manage_deleted.html", web.PageData{
		Title:       "Upload deleted",
		Description: "This Warpbox upload has been deleted.",
		Data:        boxView{ID: r.PathValue("boxID")},
	})
}

func (a *App) loadManagedBox(w http.ResponseWriter, r *http.Request) (services.Box, bool) {
	box, err := a.uploadService.GetBox(r.PathValue("boxID"))
	if err != nil {
		a.logger.Warn("anonymous manage missing box", withRequestLogAttrs(r, "source", "anonymous-delete", "severity", "warn", "code", 4103, "box_id", r.PathValue("boxID"))...)
		http.NotFound(w, r)
		return services.Box{}, false
	}
	if !a.uploadService.VerifyDeleteToken(box, r.PathValue("token")) {
		a.logger.Warn("anonymous manage invalid token", withRequestLogAttrs(r, "source", "anonymous-delete", "severity", "warn", "code", 4104, "box_id", box.ID)...)
		http.NotFound(w, r)
		return services.Box{}, false
	}
	return box, true
}

func (a *App) managePageData(box services.Box, token string) managePageData {
	var totalSize int64
	for _, file := range box.Files {
		totalSize += file.Size
	}
	return managePageData{
		Box:             boxView{ID: box.ID},
		Token:           token,
		FileCount:       len(box.Files),
		TotalSize:       helpers.FormatBytes(totalSize),
		ExpiresLabel:    boxExpiryLabel(box.ExpiresAt, "Jan 2, 2006 15:04 MST"),
		DownloadCount:   box.DownloadCount,
		MaxDownloads:    box.MaxDownloads,
		Protected:       a.uploadService.IsProtected(box),
		DeleteActionURL: "/d/" + box.ID + "/manage/" + token + "/delete",
	}
}
