<?php

namespace App\Http\Controllers;

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

class MessageController extends Controller
{
    public function index()
    {
        $conversations = auth()->user()->conversations()
            ->with(['participants', 'item'])
            ->get()
            ->map(function ($conversation) {
                $conversation->other_participant = $conversation->getOtherParticipant(auth()->id());
                $conversation->has_unread = $conversation->hasUnreadMessages(auth()->id());
                $conversation->latest_message = $conversation->messages()->latest()->first();
                return $conversation;
            });

        // If user is banned, filter to only conversations with admins
        if (!auth()->user()->is_active) {
            $conversations = $conversations->filter(function ($conversation) {
                $otherParticipant = $conversation->other_participant;
                return $otherParticipant && $otherParticipant->is_admin;
            });
        }

        return view('messages.index', compact('conversations'));
    }

    public function show(Conversation $conversation)
    {
        // Check if user is participant
        if (!$conversation->participants()->where('user_id', auth()->id())->exists()) {
            abort(403, 'You are not a participant in this conversation.');
        }

        // Mark conversation as read
        $conversation->markAsRead(auth()->id());

        // Load messages with user info
        $messages = $conversation->messages()
            ->with('user')
            ->get();

        $otherParticipant = $conversation->getOtherParticipant(auth()->id());

        return view('messages.show', compact('conversation', 'messages', 'otherParticipant'));
    }

    public function showMessageForm(Item $item)
    {
        // Banned users can't message about items (only admins via separate route)
        if (!auth()->user()->is_active) {
            return redirect()->route('dashboard')->with('error', 'Your account is suspended. Use the contact administrators feature on your dashboard.');
        }

        if ($item->user_id === auth()->id()) {
            return back()->with('error', 'You cannot message yourself about your own item.');
        }

        // Check if conversation already exists between these users for this item
        $existingConversation = Conversation::where('item_id', $item->id)
            ->whereHas('participants', function ($query) {
                $query->where('user_id', auth()->id());
            })
            ->whereHas('participants', function ($query) use ($item) {
                $query->where('user_id', $item->user_id);
            })
            ->first();

        if ($existingConversation) {
            return redirect()->route('messages.show', $existingConversation);
        }

        return view('messages.create', compact('item'));
    }

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

        $validated = $request->validate([
            'subject' => 'required|string|max:255',
            'message' => 'required|string|min:1'
        ]);

