// Package adapters provides mediagen provider adapters for various AI services.
package adapters

import (
	"context"
	"fmt"

	"{{GO_MODULE}}/pkg/gemini"
	"{{GO_MODULE}}/pkg/mediagen"
)

// GeminiProvider adapts pkg/gemini to the mediagen interfaces.
type GeminiProvider struct {
	client *gemini.Client
}

// NewGeminiProvider creates a new Gemini provider adapter.
func NewGeminiProvider(client *gemini.Client) *GeminiProvider {
	return &GeminiProvider{client: client}
}

// Name implements mediagen.ImageGenerator and mediagen.VideoGenerator.
func (p *GeminiProvider) Name() string {
	return "gemini"
}

// Health implements mediagen.ImageGenerator and mediagen.VideoGenerator.
func (p *GeminiProvider) Health(ctx context.Context) error {
	if err := p.client.Health(ctx); err != nil {
		return mediagen.NewProviderError("gemini", "Health", err)
	}
	return nil
}

// validImageMIMETypes lists MIME types supported for reference images
var geminiValidImageMIMETypes = map[string]bool{
	"image/png":  true,
	"image/jpeg": true,
	"image/webp": true,
}

// GenerateImage implements mediagen.ImageGenerator.
// Note: Gemini's native image generation currently supports only 1 image per request.
// The Count field is ignored.
func (p *GeminiProvider) GenerateImage(ctx context.Context, req mediagen.ImageRequest) (*mediagen.ImageResponse, error) {
	// Validate reference image MIME type if provided
	if len(req.ReferenceImage) > 0 && req.ReferenceMime != "" {
		if !geminiValidImageMIMETypes[req.ReferenceMime] {
			return nil, fmt.Errorf("unsupported reference image MIME type: %s (supported: image/png, image/jpeg, image/webp)", req.ReferenceMime)
		}
	}

	// Map unified request to Gemini-specific request
	gemReq := gemini.ImageRequest{
		Prompt:         req.Prompt,
		Model:          req.Model,
		Size:           req.Size,
		AspectRatio:    req.AspectRatio,
		ReferenceImage: req.ReferenceImage,
		ReferenceMime:  req.ReferenceMime,
		Seed:           req.Seed,
	}

	// Call Gemini client
	gemResp, err := p.client.GenerateImage(ctx, gemReq)
	if err != nil {
		return nil, mediagen.NewProviderError("gemini", "GenerateImage", err)
	}

	// Convert response to unified format
	images := make([]mediagen.Image, 0, len(gemResp.Images))
	for _, img := range gemResp.Images {
		images = append(images, mediagen.Image{
			Data:     img.Data,
			MimeType: img.MimeType,
		})
	}

	return &mediagen.ImageResponse{
		Images: images,
		Seed:   gemResp.Seed,
	}, nil
}

// GenerateVideo implements mediagen.VideoGenerator.
func (p *GeminiProvider) GenerateVideo(ctx context.Context, req mediagen.VideoRequest) (*mediagen.VideoResponse, error) {
	// Map unified request to Gemini-specific request
	gemReq := gemini.VideoRequest{
		Prompt:      req.Prompt,
		Model:       req.Model,
		AspectRatio: req.AspectRatio,
		Duration:    req.Duration,
	}

	// Convert first reference image if provided
	if len(req.ReferenceImages) > 0 {
		img := req.ReferenceImages[0]
		gemReq.Image = img.Data
		gemReq.ImageMimeType = img.MimeType
	}

	// Call Gemini client
	gemResp, err := p.client.GenerateVideo(ctx, gemReq)
	if err != nil {
		return nil, mediagen.NewProviderError("gemini", "GenerateVideo", err)
	}

	// If video was returned as URI, download it
	var videoData []byte
	var mimeType string
	var url string

	if len(gemResp.Video.Data) > 0 {
		videoData = gemResp.Video.Data
		mimeType = gemResp.Video.MimeType
	}

	if gemResp.Video.URI != "" {
		url = gemResp.Video.URI

		// If we don't have data yet, download from URI
		if len(videoData) == 0 {
			downloaded, downloadErr := downloadVideo(ctx, gemResp.Video.URI)
			if downloadErr != nil {
				// Return URI-only response if download fails (caller can retry download)
				return &mediagen.VideoResponse{
					Videos: []mediagen.Video{
						{
							URL:      url,
							MimeType: "video/mp4",
						},
					},
				}, nil
			}
			videoData = downloaded
			mimeType = "video/mp4"
		}
	}

	if mimeType == "" {
		mimeType = "video/mp4"
	}

	return &mediagen.VideoResponse{
		Videos: []mediagen.Video{
			{
				Data:     videoData,
				MimeType: mimeType,
				URL:      url,
			},
		},
	}, nil
}

// Compile-time interface check
var (
	_ mediagen.ImageGenerator = (*GeminiProvider)(nil)
	_ mediagen.VideoGenerator = (*GeminiProvider)(nil)
)
