<?php

namespace App\Http\Traits;

use App\Events\NewChatMessage;
use App\Models\Message;
use App\Models\User;
use App\Notifications\AdminNewSupportMessage;
use App\Notifications\NewMessageNotification;
use Illuminate\Support\Collection;

/**
 * Shared trait for chat functionality across Admin, Coach, and Client controllers.
 * Provides common methods for message retrieval, marking as read, and sending.
 */
trait ChatTrait
{
    /**
     * Get conversation messages between two users.
     */
    protected function getConversation(int $userId, int $otherUserId): Collection
    {
        return Message::where(function ($q) use ($userId, $otherUserId) {
            $q->where('sender_id', $userId)->where('receiver_id', $otherUserId);
        })->orWhere(function ($q) use ($userId, $otherUserId) {
            $q->where('sender_id', $otherUserId)->where('receiver_id', $userId);
        })->orderBy('created_at', 'asc')->get();
    }

    /**
     * Mark messages from a sender as read.
     */
    protected function markMessagesAsRead(int $senderId, int $receiverId): void
    {
        Message::where('sender_id', $senderId)
            ->where('receiver_id', $receiverId)
            ->whereNull('read_at')
            ->update(['read_at' => now()]);
    }

    /**
     * Check if user has unread messages from another user.
     */
    protected function hasUnreadMessages(int $senderId, int $receiverId): bool
    {
        return Message::where('sender_id', $senderId)
            ->where('receiver_id', $receiverId)
            ->whereNull('read_at')
            ->exists();
    }

    /**
     * Create and send a chat message with notifications.
     */
    protected function createAndNotifyMessage(User $sender, int $receiverId, string $content, bool $notifyAdminSupport = false): Message
    {
        $message = Message::create([
            'sender_id' => $sender->id,
            'receiver_id' => $receiverId,
            'content' => $content,
        ]);

        $receiver = User::find($receiverId);

        if ($receiver) {
            // Always send the standard new message notification
            $receiver->notify(new NewMessageNotification($message, $sender));

            // If this is a support message to admin, send additional notification
            if ($notifyAdminSupport && $receiver->isAdmin()) {
                $senderRole = $sender->role ?? 'user';
                $receiver->notify(new AdminNewSupportMessage($message, $senderRole));
            }

            // Broadcast real-time event for coach-client chat
            $this->broadcastChatMessage($message, $sender, $receiver);
        }

        return $message;
    }

    /**
     * Broadcast chat message via WebSocket for real-time updates.
     */
    protected function broadcastChatMessage(Message $message, User $sender, User $receiver): void
    {
        $coachId = null;
        $clientId = null;
        $adminId = null;

        // Determine channel based on user roles
        if ($sender->isCoach() && $receiver->isClient()) {
            $coachId = $sender->id;
            $clientId = $receiver->clientProfile?->id;
        } elseif ($sender->isClient() && $receiver->isCoach()) {
            $coachId = $receiver->id;
            $clientId = $sender->clientProfile?->id;
        } elseif ($sender->isAdmin() && $receiver->isCoach()) {
            $adminId = $sender->id;
            $coachId = $receiver->id;
        } elseif ($sender->isCoach() && $receiver->isAdmin()) {
            $adminId = $receiver->id;
            $coachId = $sender->id;
        }

        // Broadcast for coach-client conversation
        if ($coachId && $clientId) {
            broadcast(new NewChatMessage($message, $coachId, $clientId))->toOthers();
        }
        // Broadcast for admin-coach conversation
        elseif ($adminId && $coachId) {
            broadcast(new \App\Events\NewAdminCoachMessage($message, $adminId, $coachId))->toOthers();
        }
    }
}
