package feed

import (
	"context"
	"log"
	"sync"
	"time"

	"cloud.google.com/go/firestore"
)

const bucketBaseURL = "https://storage.googleapis.com/reimage-assets"
const cacheTTL = 5 * time.Minute

type FeedItem struct {
	ID          string    `json:"id"             firestore:"-"`
	UID         string    `json:"uid"            firestore:"uid"`
	Name        string    `json:"name"           firestore:"name"`
	Description string    `json:"description"    firestore:"description"`
	Date        time.Time `json:"date"           firestore:"date"`
	Width       int64     `json:"width"          firestore:"width"`
	Height      int64     `json:"height"         firestore:"height"`
	Profile     string    `json:"profile"        firestore:"profile"`
	Images      []string  `json:"images"         firestore:"-"`

	// Firestore-only fields — not serialized in JSON response.
	ImagePaths []string `json:"-"              firestore:"image_paths"`
	Email      string   `json:"email"              firestore:"email"`
}

var (
	cache     map[string][]FeedItem = make(map[string][]FeedItem)
	cacheTime map[string]time.Time  = make(map[string]time.Time)
	cacheMu   sync.RWMutex
)

// GetFeed returns active products with thumbnail and image URLs.
func GetFeed(client *firestore.Client, app string) ([]FeedItem, error) {
	cacheMu.RLock()
	if cache != nil && time.Since(cacheTime[app]) < cacheTTL {
		result := cache[app]
		cacheMu.RUnlock()
		return result, nil
	}
	cacheMu.RUnlock()

	ctx := context.Background()
	docs, err := client.Collection("feed").Where("app", "==", app).OrderBy("date", firestore.Desc).Documents(ctx).GetAll()
	if err != nil {
		// Stale-on-error: return expired cache if available rather than surfacing a 5xx
		cacheMu.RLock()
		stale := cache[app]
		cacheMu.RUnlock()
		if stale != nil {
			log.Printf("Warning: Feed: Firestore error, serving stale cache: %v\n", err)
			return stale, nil
		}
		return nil, err
	}

	feed := make([]FeedItem, 0, len(docs))
	for _, doc := range docs {
		var c FeedItem
		if err := doc.DataTo(&c); err != nil {
			log.Printf("Error: Feed: skip bad doc %s: %v\n", doc.Ref.ID, err)
			continue
		}
		c.ID = doc.Ref.ID
		c.Images = make([]string, 0, len(c.ImagePaths))
		for _, imgPath := range c.ImagePaths {
			c.Images = append(c.Images, bucketBaseURL+"/"+imgPath)
		}
		feed = append(feed, c)
	}

	cacheMu.Lock()
	cache[app] = feed
	cacheTime[app] = time.Now()
	cacheMu.Unlock()

	return feed, nil
}
