<?php

namespace App\Services;

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

class GoogleAiService
{
	protected ?string $apiKey;
	protected ?string $baseUrl;
	protected ?string $imageModel;
	protected ?int $timeout;
	
	public function __construct()
	{
		$this->apiKey = config('google.api_key');
		$this->baseUrl = config('google.base_url');
		$this->imageModel = config('google.image_model');
		$this->timeout = config('google.timeout');
		
		// Debug logging to verify configuration
		Log::info("GoogleAiService initialized", [
			'model' => $this->imageModel,
			'base_url' => $this->baseUrl,
			'timeout' => $this->timeout,
			'has_api_key' => !empty($this->apiKey)
		]);
		
		if (!$this->apiKey) {
			throw new Exception('Google AI API key is not configured');
		}
		
		if (!$this->imageModel) {
			throw new Exception('Google AI image model is not configured');
		}
	}
	
	/**
	 * Generate image using Google Imagen 3
	 */
	public function generateImage(string $prompt, string $imageId): array
	{
		try {
			Log::info("Generating image with Google AI", [
				'prompt'   => $prompt,
				'image_id' => $imageId,
				'model'    => $this->imageModel
			]);
			
			$url = "{$this->baseUrl}/models/{$this->imageModel}:predict";
			
			Log::info("Making Google AI API request", [
				'url' => $url,
				'model' => $this->imageModel,
				'image_id' => $imageId
			]);
			
			$response = Http::timeout($this->timeout)
				->withHeaders([
					'Content-Type'   => 'application/json',
					'x-goog-api-key' => $this->apiKey,
				])
				->post($url, [
					'instances'  => [
						[
							'prompt' => $this->buildImagePrompt($prompt)
						]
					],
					'parameters' => [
						'sampleCount'       => 1,
						'aspectRatio'       => $this->convertAspectRatio(config('google.image_settings.image_config.aspectRatio', 'ASPECT_RATIO_1_1')),
						'safetyFilterLevel' => config('google.image_settings.image_config.safetyFilterLevel', 'FILTER_MEDIUM'),
						'personGeneration'  => config('google.image_settings.image_config.personGeneration', 'DONT_ALLOW')
					]
				]);
			
			if (!$response->successful()) {
				$error = $response->json();
				$statusCode = $response->status();
				$errorMessage = 'Unknown error';
				
				// Extract detailed error message
				if (isset($error['error']['message'])) {
					$errorMessage = $error['error']['message'];
				} elseif (isset($error['message'])) {
					$errorMessage = $error['message'];
				} elseif (is_string($error)) {
					$errorMessage = $error;
				}
				
				Log::error("Google AI API error", [
					'status' => $statusCode,
					'error'  => $error,
					'error_message' => $errorMessage,
					'prompt' => $prompt,
					'model' => $this->imageModel,
					'response_body' => $response->body()
				]);
				
				// Handle specific error types
				if ($statusCode === 400 && stripos($errorMessage, 'model') !== false) {
					throw new Exception("Invalid model '{$this->imageModel}': {$errorMessage}");
				} elseif ($statusCode === 429) {
					throw new Exception("Rate limit exceeded for model '{$this->imageModel}': {$errorMessage}");
				} elseif ($statusCode === 403) {
					throw new Exception("Access denied for model '{$this->imageModel}': {$errorMessage}");
				} else {
					throw new Exception("Google AI API error (status {$statusCode}): {$errorMessage}");
				}
			}
			
			$data = $response->json();
			
			// Log response info (without body để tránh spam log)
			Log::info("Google AI response info", [
				'status_code' => $response->status(),
				'response_size' => strlen($response->body()),
				'has_predictions' => isset($data['predictions']),
				'image_id' => $imageId
			]);
			
			// Check if predictions exist
			if (!isset($data['predictions']) || empty($data['predictions'])) {
				Log::warning("No predictions in Google AI response", [
					'image_id' => $imageId,
					'response_keys' => array_keys($data),
					'full_response' => $data
				]);
				throw new Exception("No predictions in response from Google AI. This might be due to rate limiting or content policy restrictions.");
			}
			
			if (!isset($data['predictions'][0]['bytesBase64Encoded']) || empty($data['predictions'][0]['bytesBase64Encoded'])) {
				$errorDetail = isset($data['predictions'][0]) ? json_encode($data['predictions'][0]) : 'No predictions in response';
				Log::warning("Empty bytesBase64Encoded in prediction", [
					'image_id' => $imageId,
					'prediction_keys' => isset($data['predictions'][0]) ? array_keys($data['predictions'][0]) : [],
					'prediction_data' => $data['predictions'][0] ?? null
				]);
				throw new Exception("No valid image data returned from Google AI. Error details: {$errorDetail}");
			}
			
			// Decode base64 image data
			$base64Data = $data['predictions'][0]['bytesBase64Encoded'];
			$imageData = base64_decode($base64Data);
			
			// Validate decoded image data
			if (empty($imageData) || strlen($imageData) < 1024) {
				throw new Exception("Decoded image data is too small or empty. Base64 length: " . strlen($base64Data));
			}
			
			// Save image to storage
			$filename = $imageId . '.jpg';
			$path = "uploads/ai-images/{$filename}";
			
			Storage::disk('public')->put($path, $imageData);
			
			// Verify the saved file
			$fullPath = storage_path('app/public/' . $path);
			if (!file_exists($fullPath) || filesize($fullPath) < 1024) {
				throw new Exception("Failed to save image or saved image is too small. Path: {$fullPath}");
			}
			
			$url = Storage::disk('public')->url($path);
			
			Log::info("Image generated successfully", [
				'image_id' => $imageId,
				'path'     => $path,
				'url'      => $url
			]);
			
			// Estimate cost
			$costInfo = $this->estimateCost(1);
			
			return [
				'success'      => true,
				'image_id'     => $imageId,
				'image_path'   => $path,
				'image_url'    => $url,
				'prompt'       => $prompt,
				'model'        => $this->imageModel,
				'aspect_ratio' => config('google.image_settings.image_config.aspectRatio'),
				'cost'         => $costInfo['cost_per_image']
			];
			
		} catch (Exception $e) {
			$errorMessage = $e->getMessage();
			$errorContext = [
				'image_id' => $imageId,
				'prompt'   => $prompt,
				'error'    => $errorMessage,
				'model'    => $this->imageModel
			];
			
			// Add more context for specific error types
			if (stripos($errorMessage, 'base64') !== false || stripos($errorMessage, 'empty') !== false) {
				$errorContext['error_type'] = 'empty_response';
				$errorContext['retryable'] = true;
			} elseif (stripos($errorMessage, 'API') !== false) {
				$errorContext['error_type'] = 'api_error';
				$errorContext['retryable'] = true;
			} else {
				$errorContext['error_type'] = 'unknown';
				$errorContext['retryable'] = false;
			}
			
			Log::error("Image generation failed", $errorContext);
			
			return [
				'success'  => false,
				'image_id' => $imageId,
				'error'    => $errorMessage,
				'prompt'   => $prompt,
				'retryable' => $errorContext['retryable'] ?? false
			];
		}
	}
	
