package handler

import (
	"bytes"
	"encoding/json"
	"html/template"
	"net/http"
	"path/filepath"
	"strconv"
	"time"
	"xboard-go/internal/service"

	"github.com/gin-gonic/gin"
)

type userThemeViewData struct {
	Title           string
	Description     string
	Version         string
	Theme           string
	Logo            string
	AssetsPath      string
	CustomHTML      template.HTML
	ThemeConfigJSON template.JS
}

type adminAppViewData struct {
	Title      string
	SettingsJS template.JS
	AssetNonce string
}

func UserThemePage(c *gin.Context) {
	config := map[string]any{
		"accent":            service.MustGetString("nebula_theme_color", "aurora"),
		"slogan":            service.MustGetString("nebula_hero_slogan", "One control center for login, subscriptions, sessions, and device visibility."),
		"backgroundUrl":     service.MustGetString("nebula_background_url", ""),
		"metricsBaseUrl":    service.MustGetString("nebula_metrics_base_url", ""),
		"defaultThemeMode":  service.MustGetString("nebula_default_theme_mode", "system"),
		"lightLogoUrl":      service.MustGetString("nebula_light_logo_url", ""),
		"darkLogoUrl":       service.MustGetString("nebula_dark_logo_url", ""),
		"welcomeTarget":     service.MustGetString("nebula_welcome_target", service.MustGetString("app_name", "XBoard")),
		"registerTitle":     service.MustGetString("nebula_register_title", "Create your access."),
		"icpNo":             service.MustGetString("icp_no", ""),
		"psbNo":             service.MustGetString("psb_no", ""),
		"staticCdnUrl":      service.MustGetString("nebula_static_cdn_url", ""),
		"isRegisterEnabled": !service.MustGetBool("stop_register", false),
	}

	payload := userThemeViewData{
		Title:           service.MustGetString("app_name", "XBoard"),
		Description:     service.MustGetString("app_description", "Go rebuilt control panel"),
		Version:         service.MustGetString("app_version", "2.0.0"),
		Theme:           "Nebula",
		Logo:            service.MustGetString("logo", ""),
		AssetsPath:      "/theme/Nebula/assets",
		CustomHTML:      template.HTML(service.MustGetString("nebula_custom_html", "")),
		ThemeConfigJSON: mustJSON(config),
	}

	renderPageTemplate(c, filepath.Join("frontend", "templates", "user_nebula.html"), payload)
}

func AdminAppPage(c *gin.Context) {
	securePath := service.GetAdminSecurePath()
	title := service.MustGetString("app_name", "XBoard") + " Admin"

	settings := map[string]string{
		// Keep admin API requests same-origin so reverse proxies and HTTPS termination
		// don't depend on backend protocol/header inference.
		"base_url":    "",
		"title":       title,
		"version":     service.MustGetString("app_version", "1.0.0"),
		"logo":        service.MustGetString("logo", ""),
		"secure_path": securePath,
	}
	settingsJSON, _ := json.Marshal(settings)

	payload := adminAppViewData{
		Title:      title,
		SettingsJS: template.JS(settingsJSON),
		AssetNonce: strconv.FormatInt(time.Now().UnixNano(), 10),
	}

	renderPageTemplate(c, filepath.Join("frontend", "templates", "admin_app.html"), payload)
}

func renderPageTemplate(c *gin.Context, templatePath string, data any) {
	tpl, err := template.ParseFiles(templatePath)
	if err != nil {
		c.String(http.StatusInternalServerError, "template parse error: %v", err)
		return
	}

	var buf bytes.Buffer
	if err := tpl.Execute(&buf, data); err != nil {
		c.String(http.StatusInternalServerError, "template render error: %v", err)
		return
	}

	c.Data(http.StatusOK, "text/html; charset=utf-8", buf.Bytes())
}

func mustJSON(value any) template.JS {
	payload, err := json.Marshal(value)
	if err != nil {
		return template.JS("{}")
	}
	return template.JS(payload)
}
