package youtube

import (
	"fmt"
	"math"
	"regexp"
	"strings"

	"google.golang.org/api/youtube/v3"
)

const (
	twitchYTRegex    = "^https?://www.twitch.tv/yt"
	twitchYTTemplate = "https://www.twitch.tv/yt/%s"
)

func createTwitchPromotion(login string) *youtube.PromotedItem {
	return &youtube.PromotedItem{
		CustomMessage: "I'm live on Twitch, start watching!",
		Id: &youtube.PromotedItemId{
			Type:       "website",
			WebsiteUrl: fmt.Sprintf(twitchYTTemplate, login),
		},
	}
}

func shiftPromotions(items []*youtube.PromotedItem) {
	//previous behaviour was to shift all promotions to start 1s after the twitch promotions if any conflict
	//e.g.
	// 1: <non-twitch> 5s for 5s
	// 2: <non-twitch> 11s for 10s
	// becomes
	// 1: <twitch> 3s for 10s
	// 2: <non-twitch> 14s for 5s
	// 3: <non-twitch> 14s for 10s
	//new behaviour: if any conflict, shift them all back from their original start position
	//e.g.
	// 1: <non-twitch> 5s for 5s
	// 2: <non-twitch> 11s for 10s
	// becomes
	// 1: <twitch> 3s for 10ss
	// 2: <non-twitch> 14s for 5s
	// 3: <non-twitch> 20s for 10s

	twitchEndTime := uint64(promoOffsetMS + promoDurationMS)
	earliestConflictingStartTime := uint64(math.MaxUint64)
	for _, item := range items {
		if item.Timing.Type == offsetFromStartTimingType {
			offset := item.Timing.OffsetMs
			if offset < twitchEndTime && offset < earliestConflictingStartTime {
				earliestConflictingStartTime = offset
			}
		}
	}

	if earliestConflictingStartTime == math.MaxUint64 {
		return
	}

	shiftAmount := twitchEndTime + 1000 - earliestConflictingStartTime
	for _, item := range items {
		if item.Timing.Type == offsetFromStartTimingType {
			item.Timing.OffsetMs += shiftAmount
		}
	}
}

func isTwitchPromotion(item *youtube.PromotedItem) bool {
	if item == nil || item.Id == nil || item.Id.Type != "website" {
		return false
	}
	if match, _ := regexp.MatchString(twitchYTRegex, item.Id.WebsiteUrl); match {
		return true
	}
	return false
}

func twitchAnnotationsEnabled(channel *youtube.Channel) bool {
	if channel == nil || channel.InvideoPromotion == nil {
		return false
	}
	for _, item := range channel.InvideoPromotion.Items {
		if isTwitchPromotion(item) {
			return true
		}
	}
	return false
}

func ShouldIgnoreError(err error) bool {
	// Ignore the following errors from rollbar because we cannot act upon them
	errorsToIgnore := []string{"invalidCustomMessage", "requiredTimingOffset", "unauthorized_client"}
	errMessage := err.Error()

	for _, ignoreErr := range errorsToIgnore {
		if strings.Contains(errMessage, ignoreErr) {
			return true
		}
	}

	return false
}