	/**
	 * Build optimized prompt for image generation with enhanced clarity and safety
	 */
	private function buildImagePrompt(string $originalPrompt): string
	{
		// Clean and translate the prompt to ensure it's in English
		$safePrompt = $this->makeSafeForImageGeneration($originalPrompt);
		
		// Build enhanced optimized prompt with more specific instructions
		$optimizedPrompt = "Create a high-quality, professional digital illustration depicting: {$safePrompt}. ";
		$optimizedPrompt .= "Style requirements: modern, clean, minimalist flat design with vibrant colors. ";
		$optimizedPrompt .= "Use abstract concepts, infographic elements, diagrams, flowcharts, and visual metaphors. ";
		$optimizedPrompt .= "Ensure clarity and professional appearance suitable for business and educational content. ";
		$optimizedPrompt .= "Avoid any text overlays, specific company logos, personal information, or human faces. ";
		$optimizedPrompt .= "Focus on conceptual visualization with clear, geometric shapes and technical illustrations. ";
		$optimizedPrompt .= "Use a cohesive color palette with high contrast for better visibility.";
		
		return $optimizedPrompt;
	}
	
	/**
	 * Make prompt safe for image generation by replacing potentially flagged terms
	 */
	private function makeSafeForImageGeneration(string $prompt): string
	{
		// Map of potentially problematic terms to safer alternatives
		$replacements = [
			// Business/financial terms that might trigger filters
			'業務効率化' => 'workflow optimization concepts',
			'ROI向上' => 'return on investment visualization', 
			'競争優位性' => 'competitive advantage concepts',
			'リスク管理' => 'risk assessment framework',
			'セキュリティリスク' => 'security framework diagram',
			'ビジネスモデル' => 'business framework diagram',
			'戦略' => 'strategic planning diagram',
			'導入' => 'implementation process',
			'統合' => 'integration concepts',
			
			// Technology terms - make more neutral
			'AI導入' => 'AI implementation concepts',
			'AI活用' => 'AI application scenarios',
			'AI統合' => 'AI integration framework',
			'AI技術' => 'artificial intelligence technology',
			
			// Visual descriptions - make more abstract
			'グラフとダッシュボード' => 'data visualization and analytics dashboard',
			'フローチャート' => 'process flow diagram',
			'インフォグラフィック' => 'information graphics and charts',
			'図解' => 'conceptual diagram',
			'ビジュアル' => 'visual representation',
			'概念図' => 'conceptual framework',
			
			// Industry terms - generalize
			'製造業' => 'manufacturing sector',
			'金融業' => 'financial services',
			'小売業' => 'retail industry', 
			'ヘルスケア' => 'healthcare sector',
		];
		
		$safePrompt = $prompt;
		
		foreach ($replacements as $japanese => $english) {
			$safePrompt = str_replace($japanese, $english, $safePrompt);
		}
		
		// Additional safety improvements
		$safePrompt = str_replace(['図', 'を示す', 'を表現する'], '', $safePrompt);
		$safePrompt = trim(preg_replace('/\s+/', ' ', $safePrompt));
		
		return $safePrompt;
	}
	
