package api

import (
	"errors"
	"net/http"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"

	"github.com/tidbcloud/aisupport/services/oncall/models"
	"github.com/tidbcloud/aisupport/services/oncall/service"
)

func AddTeamRoutes(r *gin.RouterGroup, s *service.ScheduleService) {
	// respondTeamDetail runs the manager check + detail load + response for a team id.
	respondTeamDetail := func(c *gin.Context, s *service.ScheduleService, id uint) {
		email := c.GetString("request_user_email")
		if email == "" {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
			return
		}
		role, err := s.TeamRoleOf(id, email)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		isManager := role != "" && models.TeamRoleRank(role) >= models.TeamRoleRank(models.TeamRoleManager)
		canWrite := role != "" && models.TeamRoleRank(role) >= models.TeamRoleRank(models.TeamRoleEditor)
		isMember, err := s.IsTeamMember(id, email)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		res, err := s.GetTeamDetail(id)
		if err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				c.JSON(http.StatusNotFound, gin.H{"error": "team not found"})
				return
			}
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		res["role"] = role
		res["is_manager"] = isManager
		res["is_member"] = isMember
		// can_write covers editors too; is_manager stays manager-only so a
		// client cannot mistake one for the other.
		res["can_write"] = canWrite
		c.JSON(http.StatusOK, res)
	}

	// GET /api/v1/teams/{ref}: ref is the numeric team id, or the unique immutable
	// slug name so URLs can be shared (e.g. /api/v1/teams/payments). Sub-resources
	// still use the numeric id from the response.
	r.GET("/:ref", func(c *gin.Context) {
		ref := strings.TrimSpace(c.Param("ref"))
		if ref == "" {
			c.JSON(http.StatusBadRequest, gin.H{"error": "invalid team ref"})
			return
		}
		if n, err := strconv.Atoi(ref); err == nil && n > 0 {
			respondTeamDetail(c, s, uint(n))
			return
		}
		id, err := s.FindTeamIDByName(ref)
		if err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				c.JSON(http.StatusNotFound, gin.H{"error": "team not found"})
				return
			}
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		respondTeamDetail(c, s, id)
	})
}
