<?php
class ControllerToolOpenAIImage extends Controller {

    /** @var string|null */
    private $apiKey = null;

    public function index() {
        $this->load->language('tool/openai_image');
        $this->document->setTitle('OpenAI Image Variations (URL)');

        // API key
        $this->apiKey = $this->config->get('openai_api_key');
        if (!$this->apiKey) {
            $this->session->data['error'] = 'OpenAI API anahtarı bulunamadı.';
        }

        if ($this->request->server['REQUEST_METHOD'] == 'POST' && !empty($this->request->post['image_url'])) {
            try {
                // Bu form varyasyon üretmek içindi; prompt YOK olmalı (variations için).
                // Eğer düzenleme (edit) yapmak istiyorsan, editImageFromUrl kullan.
                $url  = trim($this->request->post['image_url']);
                $size = $this->request->post['size'] ?? '1024x1024';
                $n    = (int)($this->request->post['n'] ?? 1);

                // Varyasyon yerine düzenleme istiyorsan şunu kullan:
                // $prompt = trim($this->request->post['prompt'] ?? '');
                // $result = $this->editImageFromUrl($url, $prompt, null, $size);

                $results = $this->createVariationFromUrl($url, $size, $n, 'gpt-image-1');

                $saved = [];
                foreach ($results as $i => $b64) {
                    $targetDir = DIR_IMAGE . 'generated/';
                    if (!is_dir($targetDir)) {
                        @mkdir($targetDir, 0755, true);
                    }
                    $target = $targetDir . 'oa_var_' . date('Ymd_His') . '_' . ($i+1) . '.png';
                    $this->saveBase64Png($b64, $target);
                    $saved[] = 'generated/' . basename($target);
                }

                $this->session->data['success'] = 'Üretildi: ' . implode(', ', $saved);
                $this->response->redirect($this->url->link('tool/openai_image', 'user_token=' . $this->session->data['user_token'], true));
                return;

            } catch (Exception $e) {
                $this->session->data['error'] = $e->getMessage();
                $this->response->redirect($this->url->link('tool/openai_image', 'user_token=' . $this->session->data['user_token'], true));
                return;
            }
        }

        $data['header']      = $this->load->controller('common/header');
        $data['column_left'] = $this->load->controller('common/column_left');
        $data['footer']      = $this->load->controller('common/footer');
        $data['action']      = $this->url->link('tool/openai_image', 'user_token=' . $this->session->data['user_token'], true);
        $data['error']       = $this->session->data['error'] ?? '';
        $data['success']     = $this->session->data['success'] ?? '';
        unset($this->session->data['error'], $this->session->data['success']);

        $this->response->setOutput($this->load->view('tool/openai_image_form', $data));
    }

    /**
     * Hızlı test: URL'den EDIT (prompt ile düzenleme) yapar.
     * NOT: Üretimde anahtarı config'ten alıyoruz; hardcode yok.
     */
    public function test() {
        $apiKey = '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';

        $this->apiKey = $apiKey;
        if (!$this->apiKey) {
            throw new Exception('OpenAI API anahtarı bulunamadı.');
        }

        $image_url = 'https://cdn.dsmcdn.com//ty1613/prod/QC/20241215/20/0922c403-f59d-3fba-913f-dd2ab641f577/1_org_zoom.jpg';
        $prompt    = 'Görselde filigran, yazı, marka vb. unsurları kaldır; temiz ve doğal görünüm sağla.';
        $size      = '1024x1024';

        $result = $this->editImageFromUrl($image_url, $prompt, null, $size);
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($result, JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
        exit;
    }

    /* ====================== Yardımcılar ====================== */

    // URL'den indirir → tmp dosyaya yazar → path/mime döndürür.
    private function downloadToTemp(string $url): array {
        if (!filter_var($url, FILTER_VALIDATE_URL)) {
            throw new \Exception('Geçersiz URL: ' . $url);
        }

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_MAXREDIRS      => 5,
            CURLOPT_CONNECTTIMEOUT => 10,
            CURLOPT_TIMEOUT        => 30,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_SSL_VERIFYHOST => 2,
            CURLOPT_USERAGENT      => 'Mozilla/5.0 (OpenAIImageFetcher)'
        ]);
        $data = curl_exec($ch);
        $err  = curl_error($ch);
        $code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
        $ctype= curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
        curl_close($ch);

        if ($err)  throw new \Exception('İndirme hatası: ' . $err);
        if ($code < 200 || $code >= 300 || !$data) {
            throw new \Exception('Görsel indirilemedi. HTTP=' . $code);
        }

        if (strlen($data) > 10 * 1024 * 1024) {
            throw new \Exception('Dosya çok büyük (>10MB).');
        }

        $tmp = tempnam(sys_get_temp_dir(), 'img_');
        if ($tmp === false) throw new \Exception('Geçici dosya oluşturulamadı.');
        if (file_put_contents($tmp, $data) === false) {
            @unlink($tmp);
            throw new \Exception('Geçici dosyaya yazılamadı.');
        }

        // MIME tespiti (finfo)
        $mime = null;
        if (function_exists('finfo_open')) {
            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            if ($finfo) {
                $mime = finfo_file($finfo, $tmp);
                finfo_close($finfo);
            }
        }
        if (!$mime && $ctype) {
            $semi = strpos($ctype, ';');
            $mime = $semi !== false ? trim(substr($ctype, 0, $semi)) : trim($ctype);
        }
        if (!$mime) $mime = 'image/jpeg';

