<?php

namespace App\Services;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use App\Core\Config;
use App\Helpers\Logger;

class ImageService
{
    public const DEFAULT_FREEPIK_PROMPT_TEMPLATE = 'Professional blog header image about {topic_name}: {article_title}, high quality, photorealistic';

    private Client $client;

    public function __construct()
    {
        $this->client = new Client(['timeout' => 60]);
    }

    public function generate(string $articleTitle, string $topicName): ?array
    {
        $provider = Config::getDbSetting('image_provider', 'freepik');

        return match ($provider) {
            'freepik' => $this->generateFreepik($articleTitle, $topicName),
            'unsplash' => $this->searchUnsplash($topicName),
            'pexels' => $this->searchPexels($topicName),
            default => $this->searchPexels($topicName),
        };
    }

    private function generateFreepik(string $articleTitle, string $topicName): ?array
    {
        $apiKey = Config::getDbSetting('freepik_api_key', Config::get('FREEPIK_API_KEY'));
        $promptTemplate = Config::getDbSetting('image_generation_prompt', self::DEFAULT_FREEPIK_PROMPT_TEMPLATE);

        if (!is_string($promptTemplate) || trim($promptTemplate) === '') {
            $promptTemplate = self::DEFAULT_FREEPIK_PROMPT_TEMPLATE;
        }

        if (empty($apiKey)) {
            Logger::warning('Freepik API key not configured, falling back to Pexels', 'image');
            return $this->searchPexels($topicName);
        }

        try {
            $prompt = strtr($promptTemplate, [
                '{topic_name}' => $topicName,
                '{article_title}' => $articleTitle,
            ]);

            $response = $this->client->post('https://api.freepik.com/v1/ai/text-to-image', [
                'headers' => [
                    'x-freepik-api-key' => $apiKey,
                    'Content-Type' => 'application/json',
                ],
                'json' => [
                    'prompt' => $prompt,
                    'negative_prompt' => 'text, watermark, logo, blurry, low quality',
                    'image' => ['size' => 'landscape_16_9'],
                ],
            ]);

            $data = json_decode($response->getBody()->getContents(), true);

            if (!empty($data['data'][0]['base64'])) {
                $imageData = base64_decode($data['data'][0]['base64']);
                return [
                    'data' => $imageData,
                    'filename' => 'article-' . time() . '.jpg',
                    'mime' => 'image/jpeg',
                ];
            }

            Logger::error('Freepik returned empty image data', 'image');
            return null;
        } catch (GuzzleException $e) {
            Logger::error('Freepik API error: ' . $e->getMessage(), 'image');
            return $this->searchPexels($topicName);
        }
    }

    private function searchUnsplash(string $query): ?array
    {
        $apiKey = Config::getDbSetting('unsplash_api_key', Config::get('UNSPLASH_API_KEY'));

        if (empty($apiKey)) {
            Logger::warning('Unsplash API key not configured', 'image');
            return null;
        }

        try {
            $response = $this->client->get('https://api.unsplash.com/search/photos', [
                'headers' => ['Authorization' => "Client-ID {$apiKey}"],
                'query' => [
                    'query' => $query,
                    'orientation' => 'landscape',
                    'per_page' => 5,
                ],
            ]);

            $data = json_decode($response->getBody()->getContents(), true);
            $results = $data['results'] ?? [];

            if (empty($results)) {
                return null;
            }

            $photo = $results[array_rand($results)];
            $imageUrl = $photo['urls']['regular'] ?? null;

            if (!$imageUrl) {
                return null;
            }

            $imageData = $this->client->get($imageUrl)->getBody()->getContents();

            return [
                'data' => $imageData,
                'filename' => 'article-' . time() . '.jpg',
                'mime' => 'image/jpeg',
            ];
        } catch (GuzzleException $e) {
            Logger::error('Unsplash API error: ' . $e->getMessage(), 'image');
            return null;
        }
    }

    private function searchPexels(string $query): ?array
    {
        $apiKey = Config::getDbSetting('pexels_api_key', Config::get('PEXELS_API_KEY'));

        if (empty($apiKey)) {
            Logger::warning('Pexels API key not configured', 'image');
            return null;
        }

        try {
            $response = $this->client->get('https://api.pexels.com/v1/search', [
                'headers' => ['Authorization' => $apiKey],
                'query' => [
                    'query' => $query,
                    'orientation' => 'landscape',
                    'per_page' => 5,
                ],
            ]);

            $data = json_decode($response->getBody()->getContents(), true);
            $photos = $data['photos'] ?? [];

            if (empty($photos)) {
                return null;
            }

            $photo = $photos[array_rand($photos)];
            $imageUrl = $photo['src']['large'] ?? $photo['src']['original'] ?? null;

            if (!$imageUrl) {
                return null;
            }

            $imageData = $this->client->get($imageUrl)->getBody()->getContents();

            return [
                'data' => $imageData,
                'filename' => 'article-' . time() . '.jpg',
                'mime' => 'image/jpeg',
            ];
        } catch (GuzzleException $e) {
            Logger::error('Pexels API error: ' . $e->getMessage(), 'image');
            return null;
        }
    }
}
