package services

import (
	"errors"
	"strings"

	"gauth-central/internal/database"
	"gauth-central/internal/models"

	"gorm.io/gorm"
)

const defaultBannerColor = "#FFFFFF"

type BannerService struct{}

func NewBannerService() *BannerService {
	return &BannerService{}
}

// CreateBanner creates a new banner entry.
func (s *BannerService) CreateBanner(
	color string,
	title string,
	text1 string,
	text2 string,
	text4 string,
	text5 string,
	image string,
	imageK string,
	imageKTxt string,
	isActive bool,
) (*models.Banner, error) {
	color = strings.TrimSpace(color)
	if color == "" {
		color = defaultBannerColor
	}

	banner := models.Banner{
		Color:     color,
		Title:     strings.TrimSpace(title),
		Text1:     strings.TrimSpace(text1),
		Text2:     strings.TrimSpace(text2),
		Text4:     strings.TrimSpace(text4),
		Text5:     strings.TrimSpace(text5),
		Image:     image,
		ImageK:    imageK,
		ImageKTxt: strings.TrimSpace(imageKTxt),
		IsActive:  isActive,
	}

	if err := database.DB.Create(&banner).Error; err != nil {
		return nil, err
	}

	return s.GetBannerByID(banner.ID.String())
}

// GetAllBanners retrieves all banners. Use onlyActive to filter public data.
func (s *BannerService) GetAllBanners(onlyActive bool) ([]models.Banner, error) {
	var banners []models.Banner
	query := database.DB.Order("created_at desc")
	if onlyActive {
		query = query.Where("is_active = ?", true)
	}

	if err := query.Find(&banners).Error; err != nil {
		return nil, err
	}

	return banners, nil
}

// GetFirstActiveBanner returns the newest active banner.
func (s *BannerService) GetFirstActiveBanner() (*models.Banner, error) {
	var banner models.Banner
	if err := database.DB.Where("is_active = ?", true).Order("created_at desc").First(&banner).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("banner not found")
		}
		return nil, err
	}
	return &banner, nil
}

// GetBannerByID retrieves a banner by ID.
func (s *BannerService) GetBannerByID(id string) (*models.Banner, error) {
	var banner models.Banner
	if err := database.DB.Where("id = ?", id).First(&banner).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("banner not found")
		}
		return nil, err
	}
	return &banner, nil
}

// UpdateBanner updates an existing banner entry.
func (s *BannerService) UpdateBanner(
	id string,
	color *string,
	title *string,
	text1 *string,
	text2 *string,
	text4 *string,
	text5 *string,
	image *string,
	imageK *string,
	imageKTxt *string,
	isActive *bool,
) (*models.Banner, error) {
	banner, err := s.GetBannerByID(id)
	if err != nil {
		return nil, err
	}

	updates := map[string]interface{}{}
	if color != nil {
		clean := strings.TrimSpace(*color)
		if clean == "" {
			clean = defaultBannerColor
		}
		updates["color"] = clean
	}
	if title != nil {
		updates["title"] = strings.TrimSpace(*title)
	}
	if text1 != nil {
		updates["text1"] = strings.TrimSpace(*text1)
	}
	if text2 != nil {
		updates["text2"] = strings.TrimSpace(*text2)
	}
	if text4 != nil {
		updates["text4"] = strings.TrimSpace(*text4)
	}
	if text5 != nil {
		updates["text5"] = strings.TrimSpace(*text5)
	}
	if image != nil {
		updates["image"] = *image
	}
	if imageK != nil {
		updates["image_k"] = *imageK
	}
	if imageKTxt != nil {
		updates["image_k_txt"] = strings.TrimSpace(*imageKTxt)
	}
	if isActive != nil {
		updates["is_active"] = *isActive
	}

	if len(updates) > 0 {
		if err := database.DB.Model(banner).Updates(updates).Error; err != nil {
			return nil, err
		}
	}

	return s.GetBannerByID(id)
}

// DeleteBanner deletes a banner by ID.
func (s *BannerService) DeleteBanner(id string) error {
	result := database.DB.Delete(&models.Banner{}, "id = ?", id)
	if result.Error != nil {
		return result.Error
	}
	if result.RowsAffected == 0 {
		return errors.New("banner not found")
	}
	return nil
}
