<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Deal;
use App\Models\DealComment;

class DealController extends Controller
{
    public function index(Request $request)
    {
        $activeCategory = $request->query('category', 'all');
        $sort = $request->query('sort', 'hot');

        // Get featured deals (pinned, max 3)
        $featured = Deal::with('user')
            ->withCount('comments')
            ->active()
            ->pinned()
            ->latest()
            ->limit(3)
            ->get();

        // Get main deals (active, non-pinned, filtered by category)
        $dealsQuery = Deal::with('user')
            ->withCount('comments')
            ->active()
            ->where('is_pinned', false)
            ->category($activeCategory);

        if ($sort === 'new') {
            $dealsQuery->orderBy('created_at', 'desc');
        } else {
            // "Hot": highest community score first, freshest as tiebreaker
            $dealsQuery->orderByRaw('(upvotes - downvotes) DESC')
                ->orderBy('created_at', 'desc');
        }

        $deals = $dealsQuery->paginate(15)->appends($request->query());

        // Live hub stats for the hero
        $stats = [
            'deals_this_week' => Deal::active()->where('created_at', '>=', now()->subWeek())->count(),
            'comments_this_week' => DealComment::where('created_at', '>=', now()->subWeek())->count(),
            'store_count' => Deal::active()->whereNotNull('store_name')->where('store_name', '!=', '')->distinct()->count('store_name'),
        ];

        // Per-category counts for the filter pills
        $categoryCounts = Deal::active()
            ->where('is_pinned', false)
            ->selectRaw('category, count(*) as total')
            ->groupBy('category')
            ->pluck('total', 'category');

        return view('deals.index', compact('featured', 'deals', 'activeCategory', 'sort', 'stats', 'categoryCounts'));
    }

    public function show(Deal $deal)
    {
        $deal->load(['user', 'comments.user']);
        
        return view('deals.show', compact('deal'));
    }