        // Uzantı
        $ext = '.jpg';
        if (stripos($mime, 'png') !== false)  $ext = '.png';
        if (stripos($mime, 'webp') !== false) $ext = '.webp';

        $tmpWithExt = $tmp . $ext;
        @rename($tmp, $tmpWithExt);

        return ['path' => $tmpWithExt, 'mime' => $mime];
    }

    // Base64 → PNG kaydet
    private function saveBase64Png(string $b64, string $target): void {
        $data = preg_replace('#^data:image/\w+;base64,#i', '', $b64);
        $bin  = base64_decode($data);
        if ($bin === false) throw new \Exception('Base64 decode başarısız.');
        $dir = dirname($target);
        if (!is_dir($dir)) @mkdir($dir, 0755, true);
        if (file_put_contents($target, $bin) === false) {
            throw new \Exception('Dosya kaydedilemedi: ' . $target);
        }
    }

    /* ================== OpenAI Çağrıları =================== */

    /**
     * URL'den görsel indir → variations (PROMPT YOK!)
     * @return string[] base64 listesi
     */
    private function createVariationFromUrl(string $imageUrl, string $size = '1024x1024', int $n = 1, string $model = 'gpt-image-1'): array {
        if (!$this->apiKey) throw new \Exception('API anahtarı yok.');

        $dl = $this->downloadToTemp($imageUrl);
        try {
            $endpoint = 'https://api.openai.com/v1/images/variations';
            $payload = [
                'model' => $model,
                'n'     => $n,
                'size'  => $size,
                'image' => new CURLFile($dl['path'], $dl['mime'], basename($dl['path'])),
            ];

            $ch = curl_init($endpoint);
            curl_setopt_array($ch, [
                CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $this->apiKey],
                CURLOPT_POST           => true,
                CURLOPT_POSTFIELDS     => $payload,    // multipart/form-data
                CURLOPT_RETURNTRANSFER => true,
            ]);
            $res = curl_exec($ch);
            $err = curl_error($ch);
            curl_close($ch);

            if ($err) throw new \Exception('cURL error: ' . $err);
            $json = json_decode($res, true);
            if (isset($json['error'])) {
                throw new \Exception('OpenAI API error: ' . ($json['error']['message'] ?? $res));
            }

            // API genelde: data[n].b64_json
            $out = [];
            if (!empty($json['data'])) {
                foreach ($json['data'] as $row) {
                    if (!empty($row['b64_json'])) $out[] = $row['b64_json'];
                }
            }
            return $out;

        } finally {
            if (isset($dl['path']) && is_file($dl['path'])) @unlink($dl['path']);
        }
    }

    /**
     * URL → indir → edit (prompt ile düzenleme)
     */
    private function editImageFromUrl(string $imageUrl, string $prompt, ?string $maskUrl = null, string $size='1024x1024') {
        if (!$this->apiKey) throw new \Exception('API anahtarı yok.');

        $dl = $this->downloadToTemp($imageUrl);
        $maskPath = null;

        try {
            if ($maskUrl) {
                $dlMask = $this->downloadToTemp($maskUrl);
                $maskPath = $dlMask['path'];
            }
            return $this->editImageLocal($dl['path'], $prompt, $maskPath, $size);

        } finally {
            if (isset($dl['path']) && is_file($dl['path'])) @unlink($dl['path']);
            if ($maskPath && is_file($maskPath)) @unlink($maskPath);
        }
    }

    /**
     * LOCAL dosya ile edit çağrısı
     */
    private function editImageLocal(string $imagePath, string $prompt, ?string $maskPath = null, string $size='1024x1024') {
        if (!$this->apiKey) throw new \Exception('API anahtarı yok.');

        $endpoint = 'https://api.openai.com/v1/images/edits';

        // mime tespiti güvenli
        $mime = function_exists('finfo_open') ? (function() use($imagePath) {
            $f = finfo_open(FILEINFO_MIME_TYPE);
            if ($f) { $m = finfo_file($f, $imagePath); finfo_close($f); return $m ?: 'image/jpeg'; }
            return 'image/jpeg';
        })() : 'image/jpeg';

        $payload = [
            'model'  => 'gpt-image-1',
            'prompt' => $prompt,
            'size'   => $size,
            'image'  => new CURLFile($imagePath, $mime, basename($imagePath)),
        ];
        if ($maskPath) {
            $maskMime = 'image/png';
            if (function_exists('finfo_open')) {
                $f = finfo_open(FILEINFO_MIME_TYPE);
                if ($f) { $mm = finfo_file($f, $maskPath); finfo_close($f); if ($mm) $maskMime = $mm; }
            }
            $payload['mask'] = new CURLFile($maskPath, $maskMime, basename($maskPath));
        }

        $ch = curl_init($endpoint);
        curl_setopt_array($ch, [
            CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $this->apiKey],
            CURLOPT_POST           => true,
            CURLOPT_POSTFIELDS     => $payload,     // multipart/form-data
            CURLOPT_RETURNTRANSFER => true,
        ]);
        $res = curl_exec($ch);
        $err = curl_error($ch);
        curl_close($ch);

        if ($err) throw new \Exception('cURL error: ' . $err);
        $json = json_decode($res, true);
        if (isset($json['error'])) throw new \Exception('OpenAI API error: ' . ($json['error']['message'] ?? $res));
        return $json;
    }
}
