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

package repo

import (
	"net/http"

	security_model "code.mokoconsulting.tech/MokoConsulting/MokoGitea/models/security"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/modules/templates"
	"code.mokoconsulting.tech/MokoConsulting/MokoGitea/services/context"
	security_service "code.mokoconsulting.tech/MokoConsulting/MokoGitea/services/security"
)

const tplRepoSecurity templates.TplName = "repo/security"

// Security renders the repo-level security tab showing alerts and scan controls.
func Security(ctx *context.Context) {
	ctx.Data["Title"] = ctx.Tr("repo.security")
	ctx.Data["PageIsSecurity"] = true

	repoID := ctx.Repo.Repository.ID

	cfg, err := security_model.GetScannerConfig(ctx, repoID)
	if err != nil {
		ctx.ServerError("GetScannerConfig", err)
		return
	}
	ctx.Data["ScannerConfig"] = cfg

	alerts, err := security_model.GetAllAlerts(ctx, repoID)
	if err != nil {
		ctx.ServerError("GetAllAlerts", err)
		return
	}
	ctx.Data["SecurityAlerts"] = alerts

	counts, err := security_model.GetAlertCountsByRepo(ctx, repoID)
	if err != nil {
		ctx.ServerError("GetAlertCountsByRepo", err)
		return
	}
	ctx.Data["AlertCounts"] = counts

	ctx.HTML(http.StatusOK, tplRepoSecurity)
}

// SecurityScanNow triggers an immediate scan from the security tab.
func SecurityScanNow(ctx *context.Context) {
	commit := ctx.Repo.Commit
	if commit == nil {
		ctx.Flash.Error("No commits found")
		ctx.Redirect(ctx.Repo.RepoLink + "/security")
		return
	}

	security_service.ScanOnPush(ctx, ctx.Repo.Repository, commit)
	ctx.Flash.Success(ctx.Tr("repo.settings.security_scan_complete"))
	ctx.Redirect(ctx.Repo.RepoLink + "/security")
}

// SecurityAlertUpdate changes alert status from the security tab.
func SecurityAlertUpdateTab(ctx *context.Context) {
	id := ctx.PathParamInt64("id")
	status := security_model.AlertStatus(ctx.FormString("status"))

	if status != security_model.AlertStatusResolved && status != security_model.AlertStatusDismissed {
		status = security_model.AlertStatusDismissed
	}

	alert, err := security_model.GetAlertByID(ctx, id)
	if err != nil {
		ctx.ServerError("GetAlertByID", err)
		return
	}
	if alert.RepoID != ctx.Repo.Repository.ID {
		ctx.NotFound(nil)
		return
	}

	if err := security_model.UpdateAlertStatus(ctx, id, status, ctx.Doer.ID); err != nil {
		ctx.ServerError("UpdateAlertStatus", err)
		return
	}

	ctx.Flash.Success("Alert updated")
	ctx.Redirect(ctx.Repo.RepoLink + "/security")
}