    public function create()
    {
        return view('deals.create');
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'description' => 'nullable|string',
            'url' => 'required|url',
            'image_url' => 'nullable|url|max:2048',
            'price' => 'nullable|numeric|min:0',
            'original_price' => 'nullable|numeric|min:0',
            'store_name' => 'nullable|string|max:255',
            'category' => 'nullable|in:new_hardware,software,reverb,used,other',
            'expires_at' => 'nullable|date|after:now',
        ]);

        // Set a default description if not provided
        if (empty($validated['description'])) {
            $validated['description'] = '';
        }

        $validated['user_id'] = auth()->id();

        // Set default category if not provided
        if (empty($validated['category'])) {
            $validated['category'] = 'other';
        }

        $deal = Deal::create($validated);

        return redirect()->route('deals.show', $deal)
            ->with('success', 'Deal submitted successfully!');
    }

    public function addComment(Request $request, Deal $deal)
    {
        $validated = $request->validate([
            'comment' => 'required|string|max:1000'
        ]);

        $deal->comments()->create([
            'user_id' => auth()->id(),
            'comment' => $validated['comment']
        ]);

        return back()->with('success', 'Comment added successfully!');
    }

    public function parseUrl(Request $request)
    {
        $validated = $request->validate([
            'url' => 'required|url',
        ]);

        $url = $validated['url'];
        $data = [];

        try {
            // Fetch with proper headers to appear as a real browser
            $response = \Illuminate\Support\Facades\Http::timeout(10)
                ->withHeaders([
                    'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
                    'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
                    'Accept-Language' => 'en-US,en;q=0.5',
                    'Referer' => 'https://www.google.com/',
                ])
                ->get($url);

            if ($response->successful()) {
                $html = $response->body();

                // Generic Open Graph / JSON-LD parsing works for any store
                $data = $this->parseOpenGraph($html, $url);

                // Reverb-specific parsing fills in anything OG missed
                if (str_contains($url, 'reverb.com')) {
                    $data = array_merge($data, array_filter($this->parseReverbUrl($html, $url)));
                }
            }
        } catch (\Exception $e) {
            // Silently fail - return empty data
            \Log::debug('URL parse error', ['url' => $url, 'error' => $e->getMessage()]);
        }

        return response()->json($data);
    }

    private function parseOpenGraph($html, $url)
    {
        $data = [];

        if ($title = $this->metaContent($html, ['og:title', 'twitter:title'])) {
            $data['title'] = html_entity_decode($title, ENT_QUOTES | ENT_HTML5);
        } elseif (preg_match('~<title[^>]*>(.*?)</title>~is', $html, $m)) {
            $data['title'] = trim(html_entity_decode($m[1], ENT_QUOTES | ENT_HTML5));
        }

        if ($image = $this->metaContent($html, ['og:image', 'og:image:url', 'twitter:image'])) {
            // Resolve protocol-relative and relative image URLs
            if (str_starts_with($image, '//')) {
                $image = 'https:' . $image;
            } elseif (str_starts_with($image, '/')) {
                $parts = parse_url($url);
                $image = ($parts['scheme'] ?? 'https') . '://' . ($parts['host'] ?? '') . $image;
            }
            if (filter_var($image, FILTER_VALIDATE_URL)) {
                $data['image_url'] = $image;
            }
        }

        if ($site = $this->metaContent($html, ['og:site_name'])) {
            $data['store_name'] = html_entity_decode($site, ENT_QUOTES | ENT_HTML5);
        } elseif ($host = parse_url($url, PHP_URL_HOST)) {
            $data['store_name'] = ucfirst(preg_replace('/^www\./', '', $host));
        }

        if ($desc = $this->metaContent($html, ['og:description', 'description'])) {
            $data['description'] = \Illuminate\Support\Str::limit(html_entity_decode($desc, ENT_QUOTES | ENT_HTML5), 500);
        }

        // Price: OG product tags, then JSON-LD offers
        if ($price = $this->metaContent($html, ['product:price:amount', 'og:price:amount'])) {
            $data['price'] = (float) $price;
        } elseif (preg_match('/"price"\s*:\s*"?([\d.]+)"?/i', $html, $m)) {
            $data['price'] = (float) $m[1];
        }

        return $data;
    }

    /**
     * Read a <meta> tag's content by property/name, tolerating either attribute order.
     */
    private function metaContent($html, array $keys)
    {
        foreach ($keys as $key) {
            $key = preg_quote($key, '~');
            if (preg_match('~<meta[^>]+(?:property|name)=["\']' . $key . '["\'][^>]*content=["\']([^"\']+)["\']~i', $html, $m)
                || preg_match('~<meta[^>]+content=["\']([^"\']+)["\'][^>]*(?:property|name)=["\']' . $key . '["\']~i', $html, $m)) {
                $value = trim($m[1]);
                if ($value !== '') {
                    return $value;
                }
            }
        }
        return null;
    }

    private function parseReverbUrl($html, $url)
    {
        $data = [
            'store_name' => 'Reverb',
            'category' => 'reverb',
        ];

        // Extract title from URL slug
        if (preg_match('~reverb\.com/item/\d+-(.+?)(?:$|\?)~', $url, $matches)) {
            $title = str_replace('-', ' ', $matches[1]);
            $data['title'] = ucwords(trim($title));
        }

        // Extract price - try multiple patterns
        // Pattern 1: data-price attribute
        if (preg_match('/data-price="([\d.]+)"/i', $html, $matches)) {
            $data['price'] = (float) $matches[1];
            return $data;
        }

        // Pattern 2: JSON-LD structured data
        if (preg_match('/"price":\s*"?([\d.]+)"?/i', $html, $matches)) {
            $data['price'] = (float) $matches[1];
            return $data;
        }

        // Pattern 3: Look for price in common patterns
        if (preg_match('/\$\s*([0-9,]+(?:\.[0-9]{2})?)/i', $html, $matches)) {
            $price = str_replace(',', '', $matches[1]);
            $data['price'] = (float) $price;
            return $data;
        }

        return $data;
    }

    public function vote(Request $request, Deal $deal)
    {
        $validated = $request->validate([
            'type' => 'required|in:up,down'
        ]);

        if ($validated['type'] === 'up') {
            $deal->increment('upvotes');
        } else {
            $deal->increment('downvotes');
        }

        return response()->json([
            'success' => true,
            'upvotes' => $deal->upvotes,
            'downvotes' => $deal->downvotes
        ]);
    }
}