package handlers

import (
	"errors"
	"net/http"
	"sheetless-server/database"
	"sheetless-server/models"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
)

func AddComposer(c *gin.Context) {
	var req struct {
		Name string `json:"name" binding:"required"`
		Bio  string `json:"bio"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	uuid, err := GenerateNonexistentComposerUuid()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Could not generate composer uuid"})
		return
	}

	composer := models.Composer{
		Uuid:      *uuid,
		Name:      req.Name,
		Bio:       req.Bio,
		CreatedAt: time.Now(),
		UpdatedAt: time.Now(),
	}

	if err := database.DB.Create(&composer).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create composer"})
		return
	}

	c.JSON(http.StatusCreated, gin.H{
		"message":  "Composer created successfully",
		"composer": composer,
	})
}

func ListComposers(c *gin.Context) {
	var composers []models.Composer

	if err := database.DB.Find(&composers).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to fetch composers"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"composers": composers})
}

func GetComposer(c *gin.Context) {
	uuid, err := uuid.Parse(c.Param("uuid"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid composer ID"})
		return
	}

	var composer models.Composer
	if err := database.DB.First(&composer, uuid).Error; err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "Composer not found"})
		return
	}
	c.JSON(http.StatusOK, composer)
}

func GenerateNonexistentComposerUuid() (*uuid.UUID, error) {
	for i := 0; i < 10; i++ {
		uuid := uuid.New()

		var exists bool
		err := database.DB.Model(&models.Composer{}).
			Select("count(*) > 0").
			Where("uuid = ?", uuid).
			Find(&exists).
			Error

		if err != nil {
			return nil, err
		}

		if !exists {
			return &uuid, nil
		}
	}
	return nil, errors.New("Somehow unable to generate new uuid for sheet.")
}
