package controllers

import (
	database "ares/database/config"
	"ares/database/models"
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"time"

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

// GetSetting godoc
// @Summary Get site settings
// @Tags Setting
// @Produce json
// @Success 200 {object} map[string]interface{}
// @Failure 404 {object} map[string]string
// @Router /api/v1/setting [get]
func GetSetting(c fiber.Ctx) error {
	var setting models.Setting
	// Arkaplanda tek bir aktif ayar varsayıyoruz veya en son ekleneni/güncelleneni
	if err := database.DB.Where("is_active = ?", true).Last(&setting).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			return c.Status(http.StatusNotFound).JSON(fiber.Map{"error": "no active setting found"})
		}
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "database error"})
	}
	return c.JSON(setting)
}

func CreateSetting(c fiber.Ctx) error {
	var setting models.Setting
	if err := c.Bind().Body(&setting); err != nil {
		return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "invalid request body"})
	}

	// White Logo upload
	if file, err := c.FormFile("w_logo"); err == nil {
		if _, err := os.Stat("./uploads/settings"); os.IsNotExist(err) {
			os.MkdirAll("./uploads/settings", 0755)
		}
		filename := fmt.Sprintf("w_%d_%s", time.Now().Unix(), file.Filename)
		filePath := filepath.Join("./uploads/settings", filename)
		if err := c.SaveFile(file, filePath); err != nil {
			return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "failed to save w_logo"})
		}
		setting.WLogo = "/uploads/settings/" + filename
	}

	// Black Logo upload
	if file, err := c.FormFile("b_logo"); err == nil {
		if _, err := os.Stat("./uploads/settings"); os.IsNotExist(err) {
			os.MkdirAll("./uploads/settings", 0755)
		}
		filename := fmt.Sprintf("b_%d_%s", time.Now().Unix(), file.Filename)
		filePath := filepath.Join("./uploads/settings", filename)
		if err := c.SaveFile(file, filePath); err != nil {
			return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "failed to save b_logo"})
		}
		setting.BLogo = "/uploads/settings/" + filename
	}

	// Eğer sadece bir aktif ayar olacaksa, diğerlerini pasife çekebiliriz
	if setting.IsActive {
		database.DB.Model(&models.Setting{}).Where("is_active = ?", true).Update("is_active", false)
	}

	if err := database.DB.Create(&setting).Error; err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "setting could not be created"})
	}

	return c.Status(http.StatusCreated).JSON(setting)
}

func UpdateSetting(c fiber.Ctx) error {
	id, err := strconv.ParseUint(c.Params("id"), 10, 64)
	if err != nil {
		return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "invalid id"})
	}

	var setting models.Setting
	if err := database.DB.First(&setting, id).Error; err != nil {
		return c.Status(http.StatusNotFound).JSON(fiber.Map{"error": "setting not found"})
	}

	var updateData models.Setting
	if err := c.Bind().Body(&updateData); err != nil {
		return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "invalid request body"})
	}

	// White Logo upload
	if file, err := c.FormFile("w_logo"); err == nil {
		if _, err := os.Stat("./uploads/settings"); os.IsNotExist(err) {
			os.MkdirAll("./uploads/settings", 0755)
		}
		filename := fmt.Sprintf("w_%d_%s", time.Now().Unix(), file.Filename)
		filePath := filepath.Join("./uploads/settings", filename)
		if err := c.SaveFile(file, filePath); err != nil {
			return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "failed to save w_logo"})
		}
		updateData.WLogo = "/uploads/settings/" + filename
	}

	// Black Logo upload
	if file, err := c.FormFile("b_logo"); err == nil {
		if _, err := os.Stat("./uploads/settings"); os.IsNotExist(err) {
			os.MkdirAll("./uploads/settings", 0755)
		}
		filename := fmt.Sprintf("b_%d_%s", time.Now().Unix(), file.Filename)
		filePath := filepath.Join("./uploads/settings", filename)
		if err := c.SaveFile(file, filePath); err != nil {
			return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "failed to save b_logo"})
		}
		updateData.BLogo = "/uploads/settings/" + filename
	}

	// Eğer bu ayar aktif yapılıyorsa diğerlerini pasife çek
	if updateData.IsActive {
		database.DB.Model(&models.Setting{}).Where("id != ?", id).Where("is_active = ?", true).Update("is_active", false)
	}

	if err := database.DB.Model(&setting).Updates(updateData).Error; err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "setting could not be updated"})
	}

	return c.JSON(setting)
}

func DeleteSetting(c fiber.Ctx) error {
	id, err := strconv.ParseUint(c.Params("id"), 10, 64)
	if err != nil {
		return c.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "invalid id"})
	}

	var setting models.Setting
	if err := database.DB.First(&setting, id).Error; err != nil {
		return c.Status(http.StatusNotFound).JSON(fiber.Map{"error": "setting not found"})
	}

	if err := database.DB.Delete(&setting).Error; err != nil {
		return c.Status(http.StatusInternalServerError).JSON(fiber.Map{"error": "setting could not be deleted"})
	}

	return c.JSON(fiber.Map{"message": "setting deleted successfully"})
}
