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

package repo

import (
	"encoding/json"
	"net/http"

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

// GetRepoCustomFields returns all repo-scoped custom field values.
func GetRepoCustomFields(ctx *context.APIContext) {
	ownerID := ctx.Repo.Repository.OwnerID
	repoID := ctx.Repo.Repository.ID

	fields, err := issues_model.GetCustomFieldsByOwner(ctx, ownerID, issues_model.CustomFieldScopeRepo)
	if err != nil {
		ctx.APIErrorInternal(err)
		return
	}

	values, err := issues_model.GetCustomFieldValuesMap(ctx, repoID)
	if err != nil {
		ctx.APIErrorInternal(err)
		return
	}

	result := make(map[string]string, len(fields))
	for _, f := range fields {
		result[f.Name] = values[f.ID]
	}
	ctx.JSON(http.StatusOK, result)
}

// SetRepoCustomFields sets repo-scoped custom field values.
func SetRepoCustomFields(ctx *context.APIContext) {
	ownerID := ctx.Repo.Repository.OwnerID
	repoID := ctx.Repo.Repository.ID

	var req map[string]string
	if err := json.NewDecoder(ctx.Req.Body).Decode(&req); err != nil {
		ctx.APIError(http.StatusBadRequest, err)
		return
	}

	fields, err := issues_model.GetCustomFieldsByOwner(ctx, ownerID, issues_model.CustomFieldScopeRepo)
	if err != nil {
		ctx.APIErrorInternal(err)
		return
	}

	// Build name->ID map
	nameToID := make(map[string]int64, len(fields))
	for _, f := range fields {
		nameToID[f.Name] = f.ID
	}

	for name, value := range req {
		if fieldID, ok := nameToID[name]; ok {
			if err := issues_model.SetCustomFieldValue(ctx, repoID, fieldID, value); err != nil {
				ctx.APIErrorInternal(err)
				return
			}
		}
	}

	ctx.Status(http.StatusNoContent)
}

// GetIssueCustomFields returns custom field values for an issue.
func GetIssueCustomFields(ctx *context.APIContext) {
	issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index"))
	if err != nil {
		ctx.APIErrorNotFound()
		return
	}

	ownerID := ctx.Repo.Repository.OwnerID
	fields, err := issues_model.GetCustomFieldsByOwner(ctx, ownerID, issues_model.CustomFieldScopeIssue)
	if err != nil {
		ctx.APIErrorInternal(err)
		return
	}

	values, err := issues_model.GetCustomFieldValuesMap(ctx, issue.ID)
	if err != nil {
		ctx.APIErrorInternal(err)
		return
	}

	result := make(map[string]string, len(fields))
	for _, f := range fields {
		result[f.Name] = values[f.ID]
	}
	ctx.JSON(http.StatusOK, result)
}

// SetIssueCustomFields sets custom field values for an issue.
func SetIssueCustomFields(ctx *context.APIContext) {
	issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.PathParamInt64("index"))
	if err != nil {
		ctx.APIErrorNotFound()
		return
	}

	var req map[string]string
	if err := json.NewDecoder(ctx.Req.Body).Decode(&req); err != nil {
		ctx.APIError(http.StatusBadRequest, err)
		return
	}

	ownerID := ctx.Repo.Repository.OwnerID
	fields, err := issues_model.GetCustomFieldsByOwner(ctx, ownerID, issues_model.CustomFieldScopeIssue)
	if err != nil {
		ctx.APIErrorInternal(err)
		return
	}

	nameToID := make(map[string]int64, len(fields))
	for _, f := range fields {
		nameToID[f.Name] = f.ID
	}

	for name, value := range req {
		if fieldID, ok := nameToID[name]; ok {
			if err := issues_model.SetCustomFieldValue(ctx, issue.ID, fieldID, value); err != nil {
				ctx.APIErrorInternal(err)
				return
			}
		}
	}

	ctx.Status(http.StatusNoContent)
}
