<?php

namespace App\Http\Controllers\Market;

use App\Http\Controllers\Controller;
use App\Http\Controllers\FilesMainController;
use App\Http\Controllers\Helpers\Permissions\UserPermissions;
use App\Enums\UserActions;
use Hypervel\Http\Request;
use Hypervel\Support\Facades\Auth;

class ProductPhotoSearchController extends Controller
{
    private const DDG_BROWSER_HEADERS = [
        'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
        'Accept-Language: en-US,en;q=0.9',
        'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
        'Referer: https://duckduckgo.com/',
    ];

    // Step 1: fetch the DDG search page to extract the vqd session token.
    // DDG requires this token to serve the image JSON endpoint.
    private static function getDdgVqd(string $query): ?string
    {
        $url = 'https://duckduckgo.com/?q=' . urlencode($query) . '&iax=images&ia=images';
        $ctx = stream_context_create(['http' => [
            'method'  => 'GET',
            'header'  => implode("\r\n", self::DDG_BROWSER_HEADERS),
            'timeout' => 10,
        ]]);
        $html = @file_get_contents($url, false, $ctx);
        if (!$html) return null;
        // The vqd token appears in the page JS in several formats depending on
        // DDG's current build. Try the quoted forms first (vqd="4-xxx" /
        // vqd='4-xxx' / vqd:"4-xxx"), then fall back to the bare form.
        $patterns = [
            '/vqd=["\']([0-9a-zA-Z._\-]+)["\']/',  // vqd="4-123..." or vqd='4-123...'
            '/vqd["\']?\s*[:=]\s*["\']([0-9a-zA-Z._\-]+)["\']/', // vqd:"4-123..."
            '/vqd=([0-9a-zA-Z._\-]+)/',            // bare vqd=4-123...
        ];
        foreach ($patterns as $pattern) {
            if (preg_match($pattern, $html, $m) && !empty($m[1])) {
                return $m[1];
            }
        }
        return null;
    }

    // GET /api/products/photo-search?q=...&page=1
    public function search(Request $request)
    {
        if (!UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::SearchStockPhotos)) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $query = trim($request->input('q', ''));
        $page  = max(1, (int) $request->input('page', 1));

        if (!$query) {
            return response()->json(['error' => 'Query required'], 422);
        }

        $vqd = self::getDdgVqd($query);
        if (!$vqd) {
            return response()->json(['error' => 'Could not reach image search service'], 502);
        }

        // s = offset; DDG returns ~15 results per call; page 1 = s=0, page 2 = s=15, etc.
        $offset = ($page - 1) * 15;

        $url = 'https://duckduckgo.com/i.js?' . http_build_query([
            'q'   => $query,
            'vqd' => $vqd,
            'o'   => 'json',
            'p'   => '1',
            'f'   => ',,,',
            'l'   => 'us-en',
            's'   => $offset,
        ]);

        $ctx = stream_context_create(['http' => [
            'method'  => 'GET',
            'header'  => implode("\r\n", self::DDG_BROWSER_HEADERS),
            'timeout' => 10,
        ]]);

        $raw = @file_get_contents($url, false, $ctx);
        if ($raw === false) {
            return response()->json(['error' => 'Failed to fetch image results'], 502);
        }

        $data    = json_decode($raw, true);
        $results = $data['results'] ?? [];

        $photos = array_map(fn($r) => [
            'id'    => md5($r['image']),   // stable ID from image URL
            'thumb' => $r['thumbnail'],    // DDG-proxied small thumb (safe to display)
            'src'   => $r['image'],        // actual source image URL (used for download)
            'title' => $r['title'] ?? '',
        ], array_slice($results, 0, 15));

        return response()->json([
            'success'  => true,
            'photos'   => $photos,
            'page'     => $page,
            'has_more' => count($results) >= 15,
        ]);
    }

    // POST /api/products/photo-download
    // body: { src: "https://..." }  — the actual source image URL from DDG results
    public function download(Request $request)
    {
        if (!UserPermissions::isActionPermitted(Auth::user()->acct_type, UserActions::DownloadStockPhoto)) {
            return response()->json(['error' => 'Unauthorized'], 403);
        }

        $src = $request->input('src', '');

        // SSRF guard: must be http/https and must not target private/loopback IPs
        $parsed = parse_url($src);
        $scheme = $parsed['scheme'] ?? '';
        $host   = strtolower($parsed['host'] ?? '');

        if (!in_array($scheme, ['http', 'https']) || !$host) {
            return response()->json(['error' => 'Invalid URL'], 422);
        }

        // Block private/loopback ranges
        if (preg_match('/^(localhost|127\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.|0\.0\.0\.0|::1)/i', $host)) {
            return response()->json(['error' => 'Forbidden URL'], 403);
        }

        $ctx = stream_context_create(['http' => [
            'method'  => 'GET',
            'header'  => 'User-Agent: Mozilla/5.0' . "\r\n",
            'timeout' => 15,
        ]]);
        $raw = @file_get_contents($src, false, $ctx);
        if ($raw === false || strlen($raw) < 500) {
            return response()->json(['error' => 'Failed to fetch image'], 502);
        }

        // Resize to max 1280x720 using PHP GD (bundled — no Intervention Image needed)
        $srcImg = @imagecreatefromstring($raw);
        if (!$srcImg) {
            return response()->json(['error' => 'Invalid image data'], 422);
        }

        $origW = imagesx($srcImg);
        $origH = imagesy($srcImg);
        $maxW  = 1280;
        $maxH  = 720;

        $ratio  = min($maxW / $origW, $maxH / $origH, 1.0); // never upscale
        $newW   = (int) round($origW * $ratio);
        $newH   = (int) round($origH * $ratio);

        $dstImg = imagescale($srcImg, $newW, $newH, IMG_BILINEAR_FIXED);
        imagedestroy($srcImg);

        ob_start();
        imagejpeg($dstImg, null, 85);
        $binary = ob_get_clean();
        imagedestroy($dstImg);

        // Save via existing pipeline — binary string branch in uploadFileContent handles this
        $result = FilesMainController::uploadFileList(
            $binary,
            'stock-photo',
            'stock_photo_' . time() . '.jpg',
            '',
            [],
            'ProductMarket',
            [],
            0,
            'image/jpeg'
        );

        if (!$result || empty($result->hashkey)) {
            return response()->json(['error' => 'Save failed'], 500);
        }

        return response()->json([
            'success' => true,
            'hashkey' => $result->hashkey,
            'url'     => $result->resolvedUrl(),
        ]);
    }
}
