package web

import (
	"net/http"
	"net/url"
)

// Per-app Tier-2 (off-drive copy) config panel — item 4.
//
// The "2. mentés" row on the backup page used to link its "Beállítás" button at the app's deploy
// page, which has no backup-location setting (a dead end). This is the real surface: it shows the
// current/auto off-drive target + last-run status, and lets the customer pin a different registered
// drive or turn Tier 2 off. It is ALWAYS shown — even when only the internal SSD qualifies, or the
// app's data lives on the rootfs (already in PBS) — with honest context rather than a hidden control.
//
// Routes (wired in server.go, behind RequireAuth + CsrfProtect):
//   GET  /stacks/{name}/backup  → tier2ConfigPageHandler
//   POST /stacks/{name}/backup  → tier2ConfigSaveHandler

func (s *Server) tier2ConfigPageHandler(w http.ResponseWriter, r *http.Request, name string) {
	stack, ok := s.stackMgr.GetStack(name)
	if !ok {
		http.NotFound(w, r)
		return
	}
	if s.backupMgr == nil {
		http.Error(w, "A mentés nincs beállítva ezen a szerveren.", http.StatusServiceUnavailable)
		return
	}

	info := s.backupMgr.Tier2Info(name)

	data := s.baseData("backups", "2. mentés beállítása — "+stack.Meta.DisplayName)
	data["StackName"] = name
	data["DisplayName"] = stack.Meta.DisplayName
	data["Tier2"] = info
	if flash := r.URL.Query().Get("flash"); flash != "" {
		data["Flash"] = flash
	}
	if flashErr := r.URL.Query().Get("flash_error"); flashErr != "" {
		data["FlashError"] = flashErr
	}
	s.executeTemplate(w, r, "tier2_config", data)
}

func (s *Server) tier2ConfigSaveHandler(w http.ResponseWriter, r *http.Request, name string) {
	if _, ok := s.stackMgr.GetStack(name); !ok {
		http.NotFound(w, r)
		return
	}
	if s.backupMgr == nil {
		http.Error(w, "A mentés nincs beállítva ezen a szerveren.", http.StatusServiceUnavailable)
		return
	}
	_ = r.ParseForm()

	// "enabled" checkbox: present → Tier 2 on; absent → off (UserDisabled = !enabled).
	enabled := r.FormValue("enabled") == "on" || r.FormValue("enabled") == "true"
	target := r.FormValue("target") // "" = automatic; otherwise a registered drive path

	// Validate the chosen target against the eligible alternatives (defence-in-depth: the runner
	// also re-validates off-disk at run time, but reject a bogus path here for a clean message).
	if target != "" {
		valid := false
		for _, opt := range s.backupMgr.Tier2Info(name).Alternatives {
			if opt.Path == target {
				valid = true
				break
			}
		}
		if !valid {
			s.redirectTier2(w, r, name, "", "A választott cél meghajtó nem érvényes.")
			return
		}
	}

	if err := s.settings.SetTier2Preference(name, !enabled, target); err != nil {
		s.logger.Printf("[ERROR] [web] save Tier 2 preference for %s: %v", name, err)
		s.redirectTier2(w, r, name, "", "A beállítás mentése nem sikerült.")
		return
	}
	s.logger.Printf("[INFO] [web] Tier 2 preference saved for %s: enabled=%v target=%q", name, enabled, target)

	// Apply immediately when enabled for an HDD app so the customer sees the result on return.
	if enabled && s.backupMgr.Tier2Info(name).IsHDDApp {
		go func() {
			if err := s.backupMgr.RunTier2(name); err != nil {
				s.logger.Printf("[WARN] [web] immediate Tier 2 run for %s failed: %v", name, err)
			}
		}()
	}

	s.redirectTier2(w, r, name, "A 2. mentés beállítása elmentve.", "")
}

// appEmailToggleHandler flips the per-app email toggle (only for apps with an smtp_mapping)
// and recreates the stack so the SMTP env injection takes effect. Redirects back to the
// app's config page with a flash.
func (s *Server) appEmailToggleHandler(w http.ResponseWriter, r *http.Request, name string) {
	if _, ok := s.stackMgr.GetStack(name); !ok {
		http.NotFound(w, r)
		return
	}
	_ = r.ParseForm()
	enabled := r.FormValue("app_email_enabled") == "on" || r.FormValue("app_email_enabled") == "true"

	dest := "/stacks/" + url.PathEscape(name) + "/deploy"
	if err := s.stackMgr.SetAppEmailEnabled(name, enabled); err != nil {
		s.logger.Printf("[ERROR] [web] app-email toggle for %s: %v", name, err)
		http.Redirect(w, r, dest+"?flash_error="+url.QueryEscape(err.Error()), http.StatusSeeOther)
		return
	}
	s.logger.Printf("[INFO] [web] App-email for %s set to %v", name, enabled)
	msg := "Email-küldés kikapcsolva ennél az alkalmazásnál."
	if enabled {
		msg = "Email-küldés bekapcsolva ennél az alkalmazásnál."
	}
	http.Redirect(w, r, dest+"?flash="+url.QueryEscape(msg), http.StatusSeeOther)
}

// redirectTier2 sends the customer back to the panel with a flash message.
func (s *Server) redirectTier2(w http.ResponseWriter, r *http.Request, name, flash, flashErr string) {
	dest := "/stacks/" + url.PathEscape(name) + "/backup"
	q := url.Values{}
	if flash != "" {
		q.Set("flash", flash)
	}
	if flashErr != "" {
		q.Set("flash_error", flashErr)
	}
	if e := q.Encode(); e != "" {
		dest += "?" + e
	}
	http.Redirect(w, r, dest, http.StatusSeeOther)
}
