<?php

namespace App\Http\Controllers;

use App\Models\Offer;
use App\Models\Item;
use App\Models\Conversation;
use App\Models\Message;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class OfferController extends Controller
{
    public function store(Request $request, Item $item)
    {
        if (!auth()->check()) {
            return redirect()->route('login');
        }

        // Can't offer on own items
        if ($item->user_id === auth()->id()) {
            return back()->with('error', 'You cannot make offers on your own items.');
        }

        // Check if offers are enabled on this item
        if (!$item->offers_enabled) {
            return back()->with('error', 'The seller has disabled offers on this item.');
        }

        $validated = $request->validate([
            'offered_price' => 'required|numeric|min:0.01',
            'is_committed' => 'required|boolean',
            'message' => 'nullable|string|max:500',
        ]);

        try {
            DB::beginTransaction();

            // Check if user already has pending/counter-offered offer on this item
            $existingOffer = Offer::where('item_id', $item->id)
                ->where('buyer_id', auth()->id())
                ->whereIn('status', ['pending', 'counter_offered'])
                ->first();

            if ($existingOffer) {
                DB::rollBack();
                return back()->with('error', 'You already have an active offer on this item. You can only have one active offer per item.');
            }

            // Create offer
            $offer = Offer::create([
                'item_id' => $item->id,
                'buyer_id' => auth()->id(),
                'seller_id' => $item->user_id,
                'offered_price' => (float) $validated['offered_price'],
                'is_committed' => (bool) $validated['is_committed'],
                'status' => 'pending',
                'message' => $validated['message'] ?? null,
                'expires_at' => now()->addDays(3), // Offers expire after 3 days
            ]);

            // Create or get conversation for this item
            $conversation = Conversation::firstOrCreate(
                ['item_id' => $item->id],
                ['subject' => "Inquiry about {$item->title}"]
            );

            // Add both users as participants if not already
            $conversation->participants()->syncWithoutDetaching([
                auth()->id() => ['last_read_at' => now()],
                $item->user_id => ['last_read_at' => null],
            ]);

            // Create message with offer details
            $offerType = $offer->getOfferTypeLabel();
            $messageBody = "I made a {$offerType} for \${$offer->offered_price}";
            if ($validated['message']) {
                $messageBody .= ": {$validated['message']}";
            }

            Message::create([
                'conversation_id' => $conversation->id,
                'user_id' => auth()->id(),
                'body' => $messageBody,
            ]);

            // Update conversation's last message time
            $conversation->update(['last_message_at' => now()]);

            DB::commit();

            // Notify seller
            $item->user->notify(new \App\Notifications\OfferReceived($offer));

            return back()->with('success', "$offerType submitted! The seller will review it.");

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

    public function acceptOffer(Offer $offer)
    {
        // Only seller can accept
        if ($offer->seller_id !== auth()->id()) {
            return response()->json(['success' => false, 'message' => 'Unauthorized'], 403);
        }

        // Check if expired
        $offer->markExpiredIfNeeded();
        if ($offer->isExpired()) {
            return response()->json(['success' => false, 'message' => 'This offer has expired'], 400);
        }

        // Can only accept pending or counter-offered offers
        if (!in_array($offer->status, ['pending', 'counter_offered'])) {
            return response()->json(['success' => false, 'message' => 'Offer cannot be accepted'], 400);
        }

        try {
            DB::beginTransaction();

            $offer->update([
                'status' => 'accepted',
                'accepted_at' => now(),
            ]);

            // Notify buyer
            $offer->buyer->notify(new \App\Notifications\OfferAccepted($offer));

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Offer accepted! The buyer has been notified.',
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => 'Failed to accept offer'], 500);
        }
    }

    public function counterOffer(Request $request, Offer $offer)
    {
        // Only seller can counter
        if ($offer->seller_id !== auth()->id()) {
            return response()->json(['success' => false, 'message' => 'Unauthorized'], 403);
        }

        // Check if expired
        $offer->markExpiredIfNeeded();
        if ($offer->isExpired()) {
            return response()->json(['success' => false, 'message' => 'This offer has expired'], 400);
        }

        // Can only counter pending or counter-offered offers
        if (!in_array($offer->status, ['pending', 'counter_offered'])) {
            return response()->json(['success' => false, 'message' => 'Offer cannot be countered'], 400);
        }

        $validated = $request->validate([
            'counter_price' => 'required|numeric|min:0.01',
            'seller_message' => 'nullable|string|max:500',
        ]);

        try {
            DB::beginTransaction();

            $offer->update([
                'status' => 'counter_offered',
                'counter_price' => (float) $validated['counter_price'],
                'seller_message' => $validated['seller_message'] ?? null,
            ]);

            // Notify buyer
            $offer->buyer->notify(new \App\Notifications\OfferCountered($offer));

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Counter offer sent! The buyer has been notified.',
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => 'Failed to send counter offer'], 500);
        }
    }

    public function reject(Request $request, Offer $offer)
    {
        // Only seller can reject
        if ($offer->seller_id !== auth()->id()) {
            return response()->json(['success' => false, 'message' => 'Unauthorized'], 403);
        }

        // Check if expired
        $offer->markExpiredIfNeeded();
        if ($offer->isExpired()) {
            return response()->json(['success' => false, 'message' => 'This offer has expired'], 400);
        }

        // Can only reject pending or counter-offered offers
        if (!in_array($offer->status, ['pending', 'counter_offered'])) {
            return response()->json(['success' => false, 'message' => 'Offer cannot be rejected'], 400);
        }

        $validated = $request->validate([
            'seller_message' => 'nullable|string|max:500',
        ]);

        try {
            DB::beginTransaction();

            $offer->update([
                'status' => 'rejected',
                'rejected_at' => now(),
                'seller_message' => $validated['seller_message'] ?? null,
            ]);

            // Notify buyer
            $offer->buyer->notify(new \App\Notifications\OfferRejected($offer));

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Offer rejected.',
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['success' => false, 'message' => 'Failed to reject offer'], 500);
        }
    }

    public function withdraw(Offer $offer)
    {
        // Only buyer can withdraw
        if ($offer->buyer_id !== auth()->id()) {
            return response()->json(['success' => false, 'message' => 'Unauthorized'], 403);
        }

        // Check if expired
        $offer->markExpiredIfNeeded();
        if ($offer->isExpired()) {
            return response()->json(['success' => false, 'message' => 'This offer has already expired'], 400);
        }

        // Can only withdraw pending or counter-offered offers
        if (!in_array($offer->status, ['pending', 'counter_offered'])) {
            return response()->json(['success' => false, 'message' => 'Offer cannot be withdrawn'], 400);
        }

        try {
            DB::beginTransaction();

            $offer->update([
                'status' => 'withdrawn',
            ]);

            DB::commit();

            return back()->with('success', 'Offer withdrawn.');

        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Failed to withdraw offer.');
        }
    }

    public function myOffers()
    {
        $sentOffers = auth()->user()->offersAsBuyer()
            ->with(['item', 'seller'])
            ->latest()
            ->get();

        $receivedOffers = auth()->user()->offersAsSeller()
            ->with(['item', 'buyer'])
            ->latest()
            ->get();

        return view('offers.index', compact('sentOffers', 'receivedOffers'));
    }
}
