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

package org

import (
	"net/http"

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

// checkOrgVisibility returns true if the current user can view org metadata.
// Public orgs are visible to everyone. Private/limited orgs require authentication.
func checkOrgVisibility(ctx *context.APIContext) bool {
	if ctx.Org.Organization.Visibility == api.VisibleTypePublic {
		return true
	}
	if ctx.Doer == nil {
		ctx.APIErrorNotFound()
		return false
	}
	return true
}

// ListIssueStatuses returns active issue status definitions for an org.
func ListIssueStatuses(ctx *context.APIContext) {
	// swagger:operation GET /orgs/{org}/issue-statuses organization orgListIssueStatuses
	// ---
	// summary: List an organization's issue status definitions
	// produces:
	// - application/json
	// parameters:
	// - name: org
	//   in: path
	//   description: name of the organization
	//   type: string
	//   required: true
	// responses:
	//   "200":
	//     description: "IssueStatusDefList"
	//     schema:
	//       type: array
	//       items:
	//         "$ref": "#/definitions/IssueStatusDef"
	//   "404":
	//     "$ref": "#/responses/notFound"

	if !checkOrgVisibility(ctx) {
		return
	}

	defs, err := issues_model.GetIssueStatusDefsByOrg(ctx, ctx.Org.Organization.ID)
	if err != nil {
		ctx.APIErrorInternal(err)
		return
	}
	result := make([]*api.IssueStatusDef, 0, len(defs))
	for _, d := range defs {
		result = append(result, &api.IssueStatusDef{
			ID:          d.ID,
			Name:        d.Name,
			Color:       d.Color,
			Description: d.Description,
			ClosesIssue: d.ClosesIssue,
			IsRequired:  d.IsRequired,
			SortOrder:   d.SortOrder,
		})
	}
	ctx.JSON(http.StatusOK, result)
}

// ListIssuePriorities returns active issue priority definitions for an org.
func ListIssuePriorities(ctx *context.APIContext) {
	// swagger:operation GET /orgs/{org}/issue-priorities organization orgListIssuePriorities
	// ---
	// summary: List an organization's issue priority definitions
	// produces:
	// - application/json
	// parameters:
	// - name: org
	//   in: path
	//   description: name of the organization
	//   type: string
	//   required: true
	// responses:
	//   "200":
	//     description: "IssuePriorityDefList"
	//     schema:
	//       type: array
	//       items:
	//         "$ref": "#/definitions/IssuePriorityDef"
	//   "404":
	//     "$ref": "#/responses/notFound"

	if !checkOrgVisibility(ctx) {
		return
	}

	defs, err := issues_model.GetIssuePriorityDefsByOrg(ctx, ctx.Org.Organization.ID)
	if err != nil {
		ctx.APIErrorInternal(err)
		return
	}
	result := make([]*api.IssuePriorityDef, 0, len(defs))
	for _, d := range defs {
		result = append(result, &api.IssuePriorityDef{
			ID:          d.ID,
			Name:        d.Name,
			Color:       d.Color,
			Description: d.Description,
			SortOrder:   d.SortOrder,
			IsDefault:   d.IsDefault,
		})
	}
	ctx.JSON(http.StatusOK, result)
}

// ListIssueTypes returns active issue type definitions for an org.
func ListIssueTypes(ctx *context.APIContext) {
	// swagger:operation GET /orgs/{org}/issue-types organization orgListIssueTypes
	// ---
	// summary: List an organization's issue type definitions
	// produces:
	// - application/json
	// parameters:
	// - name: org
	//   in: path
	//   description: name of the organization
	//   type: string
	//   required: true
	// responses:
	//   "200":
	//     description: "IssueTypeDefList"
	//     schema:
	//       type: array
	//       items:
	//         "$ref": "#/definitions/IssueTypeDef"
	//   "404":
	//     "$ref": "#/responses/notFound"

	if !checkOrgVisibility(ctx) {
		return
	}

	defs, err := issues_model.GetIssueTypeDefsByOrg(ctx, ctx.Org.Organization.ID)
	if err != nil {
		ctx.APIErrorInternal(err)
		return
	}
	result := make([]*api.IssueTypeDef, 0, len(defs))
	for _, d := range defs {
		result = append(result, &api.IssueTypeDef{
			ID:          d.ID,
			Name:        d.Name,
			Color:       d.Color,
			Description: d.Description,
			SortOrder:   d.SortOrder,
			IsDefault:   d.IsDefault,
		})
	}
	ctx.JSON(http.StatusOK, result)
}
