<?php

/*
|--------------------------------------------------------------------------
| OwnStore - Build your own online store
| Author: TakfeDev (MKJUEL)
| All Rights Reserved
|--------------------------------------------------------------------------
*/

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Conversation;
use App\Models\Message;
use App\Models\Setting;
use App\Models\User;
use App\Events\MessageSent;
use App\Mail\NewMessageMail;
use Illuminate\Support\Facades\Mail;
use Inertia\Inertia;

class ChatController extends Controller
{
    // Load the main Chat UI
    public function index(Request $request)
    {
        $userId = auth()->id();
        $search = $request->query('search', '');

        $conversationsQuery = Conversation::with([
                'buyer:id,name,avatar_path', 
                'seller:id,name,avatar_path', 
                'product:id,title,slug', 
                'product.images'
            ])
            ->where(function($q) use ($userId) {
                $q->where('buyer_id', $userId)
                  ->orWhere('seller_id', $userId);
            })
            ->withCount(['messages as unread_count' => function ($query) use ($userId) {
                $query->where('sender_id', '!=', $userId)->whereNull('read_at');
            }])
            ->orderBy('last_message_at', 'desc');

        if ($search) {
            $conversationsQuery->whereHas('buyer', function($q) use ($search) {
                $q->where('name', 'like', "%{$search}%");
            })->orWhereHas('seller', function($q) use ($search) {
                $q->where('name', 'like', "%{$search}%");
            });
        }

        $conversations = $conversationsQuery->paginate(15)->withQueryString();

        $conversations->getCollection()->transform(function ($conv) use ($userId) {
            //  Cast to integer
            $conv->other_user = (int) $conv->buyer_id === (int) $userId ? $conv->seller : $conv->buyer;
            $conv->latest_message = $conv->messages()->latest()->first();

            // FETCH THE LATEST ORDER CONTEXT FOR THIS SPECIFIC PRODUCT
            if ($conv->product_id) {
                $conv->latest_order = \App\Models\Order::where('buyer_id', $conv->buyer_id)
                    ->where('seller_id', $conv->seller_id)
                    ->whereHas('items', function($q) use ($conv) {
                        $q->where('product_id', $conv->product_id);
                    })
                    ->latest()
                    ->first(['id', 'order_number', 'status', 'tracking_number', 'tracking_url', 'shipping_carrier', 'is_refund_requested']);
            }

            return $conv;
        });

        if ($request->wantsJson()) {
            return response()->json($conversations);
        }

        return Inertia::render('Dashboard/Chat/Index', [
            'initialConversations' => $conversations,
            'activeConversationId' => $request->query('c', null),
            'filters' => ['search' => $search]
        ]);
    }

    public function getUnreadCount(Request $request)
    {
        if (!auth()->check()) {
            return response()->json(['unread_count' => 0]);
        }

        $userId = auth()->id();
        $count = Message::whereHas('conversation', function ($q) use ($userId) {
            $q->where('buyer_id', $userId)->orWhere('seller_id', $userId);
        })
        ->where('sender_id', '!=', $userId)
        ->whereNull('read_at')
        ->count();

        return response()->json(['unread_count' => $count]);
    }

    public function getMessages(Conversation $conversation)
    {
        $this->authorizeAccess($conversation);
        $userId = auth()->id();

        $conversation->messages()
            ->where('sender_id', '!=', $userId)
            ->whereNull('read_at')
            ->update(['read_at' => now()]);

        $messages = $conversation->messages()->with('sender:id,name,avatar_path')->get();
        
        return response()->json($messages);
    }

    public function store(Request $request, Conversation $conversation)
    {
        $this->authorizeAccess($conversation);

        $request->validate(['body' => 'required|string|max:2000']);

        $message = $conversation->messages()->create([
            'sender_id' => auth()->id(),
            'body' => $request->body,
        ]);

        $conversation->update(['last_message_at' => now()]);

        try {
            broadcast(new MessageSent($message))->toOthers();
        } catch (\Exception $e) {
            \Illuminate\Support\Facades\Log::warning('Reverb is down. Message saved to DB only.');
        }

        // --- INSTANT NO-DELAY BACKGROUND EMAIL ---
        //  Cast to integer
        $receiverId = (int) auth()->id() === (int) $conversation->buyer_id ? $conversation->seller_id : $conversation->buyer_id;
        $receiver = User::find($receiverId);

        $emailSetting = Setting::where('key', 'notify_new_message_email')->value('value');
        $emailEnabled = filter_var($emailSetting ?? true, FILTER_VALIDATE_BOOLEAN);

        if ($emailEnabled && $receiver && $receiver->email) {
            $messageObj = $message->load('sender:id,name');
            
            dispatch(function () use ($receiver, $messageObj) {
                try {
                    Mail::to($receiver->email)->send(new NewMessageMail($messageObj, $receiver));
                } catch (\Exception $e) {
                    \Illuminate\Support\Facades\Log::error('Chat Email Failed: ' . $e->getMessage());
                }
            })->afterResponse();
        }

        return response()->json($message->load('sender:id,name,avatar_path'));
    }

    // --- SMART START CHAT LOGIC ---
    public function startChat(Request $request)
    {
        $request->validate([
            'user_id' => 'required|exists:users,id', 
            'product_id' => 'nullable|exists:products,id'
        ]);

        $targetId = $request->user_id;

        // Cast to integer
        if ((int) $targetId === (int) auth()->id()) {
            return back()->with('error', 'You cannot message yourself.');
        }

        // Default assumptions
        $buyerId = auth()->id();
        $sellerId = $targetId;

        // Smart Mapping
        if ($request->product_id) {
            $product = \App\Models\Product::find($request->product_id);
            // Cast to integer
            if ($product && (int) $product->seller_id === (int) auth()->id()) {
                // The current auth user is the seller of this product!
                $buyerId = $targetId;
                $sellerId = auth()->id();
            }
        }

        $conversation = Conversation::firstOrCreate(
            ['buyer_id' => $buyerId, 'seller_id' => $sellerId, 'product_id' => $request->product_id],
            ['last_message_at' => now()]
        );

        return redirect()->route('chat.index', ['c' => $conversation->id]);
    }

    private function authorizeAccess($conversation)
    {
        //  Cast all variables to integer to prevent strict type failures from PDO
        $userId = (int) auth()->id();
        $buyerId = (int) $conversation->buyer_id;
        $sellerId = (int) $conversation->seller_id;

        if ($userId !== $buyerId && $userId !== $sellerId) {
            abort(403, 'Unauthorized access to this conversation.');
        }
    }
}