package api

import (
	"context"
	"database/sql"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"

	"github.com/rycroftapparel/workpulse-api/internal/httpapi"
)

// reportOwnerOrSuperadmin returns the report owner when the caller may modify the report (owner or superadmin).
func (s *Server) reportOwnerOrSuperadmin(c *gin.Context, ctx context.Context, reportID uint64) (owner uint64, ok bool) {
	uid := userID(c)
	var o uint64
	err := s.DB.QueryRowContext(ctx, `SELECT user_id FROM reports WHERE id = $1`, reportID).Scan(&o)
	if err == sql.ErrNoRows {
		c.JSON(http.StatusNotFound, httpapi.Fail("not_found", "report not found"))
		return 0, false
	}
	if err != nil {
		c.JSON(http.StatusInternalServerError, httpapi.Fail("db", err.Error()))
		return 0, false
	}
	if o == uid || roleIsSuperadmin(c) {
		return o, true
	}
	c.JSON(http.StatusForbidden, httpapi.Fail("forbidden", "only owner can update"))
	return 0, false
}

// loadReportForBodyMutation loads report body/status when the caller may change body or attachments.
// Owners may only mutate draft reports; superadmin may mutate any status.
func (s *Server) loadReportForBodyMutation(c *gin.Context, reportID uint64) (body string, status string, ok bool) {
	dbCtx, cancel := s.ctx(c)
	defer cancel()
	uid := userID(c)
	var owner uint64
	var b, st string
	err := s.DB.QueryRowContext(dbCtx, `SELECT user_id, body, status FROM reports WHERE id = $1`, reportID).Scan(&owner, &b, &st)
	if err == sql.ErrNoRows {
		c.JSON(http.StatusNotFound, httpapi.Fail("not_found", "report not found"))
		return "", "", false
	}
	if err != nil {
		c.JSON(http.StatusInternalServerError, httpapi.Fail("db", err.Error()))
		return "", "", false
	}
	if roleIsSuperadmin(c) {
		return b, st, true
	}
	if owner != uid {
		c.JSON(http.StatusForbidden, httpapi.Fail("forbidden", "only owner can update"))
		return "", "", false
	}
	if strings.ToLower(strings.TrimSpace(st)) != "draft" {
		c.JSON(http.StatusBadRequest, httpapi.Fail("validation", "Lampiran hanya dapat diubah saat laporan masih draf."))
		return "", "", false
	}
	return b, st, true
}