        try {
            DB::beginTransaction();

            // Create conversation
            $conversation = Conversation::create([
                'item_id' => $item->id,
                'subject' => $validated['subject'],
                'last_message_at' => now(),
            ]);

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

            // Create first message
            Message::create([
                'conversation_id' => $conversation->id,
                'user_id' => auth()->id(),
                'body' => $validated['message'],
            ]);

            // Track messaging interaction
            \App\Models\UserInteraction::track($item->id, 'message', [
                'subject' => $validated['subject']
            ]);

            // Notify recipient
            $recipient = $item->user;
            $recipient->notify(new \App\Notifications\NewMessage($conversation, auth()->user(), $validated['message']));

            DB::commit();

            return redirect()->route('messages.show', $conversation)
                ->with('success', 'Message sent successfully!');

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

    public function reply(Request $request, Conversation $conversation)
    {
        // Check if user is participant
        if (!$conversation->participants()->where('user_id', auth()->id())->exists()) {
            abort(403, 'You are not a participant in this conversation.');
        }

        // If user is banned, only allow replies to conversations with admins
        if (!auth()->user()->is_active) {
            $otherParticipant = $conversation->getOtherParticipant(auth()->id());
            if (!$otherParticipant || !$otherParticipant->is_admin) {
                return back()->with('error', 'Suspended users can only message administrators.');
            }
        }

        $validated = $request->validate([
            'message' => 'required|string|min:1'
        ]);

        try {
            DB::beginTransaction();

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

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

            // Mark as read for sender, unread for others
            $conversation->markAsRead(auth()->id());

            // Notify other participants
            $otherParticipant = $conversation->getOtherParticipant(auth()->id());
            if ($otherParticipant) {
                $otherParticipant->notify(new \App\Notifications\NewMessage($conversation, auth()->user(), $validated['message']));
            }

            DB::commit();

            return back()->with('success', 'Message sent!');

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

    public function create()
    {
        //
    }

    public function store(Request $request)
    {
        //
    }

    public function edit(string $id)
    {
        //
    }

    public function update(Request $request, string $id)
    {
        //
    }

    public function destroy(string $id)
    {
        //
    }

    public function contactAdmin()
    {
        // Only for banned users
        if (auth()->user()->is_active) {
            return redirect()->route('messages.index');
        }

        // Get all admin users
        $admins = \App\Models\User::where('is_admin', true)->get();
        
        return view('messages.contact-admin', compact('admins'));
    }

    public function sendToAdmin(Request $request)
    {
        // Only for banned users
        if (auth()->user()->is_active) {
            return redirect()->route('messages.index');
        }

        $validated = $request->validate([
            'admin_id' => 'required|exists:users,id',
            'subject' => 'required|string|max:255',
            'message' => 'required|string|min:1'
        ]);

        // Verify the selected user is an admin
        $admin = \App\Models\User::where('id', $validated['admin_id'])
            ->where('is_admin', true)
            ->firstOrFail();

        try {
            DB::beginTransaction();

            // Check if conversation already exists between banned user and this admin
            $existingConversation = Conversation::whereNull('item_id')
                ->whereHas('participants', function ($query) {
                    $query->where('user_id', auth()->id());
                })
                ->whereHas('participants', function ($query) use ($admin) {
                    $query->where('user_id', $admin->id);
                })
                ->first();

            if ($existingConversation) {
                // Add new message to existing conversation
                Message::create([
                    'conversation_id' => $existingConversation->id,
                    'user_id' => auth()->id(),
                    'body' => $validated['message'],
                ]);

                $existingConversation->update([
                    'subject' => $validated['subject'], // Update subject
                    'last_message_at' => now()
                ]);

                $existingConversation->markAsRead(auth()->id());

                // Notify admin
                $admin->notify(new \App\Notifications\NewMessage($existingConversation, auth()->user(), $validated['message']));

                DB::commit();
                return redirect()->route('messages.show', $existingConversation)
                    ->with('success', 'Message sent to administrator!');
            }

            // Create new conversation
            $conversation = Conversation::create([
                'item_id' => null, // No item for admin conversations
                'subject' => $validated['subject'],
                'last_message_at' => now(),
            ]);

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

            // Create first message
            Message::create([
                'conversation_id' => $conversation->id,
                'user_id' => auth()->id(),
                'body' => $validated['message'],
            ]);

            // Notify admin
            $admin->notify(new \App\Notifications\NewMessage($conversation, auth()->user(), $validated['message']));

            DB::commit();

            return redirect()->route('messages.show', $conversation)
                ->with('success', 'Message sent to administrator successfully!');

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

    public function createDirectConversation(Request $request)
    {
        if (!auth()->user()->is_active) {
            abort(403, 'Your account is suspended.');
        }

        $validated = $request->validate([
            'user_id' => 'required|exists:users,id',
            'item_id' => 'required|exists:items,id'
        ]);

        $otherUserId = $validated['user_id'];
        $itemId = $validated['item_id'];
        
        // Don't allow messaging yourself
        if ($otherUserId == auth()->id()) {
            return back()->with('error', 'You cannot message yourself.');
        }

        // Check if conversation already exists between these users for this item
        $existingConversation = Conversation::where('item_id', $itemId)
            ->whereHas('participants', function ($query) {
                $query->where('user_id', auth()->id());
            })
            ->whereHas('participants', function ($query) use ($otherUserId) {
                $query->where('user_id', $otherUserId);
            })
            ->first();

        if ($existingConversation) {
            return redirect()->route('messages.show', $existingConversation);
        }

        // Create new conversation
        try {
            DB::beginTransaction();

            $item = Item::findOrFail($itemId);
            
            $conversation = Conversation::create([
                'item_id' => $itemId,
                'subject' => "About: {$item->title}",
                'last_message_at' => now(),
            ]);

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

            DB::commit();

            return redirect()->route('messages.show', $conversation);

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