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

package org

import (
	"net/http"
	"strconv"

	issues_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/issues"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/templates"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/services/context"
)

const tplOrgIssueStatuses templates.TplName = "org/settings/issue_statuses"

// SettingsIssueStatuses shows the org-level issue statuses management page.
func SettingsIssueStatuses(ctx *context.Context) {
	ctx.Data["Title"] = ctx.Tr("org.settings.issue_statuses")
	ctx.Data["PageIsOrgSettings"] = true
	ctx.Data["PageIsSettingsIssueStatuses"] = true

	defs, err := issues_model.GetAllIssueStatusDefsByOrg(ctx, ctx.Org.Organization.ID)
	if err != nil {
		ctx.ServerError("GetAllIssueStatusDefsByOrg", err)
		return
	}
	ctx.Data["IssueStatuses"] = defs

	ctx.HTML(http.StatusOK, tplOrgIssueStatuses)
}

// SettingsIssueStatusesCreatePost creates a new org-level issue status.
func SettingsIssueStatusesCreatePost(ctx *context.Context) {
	sortOrder, _ := strconv.Atoi(ctx.FormString("sort_order"))

	def := &issues_model.IssueStatusDef{
		OrgID:       ctx.Org.Organization.ID,
		Name:        ctx.FormString("name"),
		Color:       ctx.FormString("color"),
		Description: ctx.FormString("description"),
		ClosesIssue: ctx.FormString("closes_issue") == "on",
		SortOrder:   sortOrder,
		IsActive:    true,
	}

	if def.Name == "" {
		ctx.Flash.Error("Status name is required")
		ctx.Redirect(ctx.Org.OrgLink + "/settings/issue-statuses")
		return
	}

	if err := issues_model.CreateIssueStatusDef(ctx, def); err != nil {
		ctx.ServerError("CreateIssueStatusDef", err)
		return
	}

	ctx.Flash.Success(ctx.Tr("org.settings.issue_status_created"))
	ctx.Redirect(ctx.Org.OrgLink + "/settings/issue-statuses")
}

// SettingsIssueStatusesEditPost updates an org-level issue status.
func SettingsIssueStatusesEditPost(ctx *context.Context) {
	id := ctx.PathParamInt64("id")
	def, err := issues_model.GetIssueStatusDefByID(ctx, id)
	if err != nil {
		ctx.ServerError("GetIssueStatusDefByID", err)
		return
	}
	if def.OrgID != ctx.Org.Organization.ID {
		ctx.NotFound(nil)
		return
	}

	def.Name = ctx.FormString("name")
	def.Color = ctx.FormString("color")
	def.Description = ctx.FormString("description")
	def.ClosesIssue = ctx.FormString("closes_issue") == "on"
	def.IsActive = ctx.FormString("is_active") == "on"
	sortOrder, _ := strconv.Atoi(ctx.FormString("sort_order"))
	def.SortOrder = sortOrder

	if err := issues_model.UpdateIssueStatusDef(ctx, def); err != nil {
		ctx.ServerError("UpdateIssueStatusDef", err)
		return
	}

	ctx.Flash.Success(ctx.Tr("org.settings.issue_status_updated"))
	ctx.Redirect(ctx.Org.OrgLink + "/settings/issue-statuses")
}

// SettingsIssueStatusesDeletePost deletes an org-level issue status.
func SettingsIssueStatusesDeletePost(ctx *context.Context) {
	id := ctx.PathParamInt64("id")
	def, err := issues_model.GetIssueStatusDefByID(ctx, id)
	if err != nil {
		ctx.ServerError("GetIssueStatusDefByID", err)
		return
	}
	if def.OrgID != ctx.Org.Organization.ID {
		ctx.NotFound(nil)
		return
	}

	if err := issues_model.DeleteIssueStatusDef(ctx, id); err != nil {
		ctx.ServerError("DeleteIssueStatusDef", err)
		return
	}

	ctx.Flash.Success(ctx.Tr("org.settings.issue_status_deleted"))
	ctx.Redirect(ctx.Org.OrgLink + "/settings/issue-statuses")
}
