<?php

namespace App\Http\Controllers;

use App\Models\MessageThread;
use App\Models\Message;
use App\Models\Proposal;
use App\Http\Requests\SendMessageRequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class MessagingController extends Controller
{
    /**
     * Display a listing of message threads (inbox)
     */
    public function index()
    {
        $threads = MessageThread::whereHas('participants', function ($query) {
            $query->where('user_id', auth()->id());
        })->with(['participants.user', 'latestMessage', 'proposal'])
        ->orderBy('updated_at', 'desc')
        ->paginate(20);
        
        return view('messages.index', compact('threads'));
    }
    
    /**
     * Display a specific message thread
     */
    public function show(MessageThread $thread)
    {
        // Ensure the user is a participant in the thread
        if (!$thread->participants()->where('user_id', auth()->id())->exists()) {
            abort(403);
        }
        
        // Mark messages as read
        Message::where('thread_id', $thread->id)
            ->where('recipient_id', auth()->id())
            ->where('is_read', false)
            ->update(['is_read' => true, 'read_at' => now()]);
            
        // Mark thread as read for this user
        $thread->participants()
            ->where('user_id', auth()->id())
            ->update(['is_read' => true, 'last_read_at' => now()]);
        
        $messages = $thread->messages()->with('sender')->orderBy('created_at', 'asc')->get();
        $participants = $thread->participants()->with('user')->get();
        
        return view('messages.thread', compact('thread', 'messages', 'participants'));
    }
    
    /**
     * Send a message in a thread
     */
    public function send(SendMessageRequest $request, MessageThread $thread)
    {
        // Ensure the user is a participant in the thread
        if (!$thread->participants()->where('user_id', auth()->id())->exists()) {
            abort(403);
        }
        
        // Handle file upload
        $attachmentPath = null;
        if ($request->hasFile('attachment')) {
            $file = $request->file('attachment');
            $filename = Str::random(40) . '.' . $file->getClientOriginalExtension();
            $attachmentPath = $file->storeAs('messages', $filename, 'public');
        }
        
        // Get other participants
        $otherParticipants = $thread->participants()->where('user_id', '!=', auth()->id())->get();
        
        // Create messages for each participant
        foreach ($otherParticipants as $participant) {
            $message = new Message([
                'sender_id' => auth()->id(),
                'recipient_id' => $participant->user_id,
                'body' => $request->body,
                'attachment_path' => $attachmentPath,
                'thread_id' => $thread->id,
            ]);
            $message->save();
            
            // Create notification
            $this->createNotification($message);
        }
        
        // Update thread timestamp
        $thread->updated_at = now();
        $thread->save();
        
        return response()->json([
            'success' => true,
            'message' => 'Message sent successfully!'
        ]);
    }
    
    /**
     * Create a new message thread
     */
    public function createThread(Request $request)
    {
        $validated = $request->validate([
            'recipient_id' => 'required|exists:users,id',
            'body' => 'required|string|max:5000',
            'proposal_id' => 'nullable|exists:proposals,id',
            'attachment' => 'nullable|file|mimes:pdf,jpg,png,docx|max:5120', // 5MB max
        ]);
        
        // Check if a thread already exists between these users for this proposal
        $existingThread = null;
        if (isset($validated['proposal_id'])) {
            $existingThread = MessageThread::where('proposal_id', $validated['proposal_id'])
                ->whereHas('participants', function ($query) {
                    $query->where('user_id', auth()->id());
                })
                ->whereHas('participants', function ($query) use ($validated) {
                    $query->where('user_id', $validated['recipient_id']);
                })
                ->first();
        }
        
        if ($existingThread) {
            // Use existing thread
            $thread = $existingThread;
        } else {
            // Create a new thread
            $thread = new MessageThread([
                'subject' => 'Proposal Discussion',
                'proposal_id' => $validated['proposal_id'] ?? null,
            ]);
            $thread->save();
            
            // Add participants
            $thread->participants()->create([
                'user_id' => auth()->id(),
                'joined_at' => now(),
            ]);
            
            $thread->participants()->create([
                'user_id' => $validated['recipient_id'],
                'joined_at' => now(),
            ]);
        }
        
        // Handle file upload
        $attachmentPath = null;
        if ($request->hasFile('attachment')) {
            $file = $request->file('attachment');
            $filename = Str::random(40) . '.' . $file->getClientOriginalExtension();
            $attachmentPath = $file->storeAs('messages', $filename, 'public');
        }
        
        // Create the message
        $message = new Message([
            'sender_id' => auth()->id(),
            'recipient_id' => $validated['recipient_id'],
            'body' => $validated['body'],
            'attachment_path' => $attachmentPath,
            'thread_id' => $thread->id,
        ]);
        $message->save();
        
        // Create notification
        $this->createNotification($message);
        
        return response()->json([
            'success' => true,
            'thread_id' => $thread->id,
            'message' => 'Thread created successfully!'
        ]);
    }
    
    /**
     * Create a notification for a new message
     */
    private function createNotification(Message $message)
    {
        // Create DB notification
        $recipient = $message->recipient;
        $sender = $message->sender;
        
        $recipient->notify(new \App\Notifications\MessageReceived([
            'message_id' => $message->id,
            'sender_name' => $sender->name,
            'body' => Str::limit($message->body, 50),
        ]));
        
        // Send email notification
        \Mail::to($recipient->email)->send(new \App\Mail\MessageReceived($message));
    }
}