import { GoogleGenAI } from '@google/genai'
import { supabase } from './supabase'
import type { Database } from './supabase'

type WorkoutRow = Database['public']['Tables']['workouts']['Row']

function getAI(): GoogleGenAI {
  const apiKey = process.env['GEMINI_API_KEY']
  if (!apiKey) {
    throw new Error('GEMINI_API_KEY environment variable is not set')
  }
  return new GoogleGenAI({ apiKey })
}

export interface GeneratedImage {
  buffer: Buffer
  mimeType: string
}

export interface VideoGenerationResult {
  workoutId: string
  trainerId: string
  videoUrl: string
  videoPath: string
}

export async function generateTrainerAvatar(
  prompt: string,
  _trainerName: string
): Promise<GeneratedImage[]> {
  const config = {
    imageConfig: {
      aspectRatio: '1:1',
      imageSize: '1K',
      personGeneration: 'ALLOW_ADULT',
    },
    responseModalities: ['IMAGE', 'TEXT'],
  }

  const response = await getAI().models.generateContentStream({
    model: 'gemini-3.1-flash-image-preview',
    config,
    contents: [{ role: 'user', parts: [{ text: prompt }] }],
  })

  const images: GeneratedImage[] = []

  for await (const chunk of response) {
    const parts = chunk.candidates?.[0]?.content?.parts
    if (!parts) continue

    for (const part of parts) {
      if (part.inlineData) {
        images.push({
          buffer: Buffer.from(part.inlineData.data || '', 'base64'),
          mimeType: part.inlineData.mimeType || 'image/png',
        })
      }
    }
  }

  return images
}

export async function saveAvatarToStorage(
  trainerId: string,
  imageBuffer: Buffer,
  filename: string
): Promise<string> {
  const path = `${trainerId}/${filename}`

  const { error } = await supabase.storage
    .from('trainer-avatars')
    .upload(path, imageBuffer, {
      contentType: 'image/png',
      upsert: true,
    })

  if (error) throw new Error(`Failed to upload avatar: ${error.message}`)

  const { data: { publicUrl } } = supabase.storage
    .from('trainer-avatars')
    .getPublicUrl(path)

  return publicUrl
}

export async function generateWorkoutVideo(
  workoutId: string,
  trainerId: string,
  _trainerAvatarUrl: string,
  workoutTitle: string,
  exercises: { name: string; duration: number }[]
): Promise<VideoGenerationResult> {
  const exerciseList = exercises.map(e => e.name).join(', ')

  const prompt = `${workoutTitle}. Exercises: ${exerciseList}. The video must loop seamlessly - start and end in the exact same standing position with arms at sides. Person should appear energetic and properly demonstrate each exercise. 16:9 aspect ratio.`

  const operation = await getAI().models.generateVideos({
    model: 'veo-3.1-fast-generate-preview',
    source: { prompt },
    config: {
      numberOfVideos: 1,
      aspectRatio: '16:9',
      resolution: '1080p',
      personGeneration: 'dont_allow',
      durationSeconds: 8,
    },
  })

  let currentOperation = operation
  while (!currentOperation.done) {
    await new Promise(resolve => setTimeout(resolve, 10000))
    currentOperation = await getAI().operations.getVideosOperation({ operation: currentOperation })
  }

  const videoUri = currentOperation.response?.generatedVideos?.[0]?.video?.uri
  if (!videoUri) throw new Error('No video generated')

  const response = await fetch(`${videoUri}&key=${process.env['GEMINI_API_KEY']}`)
  const arrayBuffer = await response.arrayBuffer()
  const videoBuffer = Buffer.from(arrayBuffer)

  const videoPath = `${trainerId}/${workoutId}.mp4`
  const { error } = await supabase.storage
    .from('trainers-videos')
    .upload(videoPath, videoBuffer, {
      contentType: 'video/mp4',
      upsert: true,
    })

  if (error) throw new Error(`Failed to upload video: ${error.message}`)

  const { data: { publicUrl } } = supabase.storage
    .from('trainers-videos')
    .getPublicUrl(videoPath)

  return { workoutId, trainerId, videoUrl: publicUrl, videoPath }
}

export async function isWorkoutInProgram(_workoutId: string): Promise<boolean> {
  // Legacy program_workouts table removed — workout programs now use program_tabatas
  return false
}

export async function isVideoGeneratedForWorkout(_workoutId: string): Promise<boolean> {
  // Legacy program_workouts table removed — video status tracked in workouts table
  return false
}

export async function getWorkoutVideoStatus(workoutId: string): Promise<{
  hasVideo: boolean
  videoUrl: string | null
  inProgram: boolean
  videoGenerated: boolean
}> {
  const workoutResult = await supabase
    .from('workouts')
    .select('video_url')
    .eq('id', workoutId)
    .single()

  const workoutVideoUrl = (workoutResult.data as WorkoutRow | null)?.video_url ?? null

  return {
    hasVideo: !!workoutVideoUrl,
    videoUrl: workoutVideoUrl,
    inProgram: false,
    videoGenerated: false,
  }
}
