package services

import (
	"fmt"
	"sort"
	"strings"
)

// HLSPlaylistGenerator génère des playlists HLS au format standard
// T0341: Create HLS Master Playlist Generator
type HLSPlaylistGenerator struct{}

// NewHLSPlaylistGenerator crée un nouveau générateur de playlist HLS
func NewHLSPlaylistGenerator() *HLSPlaylistGenerator {
	return &HLSPlaylistGenerator{}
}

// GenerateMasterPlaylist génère un master playlist HLS avec les variantes de qualité
// bitrates: liste des bitrates en kbps (ex: [128, 192, 320])
// baseURL: URL de base pour les playlists de qualité (ex: "track_123" ou "http://example.com/track_123")
// Retourne le contenu du master playlist au format HLS standard
func (g *HLSPlaylistGenerator) GenerateMasterPlaylist(bitrates []int, baseURL string) string {
	var builder strings.Builder

	// En-tête HLS standard
	builder.WriteString("#EXTM3U\n")
	builder.WriteString("#EXT-X-VERSION:3\n")

	// Trier les bitrates par ordre croissant pour un meilleur streaming adaptatif
	sortedBitrates := make([]int, len(bitrates))
	copy(sortedBitrates, bitrates)
	sort.Ints(sortedBitrates)

	// Générer une entrée pour chaque qualité
	for _, bitrate := range sortedBitrates {
		// Calculer la bandwidth en bits par seconde (bitrate est en kbps)
		bandwidth := bitrate * 1000

		// Format HLS standard: #EXT-X-STREAM-INF:BANDWIDTH={bandwidth}
		// Pour l'audio, on peut aussi ajouter CODECS si nécessaire
		builder.WriteString(fmt.Sprintf("#EXT-X-STREAM-INF:BANDWIDTH=%d\n", bandwidth))

		// URL relative vers le playlist de qualité
		// Format: {baseURL}/{bitrate}k/playlist.m3u8
		builder.WriteString(fmt.Sprintf("%s/%dk/playlist.m3u8\n", baseURL, bitrate))
	}

	return builder.String()
}

// GenerateMasterPlaylistWithCodecs génère un master playlist HLS avec codecs spécifiés
// bitrates: liste des bitrates en kbps
// baseURL: URL de base pour les playlists de qualité
// codec: codec audio (ex: "mp4a.40.2" pour AAC-LC)
// Retourne le contenu du master playlist avec codecs
func (g *HLSPlaylistGenerator) GenerateMasterPlaylistWithCodecs(bitrates []int, baseURL string, codec string) string {
	var builder strings.Builder

	// En-tête HLS standard
	builder.WriteString("#EXTM3U\n")
	builder.WriteString("#EXT-X-VERSION:3\n")

	// Trier les bitrates par ordre croissant
	sortedBitrates := make([]int, len(bitrates))
	copy(sortedBitrates, bitrates)
	sort.Ints(sortedBitrates)

	// Générer une entrée pour chaque qualité avec codec
	for _, bitrate := range sortedBitrates {
		bandwidth := bitrate * 1000

		// Format HLS avec codec: #EXT-X-STREAM-INF:BANDWIDTH={bandwidth},CODECS="{codec}"
		builder.WriteString(fmt.Sprintf("#EXT-X-STREAM-INF:BANDWIDTH=%d,CODECS=\"%s\"\n", bandwidth, codec))

		// URL relative vers le playlist de qualité
		builder.WriteString(fmt.Sprintf("%s/%dk/playlist.m3u8\n", baseURL, bitrate))
	}

	return builder.String()
}

// GenerateQualityPlaylist génère une quality playlist HLS pour une qualité spécifique
// T0342: Create HLS Quality Playlist Generator
// segments: liste des noms de fichiers de segments (ex: ["segment_000.ts", "segment_001.ts"])
// segmentDuration: durée de chaque segment en secondes (ex: 10.0)
// Retourne le contenu de la quality playlist au format HLS standard
func (g *HLSPlaylistGenerator) GenerateQualityPlaylist(segments []string, segmentDuration float64) string {
	var builder strings.Builder

	// En-tête HLS standard
	builder.WriteString("#EXTM3U\n")
	builder.WriteString("#EXT-X-VERSION:3\n")

	// TARGETDURATION: durée maximale d'un segment (arrondie à l'entier supérieur)
	// Format: #EXT-X-TARGETDURATION:{duration}
	targetDuration := int(segmentDuration)
	if segmentDuration > float64(targetDuration) {
		targetDuration++
	}
	builder.WriteString(fmt.Sprintf("#EXT-X-TARGETDURATION:%d\n", targetDuration))

	// MEDIA-SEQUENCE: numéro de séquence du premier segment (0 pour VOD)
	builder.WriteString("#EXT-X-MEDIA-SEQUENCE:0\n")

	// PLAYLIST-TYPE: VOD (Video On Demand) pour les playlists complètes
	builder.WriteString("#EXT-X-PLAYLIST-TYPE:VOD\n")
	builder.WriteString("\n")

	// Ajouter chaque segment avec sa durée
	for _, segment := range segments {
		// Format: #EXTINF:{duration},
		// La durée est en secondes avec 2 décimales
		builder.WriteString(fmt.Sprintf("#EXTINF:%.2f,\n", segmentDuration))
		// Nom du fichier segment
		builder.WriteString(segment + "\n")
	}

	// Marqueur de fin pour les playlists VOD
	builder.WriteString("#EXT-X-ENDLIST\n")

	return builder.String()
}

// GenerateQualityPlaylistWithVariableDurations génère une quality playlist avec durées variables par segment
// segments: liste des segments avec leurs durées respectives
// Retourne le contenu de la quality playlist au format HLS standard
func (g *HLSPlaylistGenerator) GenerateQualityPlaylistWithVariableDurations(segments []SegmentInfo) string {
	if len(segments) == 0 {
		return "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-ENDLIST\n"
	}

	var builder strings.Builder

	// En-tête HLS standard
	builder.WriteString("#EXTM3U\n")
	builder.WriteString("#EXT-X-VERSION:3\n")

	// Calculer la durée maximale pour TARGETDURATION
	maxDuration := 0.0
	for _, seg := range segments {
		if seg.Duration > maxDuration {
			maxDuration = seg.Duration
		}
	}
	targetDuration := int(maxDuration)
	if maxDuration > float64(targetDuration) {
		targetDuration++
	}
	builder.WriteString(fmt.Sprintf("#EXT-X-TARGETDURATION:%d\n", targetDuration))

	// MEDIA-SEQUENCE: numéro de séquence du premier segment
	builder.WriteString("#EXT-X-MEDIA-SEQUENCE:0\n")

	// PLAYLIST-TYPE: VOD
	builder.WriteString("#EXT-X-PLAYLIST-TYPE:VOD\n")
	builder.WriteString("\n")

	// Ajouter chaque segment avec sa durée spécifique
	for _, seg := range segments {
		builder.WriteString(fmt.Sprintf("#EXTINF:%.2f,\n", seg.Duration))
		builder.WriteString(seg.Filename + "\n")
	}

	// Marqueur de fin
	builder.WriteString("#EXT-X-ENDLIST\n")

	return builder.String()
}

// SegmentInfo représente un segment avec sa durée
type SegmentInfo struct {
	Filename string
	Duration float64
}
