<?php

namespace App\Services;

use Exception;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class GoogleImagenService
{
	private string $apiKey;
	private string $baseUrl;
	private int $timeout;
	
	public function __construct()
	{
		$this->apiKey = config('services.google_ai.api_key');
		$this->baseUrl = 'https://generativelanguage.googleapis.com/v1beta/models';
		$this->timeout = config('services.google_ai.timeout', 300);
	}
	
	/**
	 * Generate images using Google Imagen API
	 *
	 * @param string $prompt
	 * @param int $sampleCount
	 * @return array
	 * @throws Exception
	 */
	public function generateImages(string $prompt, int $sampleCount = 1, string $ratio = '1:1'): array
	{
		$modelName = config('google.image_model');
		
		try {
			$response = Http::timeout($this->timeout)
				->withHeaders([
					'x-goog-api-key' => $this->apiKey,
					'Content-Type'   => 'application/json',
				])
				->post("{$this->baseUrl}/{$modelName}:predict", [
					'instances'  => [
						[
							'prompt' => $prompt
						]
					],
					'parameters' => [
						'sampleCount'      => $sampleCount,
						'numberOfImages'   => 1,
						'aspectRatio'      => $ratio,
						'personGeneration' => 'allow_all'
					]
				]);
			
			if (!$response->successful()) {
				Log::error('Google Imagen API error', [
					'status' => $response->status(),
					'body'   => $response->body(),
					'prompt' => $prompt
				]);
				
				throw new Exception('Failed to generate images: ' . $response->body());
			}
			
			$data = $response->json();
			
			Log::info('Google Imagen API success', [
				'model'         => $modelName,
				'prompt'        => $prompt,
				'sample_count'  => $sampleCount,
				'response_size' => strlen($response->body())
			]);
			
			return $this->processImageResponse($data, $prompt);
			
		} catch (Exception $e) {
			Log::error('Google Imagen Service error', [
				'model'        => $modelName,
				'prompt'       => $prompt,
				'sample_count' => $sampleCount,
				'message'      => $e->getMessage()
			]);
			
			throw $e;
		}
	}
	
	/**
	 * Process the API response and extract image data
	 *
	 * @param array $response
	 * @param string $prompt
	 * @return array
	 */
	private function processImageResponse(array $response, string $prompt): array
	{
		$images = [];
		
		if (isset($response['predictions'])) {
			foreach ($response['predictions'] as $index => $prediction) {
				if (isset($prediction['bytesBase64Encoded'])) {
					$images[] = [
						'index'        => $index,
						'prompt'       => $prompt,
						'base64_data'  => $prediction['bytesBase64Encoded'],
						'mime_type'    => $prediction['mimeType'] ?? 'image/png',
						'generated_at' => now()->toISOString()
					];
				}
			}
		}
		
		return $images;
	}
	
	/**
	 * Save base64 image to storage
	 *
	 * @param string $base64Data
	 * @param string $filename
	 * @param string $disk
	 * @return string
	 */
	public function saveBase64Image(string $base64Data, string $filename, string $disk = 'public'): string
	{
		$imageData = base64_decode($base64Data);
		$path = "uploads/generated/{$filename}";
		
		\Storage::disk($disk)->put($path, $imageData);
		
		return $path;
	}
	
	/**
	 * Generate multiple images in batch
	 *
	 * @param array $prompts
	 * @param int $sampleCount
	 * @return array
	 */
	public function generateBatchImages(array $prompts, int $sampleCount = 1): array
	{
		$results = [];
		
		foreach ($prompts as $index => $prompt) {
			try {
				$images = $this->generateImages($prompt, $sampleCount);
				$results[$index] = [
					'success' => true,
					'prompt'  => $prompt,
					'images'  => $images,
					'count'   => count($images)
				];
			} catch (Exception $e) {
				$results[$index] = [
					'success' => false,
					'prompt'  => $prompt,
					'error'   => $e->getMessage()
				];
			}
		}
		
		return $results;
	}
}