package repository

import (
	"strings"

	"hyapp-admin-server/internal/model"
)

type AppBannerListOptions struct {
	AppCode      string
	Keyword      string
	Status       string
	DisplayScope string
	Platform     string
	RegionID     int64
	Country      string
}

func (s *Store) ListAppBanners(options AppBannerListOptions) ([]model.AppBanner, error) {
	var items []model.AppBanner
	query := s.db.Where("app_code = ?", strings.TrimSpace(options.AppCode))
	if options.Status != "" {
		query = query.Where("status = ?", strings.TrimSpace(options.Status))
	}
	if options.DisplayScope != "" {
		query = query.Where("FIND_IN_SET(?, display_scope) > 0", strings.TrimSpace(options.DisplayScope))
	}
	if options.Platform != "" {
		query = query.Where("platform = ?", strings.TrimSpace(options.Platform))
	}
	if options.RegionID > 0 {
		query = query.Where("region_id = ?", options.RegionID)
	}
	if options.Country != "" {
		query = query.Where("country_code = ?", strings.TrimSpace(options.Country))
	}
	if options.Keyword != "" {
		like := "%" + strings.TrimSpace(options.Keyword) + "%"
		query = query.Where("(description LIKE ? OR param LIKE ? OR country_code LIKE ? OR display_scope LIKE ? OR room_small_image_url LIKE ? OR discover_image_url LIKE ?)", like, like, like, like, like, like)
	}
	err := query.Order("sort_order DESC, id DESC").Find(&items).Error
	return items, err
}

func (s *Store) ExpireAppBanners(appCode string, regionID int64, nowMs int64) error {
	appCode = strings.TrimSpace(appCode)
	if appCode == "" || nowMs <= 0 {
		return nil
	}
	// Portal reads carry a server-derived positive region. Keep their implicit
	// expiry maintenance inside that region; region 0 is reserved for the main
	// admin's existing app-wide maintenance behavior.
	query := s.db.Model(&model.AppBanner{}).
		Where("app_code = ? AND status = ? AND ends_at_ms > 0 AND ends_at_ms <= ?", appCode, "active", nowMs)
	if regionID > 0 {
		query = query.Where("region_id = ?", regionID)
	}
	return query.
		Updates(map[string]any{
			"status":        "expired",
			"updated_at_ms": nowMs,
		}).Error
}

func (s *Store) GetAppBanner(appCode string, id uint) (model.AppBanner, error) {
	var item model.AppBanner
	err := s.db.Where("app_code = ? AND id = ?", strings.TrimSpace(appCode), id).First(&item).Error
	return item, err
}

func (s *Store) CreateAppBanner(item *model.AppBanner) error {
	return s.db.Create(item).Error
}

func (s *Store) UpdateAppBanner(item *model.AppBanner) error {
	return s.db.Save(item).Error
}

func (s *Store) DeleteAppBanner(appCode string, id uint) error {
	return s.db.Where("app_code = ? AND id = ?", strings.TrimSpace(appCode), id).Delete(&model.AppBanner{}).Error
}

// DisableActivityTemplateBanners is the admin-side safety net for a template disable/archive.
// It uses the bounded composite target index added by migration 107; no activity or banner table scan is involved.
func (s *Store) DisableActivityTemplateBanners(appCode string, templateID string, nowMS int64) error {
	return s.db.Model(&model.AppBanner{}).
		Where("app_code = ? AND target_type = ? AND activity_template_id = ? AND status = ?",
			strings.TrimSpace(appCode), "activity_template", strings.TrimSpace(templateID), "active").
		Updates(map[string]any{"status": "disabled", "updated_at_ms": nowMS}).Error
}
