package cache

import (
	"jannex/admin-dashboard-backend/modules/structs"
	"jannex/admin-dashboard-backend/modules/utils"
	"sort"
	"sync"
	"time"
)

var pipelineProductsCache *structs.PipelineProductsCache
var pp sync.RWMutex
var pipelineProductsLastUpdated time.Time // last fetch from google sheets
var ppLU sync.RWMutex
var productsStatesCache []structs.ProductState
var ps sync.RWMutex

func SetPipelineProductsCache(newPipelineProducts structs.PipelineProductsCache) {
	pp.Lock()
	pipelineProductsCache = &newPipelineProducts
	pp.Unlock()
}

/*
func isPipelineProductCached(name string) bool {
	pp.RLock()
	defer pp.RUnlock()

	for _, newProduct := range pipelineProductsCache.NewProducts {
		if newProduct.Name == name {
			return true
		}
	}

	for _, futureProduct := range pipelineProductsCache.FutureProducts {
		if futureProduct.Name == name {
			return true
		}
	}

	for _, inWorkProduct := range pipelineProductsCache.InWorkProducts {
		if inWorkProduct == name {
			return true
		}
	}

	return false
} */

func IsPipelineProductsCacheTimeExpired() bool {
	ppLU.RLock()
	defer ppLU.RUnlock()

	return time.Since(pipelineProductsLastUpdated) > utils.ProductPipelineCacheTime
}

func UpdateProductsPipelineLastCacheUpdate() {
	ppLU.Lock()

	pipelineProductsLastUpdated = time.Now()

	ppLU.Unlock()
}

func GetPipelineProducts() *structs.PipelineProductsCache {
	pp.RLock()
	defer pp.RUnlock()

	return pipelineProductsCache
}

func GetProductsStates() []structs.ProductState {
	ps.RLock()
	defer ps.RUnlock()

	return productsStatesCache
}

func SetProductStates(productStates []structs.ProductState) {
	ps.Lock()
	productsStatesCache = productStates
	ps.Unlock()
}

func IsNameInFutureProducts(name string) bool {
	pipelineProducts := GetPipelineProducts()

	for _, pipelineProduct := range pipelineProducts.FutureProducts {
		if pipelineProduct.Name == name {
			return true
		}
	}

	return false
}

func VoteFutureProduct(name string, up bool) {
	pipelineProducts := GetPipelineProducts()

	for index, futureProduct := range pipelineProducts.FutureProducts {
		if futureProduct.Name == name {
			pp.Lock()

			if up {
				pipelineProductsCache.FutureProducts[index].Votes++
			} else {

				pipelineProductsCache.FutureProducts[index].Votes--
			}

			pp.Unlock()
			break
		}
	}
}

func SortFutureProducts() {
	pipelineProducts := GetPipelineProducts()

	pp.Lock()
	defer pp.Unlock()

	sort.SliceStable(pipelineProducts.FutureProducts, func(i, j int) bool {
		return pipelineProducts.FutureProducts[i].Votes > pipelineProducts.FutureProducts[j].Votes
	})
}
