package speech

import (
	"context"

	"github.com/flowy-live/llink/internal/utils/flog"

	dgapi "github.com/deepgram/deepgram-go-sdk/v3/pkg/api/listen/v1/rest"
	interfaces "github.com/deepgram/deepgram-go-sdk/v3/pkg/client/interfaces"
	client "github.com/deepgram/deepgram-go-sdk/v3/pkg/client/listen"
)

type TranscriptWord struct {
	Word  string
	Start float64
	End   float64
}

type TranscriptSentence struct {
	Text  string
	Start float64
	End   float64
}

type TranscriptParagraph struct {
	Sentences []TranscriptSentence
	Start     float64
	End       float64
}

type TranscriptResult struct {
	Transcript string
	Words      []TranscriptWord
	Paragraphs []TranscriptParagraph
}

type SpeechService interface {
	Transcribe(ctx context.Context, mediaUrl string) (*TranscriptResult, error)
}

type speechServiceImpl struct {
	deepgramClient *dgapi.Client
}

func NewSpeechService(ctx context.Context) SpeechService {
	return &speechServiceImpl{
		deepgramClient: dgapi.New(client.NewRESTWithDefaults()),
	}
}

func (s *speechServiceImpl) Transcribe(ctx context.Context, mediaUrl string) (*TranscriptResult, error) {
	options := &interfaces.PreRecordedTranscriptionOptions{
		Model:       "nova-3",
		SmartFormat: true,
		Paragraphs:  true,
	}

	response, err := s.deepgramClient.FromURL(ctx, mediaUrl, options)
	if err != nil {
		flog.Error("failed to transcribe prerecorded media", "error", err)
		return nil, err
	}

	alt := response.Results.Channels[0].Alternatives[0]

	words := make([]TranscriptWord, len(alt.Words))
	for i, w := range alt.Words {
		words[i] = TranscriptWord{
			Word:  w.PunctuatedWord,
			Start: w.Start,
			End:   w.End,
		}
	}

	var paragraphs []TranscriptParagraph
	if alt.Paragraphs != nil {
		paragraphs = make([]TranscriptParagraph, len(alt.Paragraphs.Paragraphs))
		for i, p := range alt.Paragraphs.Paragraphs {
			sentences := make([]TranscriptSentence, len(p.Sentences))
			for j, s := range p.Sentences {
				sentences[j] = TranscriptSentence{
					Text:  s.Text,
					Start: s.Start,
					End:   s.End,
				}
			}
			paragraphs[i] = TranscriptParagraph{
				Sentences: sentences,
				Start:     p.Start,
				End:       p.End,
			}
		}
	}

	return &TranscriptResult{
		Transcript: alt.Transcript,
		Words:      words,
		Paragraphs: paragraphs,
	}, nil
}
