<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Item;
use App\Models\Category;
use App\Models\Manufacturer;
use App\Models\ItemPhoto;
use App\Models\BuyQueue;
use App\Models\Watchlist;
use App\Models\Transaction;
use App\Models\Conversation;
use App\Models\Message;
use App\Models\User;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;

class ItemController extends Controller
{
    public function index(Request $request)
    {
        $query = Item::with(['user', 'category', 'primaryPhoto'])
            ->whereIn('status', ['active', 'sale_pending'])
            ->whereIn('listing_type', ['sale', 'inventory_open'])
            ->whereHas('user', function($q) {
                $q->where('is_active', true);
            })
            ->withCount('watchlists as watchers_count');

        // Exclude flagged items unless user is admin
        if (!auth()->check() || !auth()->user()->is_admin) {
            $query->where('status', '!=', 'flagged');
        }

        // Filter by category
        if ($request->filled('category')) {
            $query->where('category_id', $request->category);
        }

        // Filter by manufacturer
        if ($request->filled('manufacturer')) {
            $query->where('manufacturer_id', $request->manufacturer);
        }

        // Filter by model
        if ($request->filled('model')) {
            $query->where('model', $request->model);
        }

        // Filter by listing type
        if ($request->filled('type')) {
            $query->where('listing_type', $request->type);
        }

        // Search
        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('title', 'like', "%{$search}%")
                  ->orWhere('description', 'like', "%{$search}%")
                  ->orWhere('model', 'like', "%{$search}%");
            });
        }

        // Price range
        if ($request->filled('min_price')) {
            $query->where('price', '>=', $request->min_price);
        }
        if ($request->filled('max_price')) {
            $query->where('price', '<=', $request->max_price);
        }

        // Location
        if ($request->filled('location')) {
            $location = $request->location;
            $query->where(function($q) use ($location) {
                $q->where('location_city', 'like', "%{$location}%")
                  ->orWhere('location_state', 'like', "%{$location}%");
            });
        }

        // Prioritize items with photos FIRST (primary sort) — pointless in the
        // text-only simple view, where photos aren't shown
        if ($request->attributes->get('ui_mode') !== 'simple') {
            $query->orderByRaw('EXISTS(SELECT 1 FROM item_photos WHERE item_photos.item_id = items.id) DESC');
        }

        // Sort (secondary sort, after photo priority)
        $sortBy = $request->get('sort', 'newest');
        switch ($sortBy) {
            case 'price_low':
                $query->orderBy('price', 'asc');
                break;
            case 'price_high':
                $query->orderBy('price', 'desc');
                break;
            case 'oldest':
                $query->orderBy('created_at', 'asc');
                break;
            default:
                $query->orderBy('created_at', 'desc');
        }

        $items = $query->paginate(12)->withQueryString();
        $categories = Category::where('is_active', true)->orderBy('name')->get();

        return view('items.index', compact('items', 'categories'));
    }

    public function show(Item $item)
    {
        // Check if this is a private inventory item and user is not the owner
        if ($item->listing_type === 'inventory' && (!auth()->check() || $item->user_id !== auth()->id())) {
            abort(404);
        }

        $item->load(['user', 'category', 'manufacturer', 'photos', 'buyQueue.user']);
        $item->increment('views');

        // Track user interaction
        \App\Models\UserInteraction::track($item->id, 'view', [
            'referrer' => request()->header('referer'),
            'user_agent' => request()->header('user-agent')
        ]);

        $relatedItems = Item::with(['primaryPhoto'])
            ->where('category_id', $item->category_id)
            ->where('id', '!=', $item->id)
            ->whereIn('status', ['active', 'sale_pending'])
            ->whereIn('listing_type', ['sale', 'inventory_open'])
            ->take(4)
            ->get();

        $userInQueue = auth()->check() ? 
            $item->buyQueue()->where('user_id', auth()->id())->first() : null;

        $isWatching = auth()->check() ?
            $item->watchlists()->where('user_id', auth()->id())->exists() : false;

        $watchersCount = $item->watchlists()->count();

        // Check if user has an active offer on this item
        $userOffer = auth()->check() ?
            $item->offers()->where('buyer_id', auth()->id())->active()->first() : null;

        return view('items.show', compact('item', 'relatedItems', 'userInQueue', 'isWatching', 'watchersCount', 'userOffer'));
    }

    public function create()
    {
        $categories = Category::where('is_active', true)->orderBy('name')->get();
        $manufacturers = Manufacturer::where('is_active', true)->orderBy('name')->get();
        
        return view('items.create-wizard', compact('categories', 'manufacturers'));
    }

    public function createClassic()
    {
        $categories = Category::where('is_active', true)->orderBy('name')->get();
        $manufacturers = Manufacturer::where('is_active', true)->orderBy('name')->get();
        
        return view('items.create', compact('categories', 'manufacturers'));
    }

    public function store(Request $request)
    {
        $isDraft = $request->has('save_as_draft') || $request->input('action') === 'draft';
        
        // Different validation rules for drafts vs published items
        if ($isDraft) {
            $validated = $request->validate([
                'title' => 'nullable|string|max:255',
                'description' => 'nullable|string',
                'category_id' => 'nullable|exists:categories,id',
                'manufacturer_id' => 'nullable|exists:manufacturers,id',
                'model' => 'nullable|string|max:255',
                'serial_number' => 'nullable|string|max:255',
                'year' => 'nullable|integer|min:1900|max:' . date('Y'),
                'condition' => 'nullable|string',
                'price' => 'nullable|numeric|min:0',
                'quantity' => 'nullable|integer|min:1',
                'listing_type' => 'nullable|in:sale,inventory,inventory_open',
                'open_to_trades' => 'boolean',
                'offers_enabled' => 'boolean',
                'local_meetup_only' => 'boolean',
                'shipping_mode' => 'nullable|in:free,fixed,buyer_pays',
                'shipping_cost' => 'nullable|numeric|min:0',
                'photos' => 'nullable|array',
                'photos.*' => 'image|mimes:jpeg,png,jpg,gif|max:2048'
            ]);
        } else {
            $validated = $request->validate([
                'title' => 'required|string|max:255',
                'description' => 'required|string',
                'category_id' => 'nullable|exists:categories,id',
                'manufacturer_id' => 'nullable|exists:manufacturers,id',
                'model' => 'nullable|string|max:255',
                'serial_number' => 'nullable|string|max:255',
                'year' => 'nullable|integer|min:1900|max:' . date('Y'),
                'condition' => 'required|string',
                'price' => 'nullable|numeric|min:0',
                'quantity' => 'required|integer|min:1',
                'listing_type' => 'required|in:sale,inventory,inventory_open',
                'open_to_trades' => 'boolean',
                'offers_enabled' => 'boolean',
                'local_meetup_only' => 'boolean',
                'shipping_mode' => 'nullable|in:free,fixed,buyer_pays',
                'shipping_cost' => 'nullable|numeric|min:0',
                'photos' => 'required|array|min:1',
                'photos.*' => 'image|mimes:jpeg,png,jpg,gif|max:2048'
            ]);
        }

        $validated['user_id'] = auth()->id();
        $validated['status'] = $isDraft ? 'draft' : 'active';
        $validated['location_country'] = 'US';

        // Map local_meetup_only to database fields
        $localMeetupOnly = $validated['local_meetup_only'] ?? false;
        $validated['shipping_available'] = !$localMeetupOnly;
        $validated['local_pickup'] = true; // Always allow local pickup
        unset($validated['local_meetup_only']);

        // Map shipping_mode to shipping_cost and shipping_buyer_pays
        $shippingMode = $validated['shipping_mode'] ?? 'free';
        if ($shippingMode === 'free') {
            $validated['shipping_cost'] = null;
            $validated['shipping_buyer_pays'] = false;
        } elseif ($shippingMode === 'fixed') {
            $validated['shipping_cost'] = $validated['shipping_cost'] ?? null;
            $validated['shipping_buyer_pays'] = false;
        } elseif ($shippingMode === 'buyer_pays') {
            $validated['shipping_cost'] = null;
            $validated['shipping_buyer_pays'] = true;
        }
        unset($validated['shipping_mode']);

        $item = Item::create($validated);

        // Handle photo uploads
        if ($request->hasFile('photos')) {
            foreach ($request->file('photos') as $index => $photo) {
                $this->storePhoto($item, $photo, $index === 0);
            }
        }

        $message = $isDraft ? 'Draft saved successfully!' : 'Item listed successfully!';
        $route = $isDraft ? 'items.my-drafts' : 'items.show';
        $param = $isDraft ? [] : [$item];

        return redirect()->route($route, ...$param)
            ->with('success', $message);
    }

    public function edit(Item $item)
    {
        // Check if user can edit this item (owner or admin)
        if ($item->user_id !== auth()->id() && !auth()->user()->is_admin) {
            abort(403, 'You can only edit your own items.');
        }
        
        // Load photos for the edit view
        $item->load('photos');
        
        $categories = Category::where('is_active', true)->orderBy('name')->get();
        $manufacturers = Manufacturer::where('is_active', true)->orderBy('name')->get();
        
        return view('items.edit', compact('item', 'categories', 'manufacturers'));
    }

    public function update(Request $request, Item $item)
    {
        // Check if user can update this item (owner or admin)
        if ($item->user_id !== auth()->id() && !auth()->user()->is_admin) {
            abort(403, 'You can only edit your own items.');
        }

        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'description' => 'required|string',
            'category_id' => 'nullable|exists:categories,id',
            'manufacturer_id' => 'nullable|exists:manufacturers,id',
            'model' => 'nullable|string|max:255',
            'serial_number' => 'nullable|string|max:255',
            'year' => 'nullable|integer|min:1900|max:' . date('Y'),
            'condition' => 'required|string',
            'price' => 'nullable|numeric|min:0',
            'quantity' => 'required|integer|min:1',
            'listing_type' => 'required|in:sale,inventory,inventory_open',
            'open_to_trades' => 'boolean',
            'local_meetup_only' => 'boolean',
            'shipping_mode' => 'nullable|in:free,fixed,buyer_pays',
            'shipping_cost' => 'nullable|numeric|min:0',
            'photos' => 'nullable|array',
            'photos.*' => 'image|mimes:jpeg,png,jpg,gif|max:2048'
        ]);

        // Map local_meetup_only to database fields
        $localMeetupOnly = $validated['local_meetup_only'] ?? false;
        $validated['shipping_available'] = !$localMeetupOnly;
        $validated['local_pickup'] = true; // Always allow local pickup
        unset($validated['local_meetup_only']);

        // Map shipping_mode to shipping_cost and shipping_buyer_pays
        $shippingMode = $validated['shipping_mode'] ?? 'free';
        if ($shippingMode === 'free') {
            $validated['shipping_cost'] = null;
            $validated['shipping_buyer_pays'] = false;
        } elseif ($shippingMode === 'fixed') {
            $validated['shipping_cost'] = $validated['shipping_cost'] ?? null;
            $validated['shipping_buyer_pays'] = false;
        } elseif ($shippingMode === 'buyer_pays') {
            $validated['shipping_cost'] = null;
            $validated['shipping_buyer_pays'] = true;
        }
        unset($validated['shipping_mode']);

        // Remove photos from validated data for item update
        $photos = $validated['photos'] ?? [];
        unset($validated['photos']);

        $item->update($validated);

        // Handle new photo uploads
        if (!empty($photos)) {
            foreach ($photos as $index => $photo) {
                $this->storePhoto($item, $photo, $index === 0 && $item->photos()->count() === 0);
            }
        }

        return redirect()->route('items.show', $item)
            ->with('success', 'Item updated successfully!');
    }

    public function destroy(Item $item)
    {
        // Check if user can delete this item (owner or admin)
        if ($item->user_id !== auth()->id() && !auth()->user()->is_admin) {
            abort(403, 'You can only delete your own items.');
        }
        
        // Delete photos
        foreach ($item->photos as $photo) {
            Storage::disk('images')->delete($photo->path);
            $photo->delete();
        }
        
        $item->delete();

        return redirect()->route('items.my-listings')
            ->with('success', 'Item deleted successfully!');
    }

    public function checkout(Item $item)
    {
        if ($item->user_id === auth()->id()) {
            return redirect()->route('items.show', $item)->with('error', 'You cannot buy your own item.');
        }

        if (!in_array($item->listing_type, ['sale', 'inventory_open'])) {
            return redirect()->route('items.show', $item)->with('error', 'This item is not available for purchase.');
        }

        if (!in_array($item->status, ['active', 'sale_pending'])) {
            return redirect()->route('items.show', $item)->with('error', 'This item is no longer available.');
        }

        // Check if user is already in queue
        $existingQueue = BuyQueue::where('item_id', $item->id)
            ->where('user_id', auth()->id())
            ->first();

        // Load buy queue to determine status
        $buyQueue = BuyQueue::where('item_id', $item->id)
            ->with('user')
            ->orderBy('position')
            ->get();

        $isPrimary = $buyQueue->isEmpty();
        $userPosition = null;
        
        if ($existingQueue) {
            $userPosition = $existingQueue->position;
        }

        return view('items.checkout', compact('item', 'buyQueue', 'isPrimary', 'userPosition', 'existingQueue'));
    }

    public function buy(Item $item)
    {
        if ($item->user_id === auth()->id()) {
            return back()->with('error', 'You cannot buy your own item.');
        }

        if (!in_array($item->listing_type, ['sale', 'inventory_open'])) {
            return back()->with('error', 'This item is not available for purchase.');
        }

        if (!in_array($item->status, ['active', 'sale_pending'])) {
            return redirect()->route('items.show', $item)->with('error', 'This item is no longer available.');
        }

        // Check if user is already in queue
        $existingQueue = BuyQueue::where('item_id', $item->id)
            ->where('user_id', auth()->id())
            ->first();

        if ($existingQueue) {
            return back()->with('error', 'You are already in the queue for this item.');
        }

        // Lock the item's queue rows so concurrent buyers can't both claim the
        // same position (backed by the unique index on item_id + position)
        $nextPosition = DB::transaction(function () use ($item) {
            $position = BuyQueue::where('item_id', $item->id)
                ->lockForUpdate()
                ->max('position') + 1;

            BuyQueue::create([
                'item_id' => $item->id,
                'user_id' => auth()->id(),
                'position' => $position,
                'status' => 'pending'
            ]);

            return $position;
        });

        // Track buy interest
        \App\Models\UserInteraction::track($item->id, 'buy_interest', [
            'position' => $nextPosition
        ]);

        // Update item status if this is the first buyer
        if ($nextPosition === 1) {
            $item->update(['status' => 'sale_pending']);
        }

        // Notify the seller
        $item->user->notify(new \App\Notifications\BuyerInterest($item, auth()->user(), $nextPosition));

        $message = $nextPosition === 1 ?
            'You are now the primary buyer! The seller will contact you to arrange payment and delivery.' :
            "You are backup buyer #" . ($nextPosition - 1) . ". You'll be contacted if the primary sale falls through.";

        return redirect()->route('items.show', $item)->with('success', $message);
    }

    public function leaveQueue(Item $item)
    {
        $entry = BuyQueue::where('item_id', $item->id)
            ->where('user_id', auth()->id())
            ->first();

        if (!$entry) {
            return redirect()->route('items.show', $item)->with('error', 'You are not in the queue for this item.');
        }

        $wasPrimary = $entry->position === 1;
        DB::transaction(function () use ($entry, $item, $wasPrimary) {
            $entry->delete();
            $this->resequenceQueue($item, notifyNewPrimary: $wasPrimary);
        });

        $item->user->notify(new \App\Notifications\BuyerLeftQueue($item, auth()->user(), $wasPrimary));

        return redirect()->route('items.show', $item)->with('success', 'You have withdrawn from the buy queue.');
    }

    public function removeFromQueue(Item $item, User $user)
    {
        if ($item->user_id !== auth()->id()) {
            abort(403, 'You can only manage queues for your own items.');
        }

        $entry = BuyQueue::where('item_id', $item->id)
            ->where('user_id', $user->id)
            ->first();

        if (!$entry) {
            return back()->with('error', 'That buyer is not in the queue.');
        }

        $wasPrimary = $entry->position === 1;
        DB::transaction(function () use ($entry, $item, $wasPrimary) {
            $entry->delete();
            $this->resequenceQueue($item, notifyNewPrimary: $wasPrimary);
        });

        $user->notify(new \App\Notifications\RemovedFromQueue($item));

        return back()->with('success', "{$user->name} has been removed from the queue.");
    }

    /**
     * Renumber queue positions to 1..n after a removal. Promotes (and
     * optionally notifies) the new primary buyer, and returns the item to
     * active status when the queue empties.
     */
    private function resequenceQueue(Item $item, bool $notifyNewPrimary = false)
    {
        $remaining = BuyQueue::where('item_id', $item->id)
            ->orderBy('position')
            ->get();

        foreach ($remaining as $index => $queueEntry) {
            if ($queueEntry->position !== $index + 1) {
                $queueEntry->update(['position' => $index + 1]);
            }
        }

        if ($remaining->isEmpty()) {
            if ($item->status === 'sale_pending') {
                $item->update(['status' => 'active']);
            }
        } elseif ($notifyNewPrimary) {
            $remaining->first()->user->notify(new \App\Notifications\PromotedToPrimaryBuyer($item));
        }
    }

    public function myListings()
    {
        // Get live listings (non-draft)
        $liveItems = auth()->user()->items()
            ->with(['category', 'primaryPhoto', 'buyQueue'])
            ->where('status', '!=', 'draft')
            ->latest()
            ->get();

        // Get draft items
        $draftItems = auth()->user()->items()
            ->with(['category', 'primaryPhoto'])
            ->where('status', 'draft')
            ->latest()
            ->get();

        return view('items.my-listings', compact('liveItems', 'draftItems'));
    }

    public function myInventory()
    {
        $items = auth()->user()->items()
            ->with(['category', 'primaryPhoto'])
            ->where('listing_type', 'inventory')
            ->latest()
            ->paginate(12);

        return view('items.my-inventory', compact('items'));
    }

    public function myDrafts()
    {
        $items = auth()->user()->items()
            ->with(['category', 'primaryPhoto'])
            ->where('status', 'draft')
            ->latest()
            ->paginate(12);

        return view('items.my-drafts', compact('items'));
    }

    public function publishDraft(Item $item)
    {
        // Check if user can publish this item (owner or admin)
        if ($item->user_id !== auth()->id() && !auth()->user()->is_admin) {
            abort(403, 'You can only publish your own drafts.');
        }

        // Check if item is actually a draft
        if ($item->status !== 'draft') {
            return back()->with('error', 'This item is not a draft.');
        }

        // Validate that the draft has all required fields for publishing
        $requiredFields = ['title', 'description', 'condition', 'listing_type'];
        foreach ($requiredFields as $field) {
            if (empty($item->{$field})) {
                return back()->with('error', "Cannot publish: {$field} is required.");
            }
        }

        // Check if photos are required and present
        if ($item->photos()->count() === 0) {
            return back()->with('error', 'Cannot publish: At least one photo is required.');
        }

        // Update status to active
        $item->update(['status' => 'active']);

        return redirect()->route('items.show', $item)
            ->with('success', 'Draft published successfully!');
    }

    public function myPurchases()
    {
        $buyQueue = auth()->user()->buyQueue()
            ->with(['item.primaryPhoto', 'item.user'])
            ->latest()
            ->paginate(12);

        return view('items.my-purchases', compact('buyQueue'));
    }

    public function mySales()
    {
        $transactions = auth()->user()->soldTransactions()
            ->with(['item.primaryPhoto', 'buyer'])
            ->latest()
            ->paginate(12);

        return view('items.my-sales', compact('transactions'));
    }

    public function uploadPhoto(Request $request, Item $item)
    {
        // Check if user can upload photos for this item (owner or admin)
        if ($item->user_id !== auth()->id() && !auth()->user()->is_admin) {
            abort(403, 'You can only upload photos for your own items.');
        }

        $request->validate([
            'photo' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048'
        ]);

        $isFirst = $item->photos()->count() === 0;
        $this->storePhoto($item, $request->file('photo'), $isFirst);

        return back()->with('success', 'Photo uploaded successfully!');
    }

    public function deletePhoto(Item $item, ItemPhoto $photo)
    {
        // Check if user can delete photos for this item (owner or admin)
        if ($item->user_id !== auth()->id() && !auth()->user()->is_admin) {
            abort(403, 'You can only delete photos for your own items.');
        }

        if ($photo->item_id !== $item->id) {
            abort(403);
        }

        Storage::disk('images')->delete($photo->path);
        $photo->delete();

        return back()->with('success', 'Photo deleted successfully!');
    }

    private function storePhoto(Item $item, $file, $isPrimary = false)
    {
        $filename = Str::uuid() . '.' . $file->extension();
        $path = $file->storeAs('items', $filename, 'images');
        
        return ItemPhoto::create([
            'item_id' => $item->id,
            'filename' => $filename,
            'original_name' => $file->getClientOriginalName(),
            'path' => $path,
            'url' => Storage::disk('images')->url($path),
            'file_size' => $file->getSize(),
            'mime_type' => $file->getMimeType(),
            'sort_order' => $item->photos()->count(),
            'is_primary' => $isPrimary
        ]);
    }

    public function addToWatchlist(Item $item)
    {
        if ($item->user_id === auth()->id()) {
            if (request()->wantsJson()) {
                return response()->json(['success' => false, 'message' => 'You cannot watch your own item.']);
            }
            return back()->with('error', 'You cannot watch your own item.');
        }

        $existingWatch = Watchlist::where('user_id', auth()->id())
            ->where('item_id', $item->id)
            ->first();

        if ($existingWatch) {
            if (request()->wantsJson()) {
                return response()->json(['success' => false, 'message' => 'Item is already in your watchlist.']);
            }
            return back()->with('error', 'Item is already in your watchlist.');
        }

        Watchlist::create([
            'user_id' => auth()->id(),
            'item_id' => $item->id
        ]);

        // Track watchlist interaction
        \App\Models\UserInteraction::track($item->id, 'watchlist_add');

        if (request()->wantsJson()) {
            return response()->json(['success' => true, 'message' => 'Item added to your watchlist!']);
        }
        return back()->with('success', 'Item added to your watchlist!');
    }

    public function removeFromWatchlist(Item $item)
    {
        $watchlist = Watchlist::where('user_id', auth()->id())
            ->where('item_id', $item->id)
            ->first();

        if ($watchlist) {
            $watchlist->delete();
            if (request()->wantsJson()) {
                return response()->json(['success' => true, 'message' => 'Item removed from your watchlist.']);
            }
            return back()->with('success', 'Item removed from your watchlist.');
        }

        if (request()->wantsJson()) {
            return response()->json(['success' => false, 'message' => 'Item is not in your watchlist.']);
        }
        return back()->with('error', 'Item is not in your watchlist.');
    }

    public function myWatchlist()
    {
        $watchlist = auth()->user()->watchlist()
            ->with(['item.category', 'item.primaryPhoto', 'item.user'])
            ->whereHas('item', function($query) {
                $query->whereIn('status', ['active', 'sale_pending']);
            })
            ->latest()
            ->paginate(12);

        return view('items.my-watchlist', compact('watchlist'));
    }

    public function manageQueue(Item $item)
    {
        // Ensure user owns this item
        if ($item->user_id !== auth()->id()) {
            abort(403, 'You can only manage queues for your own items.');
        }

        $item->load(['buyQueue.user', 'category']);

        return view('items.manage-queue', compact('item'));
    }

    public function markSold(Request $request, Item $item)
    {
        // Ensure user owns this item
        if ($item->user_id !== auth()->id()) {
            abort(403, 'You can only mark your own items as sold.');
        }

        $validated = $request->validate([
            'buyer_id' => 'required|exists:users,id',
            'final_price' => 'required|numeric|min:0'
        ]);

        // Verify the buyer is in the queue
        $buyerInQueue = BuyQueue::where('item_id', $item->id)
            ->where('user_id', $validated['buyer_id'])
            ->first();

        if (!$buyerInQueue) {
            return back()->with('error', 'Selected buyer is not in the queue for this item.');
        }

        try {
            DB::beginTransaction();

            // Create transaction
            $transaction = Transaction::create([
                'item_id' => $item->id,
                'seller_id' => $item->user_id,
                'buyer_id' => $validated['buyer_id'],
                'price' => $validated['final_price'],
                'status' => 'pending',
                'type' => 'sale',
                'auto_close_at' => now()->addWeeks(2),
            ]);

            $remainingStock = ($item->quantity ?? 1) - 1;

            if ($remainingStock > 0) {
                // Units remain: decrement stock, drop only the winning buyer
                // from the queue, and keep the listing live for the rest
                $wasPrimary = $buyerInQueue->position === 1;
                $buyerInQueue->delete();
                $this->resequenceQueue($item, notifyNewPrimary: $wasPrimary);

                $hasQueue = BuyQueue::where('item_id', $item->id)->exists();
                $item->update([
                    'quantity' => $remainingStock,
                    'status' => $hasQueue ? 'sale_pending' : 'active',
                ]);
            } else {
                // Last unit: close out the listing
                $item->update(['status' => 'sold']);

                // Get all backup buyers (exclude the selected buyer)
                $backupBuyers = BuyQueue::where('item_id', $item->id)
                    ->where('user_id', '!=', $validated['buyer_id'])
                    ->with('user')
                    ->get();

                // Send messages to backup buyers
                foreach ($backupBuyers as $backup) {
                    $this->sendBackupBuyerNotification($item, $backup->user);
                }

                // Notify all watchers that item has been sold
                // TODO: Enable this feature in the future
                // $watchers = $item->watchlists()->with('user')->get();
                // foreach ($watchers as $watchlist) {
                //     $watchlist->user->notify(new \App\Notifications\ItemSold($item));
                // }

                // Remove all buy queue entries
                BuyQueue::where('item_id', $item->id)->delete();
            }

            DB::commit();

            // Tell the winning buyer the sale is official (after commit so the
            // queued mail never references a rolled-back transaction)
            $transaction->buyer->notify(new \App\Notifications\PurchaseConfirmed($transaction));

            return redirect()->route('transactions.show', $transaction)
                ->with('success', 'Item marked as sold! Transaction created.');

        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Failed to process sale. Please try again.');
        }
    }

    private function sendBackupBuyerNotification(Item $item, User $buyer)
    {
        // Create conversation with backup buyer to notify them
        $conversation = Conversation::create([
            'item_id' => $item->id,
            'subject' => "Item Sold: {$item->title}",
            'last_message_at' => now(),
        ]);

        // Add participants
        $conversation->participants()->attach([
            $item->user_id => ['last_read_at' => now()],
            $buyer->id => ['last_read_at' => null],
        ]);

        // Create notification message
        Message::create([
            'conversation_id' => $conversation->id,
            'user_id' => $item->user_id,
            'body' => "Hello {$buyer->name},\n\nUnfortunately, the item \"{$item->title}\" you were interested in has been sold to another buyer. Thank you for your interest!\n\nBest regards,\n{$item->user->name}",
        ]);
    }

    public function storeCategory(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255|unique:categories,name',
        ]);

        $category = Category::create([
            'name' => $validated['name'],
            'slug' => \Str::slug($validated['name']),
            'is_active' => true,
            'sort_order' => Category::max('sort_order') + 1
        ]);

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

    public function storeManufacturer(Request $request)
    {
        $validated = $request->validate([
            'name' => 'required|string|max:255|unique:manufacturers,name',
        ]);

        $manufacturer = Manufacturer::create([
            'name' => $validated['name'],
            'slug' => \Str::slug($validated['name']),
            'is_active' => true
        ]);

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

    public function massListing()
    {
        return view('items.mass-listing');
    }

    public function storeMassListing(Request $request)
    {
        $validated = $request->validate([
            'items_text' => 'required|string|min:10'
        ]);

        $itemsText = $validated['items_text'];
        $parsedItems = $this->parseItemsText($itemsText);

        if (empty($parsedItems)) {
            return back()
                ->withInput()
                ->withErrors(['items_text' => 'No items could be parsed. Expected format: "Item Name - $Price" or "$Price - Item Name" (one per line or separated by blank lines).']);
        }

        // Store parsed items in session for review
        session(['parsed_items' => $parsedItems]);

        return redirect()->route('items.review-mass-listing-quick');
    }

    public function reviewMassListing()
    {
        $parsedItems = session('parsed_items', []);
        
        if (empty($parsedItems)) {
            return redirect()->route('items.mass-listing')
                ->with('error', 'No items found to review. Please paste your listings first.');
        }

        $categories = Category::where('is_active', true)->orderBy('name')->get();
        $manufacturers = Manufacturer::where('is_active', true)->orderBy('name')->get();

        return view('items.review-mass-listing', compact('parsedItems', 'categories', 'manufacturers'));
    }

    public function createAllDrafts(Request $request)
    {
        $parsedItems = session('parsed_items', []);
        
        if (empty($parsedItems)) {
            return response()->json(['success' => false, 'message' => 'No items found to create']);
        }

        $created = 0;
        foreach ($parsedItems as $itemData) {
            $item = Item::create([
                'user_id' => auth()->id(),
                'title' => $itemData['title'],
                'description' => $itemData['description'],
                'price' => $itemData['price'],
                'manufacturer' => $itemData['manufacturer'],
                'model' => $itemData['model'],
                'quantity' => $itemData['quantity'],
                'listing_type' => $itemData['listing_type'],
                'condition' => $itemData['condition'],
                'open_to_trades' => $itemData['open_to_trades'],
                'shipping_available' => $itemData['shipping_available'],
                'local_pickup' => $itemData['local_pickup'],
                'status' => 'draft',
                'location_country' => 'US'
            ]);
            $created++;
        }

        // Clear the session
        session()->forget('parsed_items');

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

    public function reviewMassListingQuick()
    {
        $parsedItems = session('parsed_items', []);

        if (empty($parsedItems)) {
            return redirect()->route('items.mass-listing')
                ->with('error', 'No items found to review. Please paste your listings first.');
        }

        $categories = Category::where('is_active', true)->orderBy('name')->get();

        return view('items.review-mass-listing-quick', compact('parsedItems', 'categories'));
    }

    public function createAllLive(Request $request)
    {
        $validated = $request->validate([
            'status' => 'required|in:draft,active',
            'items' => 'required|array|min:1|max:100',
            'items.*.title' => 'required|string|max:255',
            'items.*.price' => 'required|numeric|min:0|max:999999',
            'items.*.description' => 'nullable|string|max:10000',
            'items.*.condition' => 'required|in:New,Like New,Excellent,Very Good,Good,Fair,Poor',
            'items.*.quantity' => 'nullable|integer|min:1|max:999',
            'items.*.category_id' => 'nullable|exists:categories,id',
        ]);

        $created = 0;
        DB::transaction(function () use ($validated, &$created) {
            foreach ($validated['items'] as $itemData) {
                Item::create([
                    'user_id' => auth()->id(),
                    'title' => $itemData['title'],
                    'description' => $itemData['description'] ?? '',
                    'price' => $itemData['price'],
                    'condition' => $itemData['condition'],
                    'quantity' => $itemData['quantity'] ?? 1,
                    'category_id' => $itemData['category_id'] ?? null,
                    'listing_type' => 'sale',
                    'open_to_trades' => false,
                    'shipping_available' => true,
                    'local_pickup' => true,
                    'status' => $validated['status'],
                    'location_country' => 'US',
                ]);
                $created++;
            }
        });

        session()->forget('parsed_items');

        $noun = $created === 1 ? 'listing' : 'listings';
        session()->flash('success', $validated['status'] === 'draft'
            ? "{$created} {$noun} saved as drafts. Add photos and publish when ready."
            : "{$created} {$noun} published.");

        return response()->json([
            'success' => true,
            'created' => $created,
            'redirect' => $validated['status'] === 'draft'
                ? route('items.my-drafts')
                : route('items.my-listings'),
        ]);
    }

    private function parseItemsText($text)
    {
        $items = [];
        $lines = explode("\n", trim($text));

        // A line is an item header if it matches any of these patterns:
        // - "$price - title"
        // - "title - $price"
        // - "$price title" (price at start)
        // - "title $price" (price at end)
        $isHeader = fn(string $line): bool => (bool) preg_match(
            '/^\$\d+(?:\.\d{2})?\s*-\s*.+$|' .           // $price - title
            '^.+\s*-\s*\$\d+(?:\.\d{2})?$|' .            // title - $price
            '^\$\d+(?:\.\d{2})?\s+.+$|' .                // $price title
            '^.+?\s+\$\d+(?:\.\d{2})?$/',                // title $price
            trim($line)
        );

        $blocks = [];
        $current = [];

        foreach ($lines as $line) {
            if ($isHeader($line) && !empty($current)) {
                $blocks[] = implode("\n", $current);
                $current = [];
            }
            $current[] = $line;
        }
        if (!empty($current)) {
            $blocks[] = implode("\n", $current);
        }

        foreach ($blocks as $block) {
            $block = trim($block);
            if (empty($block)) continue;

            $item = $this->parseItemBlock($block);
            if ($item) {
                $items[] = $item;
            }
        }

        return $items;
    }

    private function parseItemBlock($block)
    {
        $lines = explode("\n", $block);
        $firstLine = trim($lines[0]);

        $price = null;
        $title = null;

        // 1. Try "$price - Title" format
        if (preg_match('/^\$(\d+(?:\.\d{2})?)\s*-\s*(.+)$/', $firstLine, $matches)) {
            $price = (float) $matches[1];
            $title = trim($matches[2]);
        }
        // 2. Try "Title - $price" format
        elseif (preg_match('/^(.+?)\s*-\s*\$(\d+(?:\.\d{2})?)/', $firstLine, $matches)) {
            $title = trim($matches[1]);
            $price = (float) $matches[2];
        }
        // 3. Try line starts with $price (no dash required)
        elseif (preg_match('/^\$(\d+(?:\.\d{2})?)\s+(.+)$/', $firstLine, $matches)) {
            $price = (float) $matches[1];
            $title = trim($matches[2]);
        }
        // 4. Try line ends with $price (no dash required)
        elseif (preg_match('/^(.+?)\s+\$(\d+(?:\.\d{2})?)$/', $firstLine, $matches)) {
            $title = trim($matches[1]);
            $price = (float) $matches[2];
        }
        // 5. If we still don't have a price, just use the whole line as title
        else {
            $title = $firstLine;
            // Try to extract price from any line in the description
            if (count($lines) > 1) {
                for ($i = 1; $i < count($lines); $i++) {
                    $line = trim($lines[$i]);
                    if (preg_match('/\$(\d+(?:\.\d{2})?)/', $line, $matches)) {
                        $price = (float) $matches[1];
                        break;
                    }
                }
            }
        }

        // If we couldn't extract a price, we can't create an item
        if ($price === null) {
            return null;
        }

        // Extract description (everything after the first line)
        $description = '';
        if (count($lines) > 1) {
            $descriptionLines = array_slice($lines, 1);
            $description = trim(implode("\n", $descriptionLines));
        }

        // Note: no manufacturer/model guessing here — earlier heuristics produced
        // unreliable values ('manufacturer' isn't even a DB column), so sellers
        // set those on the edit form where they can pick from real records.
        return [
            'title' => $title,
            'description' => $description,
            'price' => $price,
            'manufacturer' => null,
            'model' => null,
            'quantity' => 1,
            'listing_type' => 'sale',
            'condition' => 'Good',
            'open_to_trades' => false,
            'shipping_available' => true,
            'local_pickup' => true
        ];
    }

    // API endpoints for AJAX requests
    public function apiStoreCategory(Request $request)
    {
        try {
            $validated = $request->validate([
                'name' => 'required|string|max:255|unique:categories,name',
            ]);
            
            $category = Category::create([
                'name' => $validated['name'],
                'slug' => \Str::slug($validated['name']),
                'is_active' => true,
                'sort_order' => Category::max('sort_order') + 1,
                'created_by' => auth()->id()
            ]);
            
            return response()->json([
                'success' => true,
                'category' => $category
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 422);
        }
    }

    public function apiStoreManufacturer(Request $request)
    {
        try {
            $validated = $request->validate([
                'name' => 'required|string|max:255|unique:manufacturers,name',
            ]);
            
            $manufacturer = Manufacturer::create([
                'name' => $validated['name'],
                'slug' => \Str::slug($validated['name']),
                'is_active' => true,
                'created_by' => auth()->id()
            ]);
            
            return response()->json([
                'success' => true,
                'manufacturer' => $manufacturer
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 422);
        }
    }
}
