// Copyright 2026 Moko Consulting <hello@mokoconsulting.tech>
// SPDX-License-Identifier: GPL-3.0-or-later

package admin

import (
	"net/http"
	"strconv"

	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/db"
	licensing_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/licensing"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/json"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/templates"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/services/context"
)

const tplLicenseTiers templates.TplName = "admin/license_tiers"

// LicenseTiers shows the product tier management page.
func LicenseTiers(ctx *context.Context) {
	ctx.Data["Title"] = "Product Tiers"
	ctx.Data["PageIsAdminLicenseTiers"] = true

	tiers, err := licensing_model.GetAllProductTiers(ctx)
	if err != nil {
		ctx.ServerError("GetAllProductTiers", err)
		return
	}

	type tierView struct {
		*licensing_model.ProductTier
		Repos        []string
		LicenseCount int64
	}

	views := make([]tierView, 0, len(tiers))
	for _, t := range tiers {
		count, _ := db.GetEngine(ctx).Where("tier = ?", t.TierKey).Count(new(licensing_model.License))
		views = append(views, tierView{
			ProductTier:  t,
			Repos:        t.RepoList(),
			LicenseCount: count,
		})
	}

	ctx.Data["Tiers"] = views
	ctx.HTML(http.StatusOK, tplLicenseTiers)
}

// LicenseTierCreate handles POST to create a new tier.
func LicenseTierCreate(ctx *context.Context) {
	tierKey := ctx.FormString("tier_key")
	tierName := ctx.FormString("tier_name")
	repos := ctx.FormStrings("repos")
	maxDomains, _ := strconv.Atoi(ctx.FormString("max_domains"))
	sortOrder, _ := strconv.Atoi(ctx.FormString("sort_order"))

	if tierKey == "" || tierName == "" {
		ctx.Flash.Error("Tier key and name are required")
		ctx.Redirect("/admin/license-tiers")
		return
	}

	reposJSON, _ := json.Marshal(repos)
	tier := &licensing_model.ProductTier{
		TierKey:    tierKey,
		TierName:   tierName,
		Repos:      string(reposJSON),
		MaxDomains: maxDomains,
		SortOrder:  sortOrder,
	}

	if _, err := db.GetEngine(ctx).Insert(tier); err != nil {
		ctx.Flash.Error("Failed to create tier: " + err.Error())
	} else {
		ctx.Flash.Success("Tier '" + tierName + "' created")
	}
	ctx.Redirect("/admin/license-tiers")
}

// LicenseTierUpdate handles POST to update a tier.
func LicenseTierUpdate(ctx *context.Context) {
	id, _ := strconv.ParseInt(ctx.PathParam("id"), 10, 64)

	tier := new(licensing_model.ProductTier)
	has, _ := db.GetEngine(ctx).ID(id).Get(tier)
	if !has {
		ctx.NotFound(nil)
		return
	}

	tier.TierName = ctx.FormString("tier_name")
	repos := ctx.FormStrings("repos")
	reposJSON, _ := json.Marshal(repos)
	tier.Repos = string(reposJSON)
	tier.MaxDomains, _ = strconv.Atoi(ctx.FormString("max_domains"))
	tier.SortOrder, _ = strconv.Atoi(ctx.FormString("sort_order"))

	if _, err := db.GetEngine(ctx).ID(id).Cols("tier_name", "repos", "max_domains", "sort_order").Update(tier); err != nil {
		ctx.Flash.Error("Failed to update tier: " + err.Error())
	} else {
		ctx.Flash.Success("Tier '" + tier.TierName + "' updated")
	}
	ctx.Redirect("/admin/license-tiers")
}

// LicenseTierDelete handles POST to delete a tier.
func LicenseTierDelete(ctx *context.Context) {
	id, _ := strconv.ParseInt(ctx.FormString("id"), 10, 64)

	tier := new(licensing_model.ProductTier)
	has, _ := db.GetEngine(ctx).ID(id).Get(tier)
	if !has {
		ctx.NotFound(nil)
		return
	}

	count, _ := db.GetEngine(ctx).Where("tier = ?", tier.TierKey).Count(new(licensing_model.License))
	if count > 0 {
		ctx.Flash.Error("Cannot delete tier with active licenses. Reassign licenses first.")
		ctx.Redirect("/admin/license-tiers")
		return
	}

	db.GetEngine(ctx).ID(id).Delete(new(licensing_model.ProductTier))
	ctx.Flash.Success("Tier '" + tier.TierName + "' deleted")
	ctx.Redirect("/admin/license-tiers")
}