	/**
	 * Batch generate multiple images
	 */
	public function batchGenerateImages(array $imageRequests): array
	{
		$results = [];
		
		foreach ($imageRequests as $request) {
			$results[] = $this->generateImage($request['prompt'], $request['image_id']);
			
			// Add small delay between requests to avoid rate limiting
			usleep(500000); // 0.5 seconds
		}
		
		return $results;
	}
	
	/**
	 * Test API connection
	 */
	public function testConnection(): bool
	{
		try {
			$response = Http::timeout(10)
				->get("{$this->baseUrl}/models?key={$this->apiKey}");
			
			return $response->successful();
		} catch (Exception $e) {
			Log::error("Google AI connection test failed", ['error' => $e->getMessage()]);
			return false;
		}
	}
	
	/**
	 * Estimate cost for image generation batch
	 */
	public function estimateCost(int $imageCount): array
	{
		$aspectRatio = config('google.image_settings.image_config.aspectRatio');
		
		// Cost per image based on aspect ratio (approximate pricing)
		$costMapping = [
			'ASPECT_RATIO_1_1'  => 0.040,     // 1024x1024 - Most cost-effective
			'ASPECT_RATIO_16_9' => 0.065,    // 1536x864 - Higher cost
			'ASPECT_RATIO_9_16' => 0.065,    // 864x1536 - Higher cost
			'ASPECT_RATIO_4_3'  => 0.055,     // 1152x896 - Medium cost
			'ASPECT_RATIO_3_4'  => 0.055,     // 896x1152 - Medium cost
		];
		
		$costPerImage = $costMapping[$aspectRatio] ?? 0.040;
		
		$totalCost = $imageCount * $costPerImage;
		
		return [
			'image_count'          => $imageCount,
			'aspect_ratio'         => $aspectRatio,
			'cost_per_image'       => $costPerImage,
			'total_estimated_cost' => round($totalCost, 3),
			'currency'             => 'USD'
		];
	}
	
	/**
	 * Get current aspect ratio configuration
	 */
	public function getCurrentImageConfig(): array
	{
		$aspectRatio = config('google.image_settings.image_config.aspectRatio');
		
		$sizeMapping = [
			'ASPECT_RATIO_1_1'  => ['width' => 1024, 'height' => 1024, 'description' => 'Square (balanced cost/quality)'],
			'ASPECT_RATIO_16_9' => ['width' => 1536, 'height' => 864, 'description' => 'Landscape (premium quality)'],
			'ASPECT_RATIO_9_16' => ['width' => 864, 'height' => 1536, 'description' => 'Portrait (mobile optimized)'],
			'ASPECT_RATIO_4_3'  => ['width' => 1152, 'height' => 896, 'description' => 'Traditional landscape'],
			'ASPECT_RATIO_3_4'  => ['width' => 896, 'height' => 1152, 'description' => 'Traditional portrait'],
		];
		
		$sizeInfo = $sizeMapping[$aspectRatio] ?? ['width' => 1024, 'height' => 1024, 'description' => 'Square (default)'];
		
		return [
			'aspect_ratio'           => $aspectRatio,
			'dimensions'             => "{$sizeInfo['width']}x{$sizeInfo['height']}px",
			'description'            => $sizeInfo['description'],
			'max_images_per_article' => config('google.cost_settings.max_images_per_article', 5)
		];
	}

	/**
	 * Convert aspect ratio from old format to new Google AI format
	 */
	private function convertAspectRatio(string $oldFormat): string
	{
		$mapping = [
			'ASPECT_RATIO_1_1'  => '1:1',
			'ASPECT_RATIO_16_9' => '16:9',
			'ASPECT_RATIO_9_16' => '9:16',
			'ASPECT_RATIO_4_3'  => '4:3',
			'ASPECT_RATIO_3_4'  => '3:4',
		];

		return $mapping[$oldFormat] ?? '1:1';
	}
}