package handlers

import (
	"context"
	"strings"
	"sync"
	"time"

	filemanager "wucher/internal/domain/file_manager"
	"wucher/internal/shared/pkg/metrics"
)

const fileManagerDownloadURLTTL = 15 * time.Minute

type fileManagerDownloadURLStorage interface {
	PresignGetObject(ctx context.Context, objectKey string, ttl time.Duration) (string, error)
}

type fileManagerDownloadURLs struct {
	OriginalURL       string
	ThumbnailURL      string
	PreviewURL        string
	OriginalSizeBytes int64
}

func resolveFileManagerDownloadURLs(ctx context.Context, storage fileManagerDownloadURLStorage, row *filemanager.File) fileManagerDownloadURLs {
	if row == nil {
		return fileManagerDownloadURLs{}
	}

	result := fileManagerDownloadURLs{
		OriginalSizeBytes: row.SizeBytes,
	}
	if storage == nil {
		return result
	}

	var wg sync.WaitGroup

	if key := strings.TrimSpace(row.ObjectKey); key != "" {
		wg.Add(1)
		go func(k string) {
			defer wg.Done()
			presigned, err := storage.PresignGetObject(ctx, k, fileManagerDownloadURLTTL)
			if err == nil && strings.TrimSpace(presigned) != "" {
				result.OriginalURL = presigned
				metrics.ObserveAWSTransferredBytes("api", "s3", "GetObject", "download", row.SizeBytes)
			}
		}(key)
	}

	if row.ThumbnailObjectKey != nil {
		if thumbKey := strings.TrimSpace(*row.ThumbnailObjectKey); thumbKey != "" {
			wg.Add(1)
			go func(tk string) {
				defer wg.Done()
				presigned, err := storage.PresignGetObject(ctx, tk, fileManagerDownloadURLTTL)
				if err == nil && strings.TrimSpace(presigned) != "" {
					result.ThumbnailURL = presigned
					metrics.ObserveAWSTransferredBytes("api", "s3", "GetObject", "download_thumbnail", row.ThumbnailSizeBytes)
				}
			}(thumbKey)
		}
	}

	// Preview URL: for Office docs use the converted preview_object_key;
	// for PDF use the original object key directly (no conversion needed).
	if row.PreviewObjectKey != nil {
		if previewKey := strings.TrimSpace(*row.PreviewObjectKey); previewKey != "" {
			wg.Add(1)
			go func(pk string) {
				defer wg.Done()
				presigned, err := storage.PresignGetObject(ctx, pk, fileManagerDownloadURLTTL)
				if err == nil && strings.TrimSpace(presigned) != "" {
					result.PreviewURL = presigned
					metrics.ObserveAWSTransferredBytes("api", "s3", "GetObject", "download_preview", row.PreviewSizeBytes)
				}
			}(previewKey)
		}
	} else if strings.EqualFold(strings.TrimSpace(row.MimeType), "application/pdf") {
		// PDF files are directly previewable — reuse the original presigned URL.
		// We wait for the original URL goroutine to finish before reading it.
		wg.Wait()
		result.PreviewURL = result.OriginalURL
		return result
	}

	wg.Wait()
	return result
}

func resolveFileManagerDownloadURL(ctx context.Context, storage fileManagerDownloadURLStorage, row *filemanager.File) string {
	return resolveFileManagerDownloadURLs(ctx, storage, row).OriginalURL
}

func resolveFileManagerThumbnailDownloadURL(ctx context.Context, storage fileManagerDownloadURLStorage, row *filemanager.File) string {
	return resolveFileManagerDownloadURLs(ctx, storage, row).ThumbnailURL
}
