package handlers

import (
	"strings"

	"server/internal/models"

	"github.com/gofiber/fiber/v2"
	"gorm.io/gorm"
)

// GET /api/app-templates
func ListAppTemplatesHandler(db *gorm.DB) fiber.Handler {
	return func(c *fiber.Ctx) error {
		var rows []models.AppTemplate
		if err := db.Order("name asc").Find(&rows).Error; err != nil {
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
		}
		return c.JSON(fiber.Map{"data": rows})
	}
}

// POST /api/app-templates
func CreateAppTemplateHandler(db *gorm.DB) fiber.Handler {
	return func(c *fiber.Ctx) error {
		var req struct {
			Name        string `json:"name"`
			Description string `json:"description"`
			Keywords    string `json:"keywords"`
		}
		if err := c.BodyParser(&req); err != nil {
			return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid payload"})
		}
		name := strings.TrimSpace(req.Name)
		if name == "" {
			return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "name required"})
		}
		keywords := normalizeKeywordCSV(req.Keywords)
		if keywords == "" {
			return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "keywords required"})
		}
		row := models.AppTemplate{
			Name:        name,
			Description: strings.TrimSpace(req.Description),
			Keywords:    keywords,
		}
		if err := db.Create(&row).Error; err != nil {
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
		}
		return c.JSON(fiber.Map{"ok": true, "data": row})
	}
}

// PATCH /api/app-templates/:id
func UpdateAppTemplateHandler(db *gorm.DB) fiber.Handler {
	return func(c *fiber.Ctx) error {
		var row models.AppTemplate
		if err := db.First(&row, c.Params("id")).Error; err != nil {
			return c.Status(fiber.StatusNotFound).JSON(fiber.Map{"error": "not found"})
		}
		var req struct {
			Name        *string `json:"name"`
			Description *string `json:"description"`
			Keywords    *string `json:"keywords"`
		}
		if err := c.BodyParser(&req); err != nil {
			return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "Invalid payload"})
		}
		if req.Name != nil {
			name := strings.TrimSpace(*req.Name)
			if name == "" {
				return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "name required"})
			}
			row.Name = name
		}
		if req.Description != nil {
			row.Description = strings.TrimSpace(*req.Description)
		}
		if req.Keywords != nil {
			keywords := normalizeKeywordCSV(*req.Keywords)
			if keywords == "" {
				return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "keywords required"})
			}
			row.Keywords = keywords
		}
		if err := db.Save(&row).Error; err != nil {
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
		}
		return c.JSON(fiber.Map{"ok": true, "data": row})
	}
}

// DELETE /api/app-templates/:id
func DeleteAppTemplateHandler(db *gorm.DB) fiber.Handler {
	return func(c *fiber.Ctx) error {
		if err := db.Delete(&models.AppTemplate{}, c.Params("id")).Error; err != nil {
			return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{"error": err.Error()})
		}
		return c.JSON(fiber.Map{"ok": true})
	}
}

func normalizeKeywordCSV(raw string) string {
	parts := strings.Split(raw, ",")
	seen := make(map[string]struct{})
	var out []string
	for _, p := range parts {
		kw := strings.ToLower(strings.TrimSpace(p))
		if kw == "" {
			continue
		}
		if _, ok := seen[kw]; ok {
			continue
		}
		seen[kw] = struct{}{}
		out = append(out, kw)
	}
	return strings.Join(out, ", ")
}
