<?php

namespace App\Listeners;

use App\Jobs\SendDelayedEmail;
use App\Models\MessageSetting;
use Illuminate\Support\Facades\Log;
use Namu\WireChat\Events\MessageCreated;

class SendEmailNewMessage
{
    /**
     * Handle the event.
     *
     * @param  \Namu\WireChat\Events\MessageCreated  $event
     * @return void
     */
    public function handle(MessageCreated $event)
    {
        try {
            // Log the event structure for debugging
            Log::info('MessageCreated event received', [
                'message_id' => $event->message->id ?? 'unknown',
                'sendable_id' => $event->message->sendable_id ?? 'null',
                'sendable_type' => $event->message->sendable_type ?? 'null',
            ]);

            // Get the conversation from the message
            $conversation = $event->message->conversation;

            // Get all participants from the conversation
            $participants = $conversation->participants;

            // Get the sender - WireChat uses sendable_id and sendable_type
            $sender = null;
            $senderId = null;
            $senderType = null;

            // Check for sendable properties (WireChat's actual naming)
            if (isset($event->message->sendable_id) && isset($event->message->sendable_type)) {
                $senderId = $event->message->sendable_id;
                $senderType = $event->message->sendable_type;
                // Try to get the actual sender model
                if ($senderType && class_exists($senderType)) {
                    $sender = $senderType::find($senderId);
                }
                Log::info('Found sender through sendable properties', [
                    'sendable_id' => $senderId,
                    'sendable_type' => $senderType,
                ]);
            }
            // Check if there's a sendable relationship
            elseif (method_exists($event->message, 'sendable')) {
                $sender = $event->message->sendable;
                if ($sender) {
                    $senderId = $sender->id;
                    $senderType = get_class($sender);
                }
            }

            Log::info('Sender information', [
                'sender_id' => $senderId ?? 'null',
                'sender_type' => $senderType ?? 'null',
                'sender_found' => $sender ? 'yes' : 'no',
            ]);

            Log::info('Found participants', ['count' => $participants->count()]);

            foreach ($participants as $participant) {
                // Skip if this participant is the sender
                if (
                    $senderId && $senderType &&
                    $participant->participantable_id == $senderId &&
                    $participant->participantable_type == $senderType
                ) {
                    Log::info('Skipping sender participant', [
                        'participant_id' => $participant->id,
                    ]);
                    continue;
                }

                // Get the participantable model (User, Organization, etc.)
                $recipient = $participant->participantable;

                if (!$recipient || !$recipient->email) {
                    Log::warning('Participant has no email', [
                        'participant_id' => $participant->id,
                        'participantable_type' => $participant->participantable_type,
                        'participantable_id' => $participant->participantable_id,
                    ]);
                    continue;
                }

                // Get message settings for this recipient
                $messageSettings = MessageSetting::where('message_settingable_id', $recipient->id)
                    ->where('message_settingable_type', get_class($recipient))
                    ->first();

                // Check if email notifications are enabled for this type of chat
                if (!$this->shouldSendEmailNotification($messageSettings, $conversation)) {
                    Log::info('Email notifications disabled for recipient', [
                        'recipient_id' => $recipient->id,
                        'conversation_type' => $conversation->type ?? 'personal',
                    ]);
                    continue;
                }

                // Get the delay in hours (default to 1 if not set)
                $delayHours = $messageSettings->chat_unread_delay ?? 1;

                Log::info('Message settings check', [
                    'settings_found' => $messageSettings ? 'yes' : 'no',
                    'chat_unread_delay' => $messageSettings->chat_unread_delay ?? 'null',
                    'delay_hours' => $delayHours,
                ]);

                // If we couldn't determine the sender, use the first participant that's not the recipient
                if (!$sender) {
                    $sender = $participants->first(function ($p) use ($recipient) {
                        return $p->participantable_id != $recipient->id ||
                            $p->participantable_type != get_class($recipient);
                    })?->participantable ?? $recipient; // Fallback to recipient (self-chat)
                }

                // Dispatch the delayed email job
                SendDelayedEmail::dispatch($event, $sender, $recipient, $participant)
                    ->delay(now()->addHours ($delayHours));

                Log::info('Delayed email job dispatched', [
                    'recipient_id' => $recipient->id,
                    'delay_minutes' => $delayHours,
                    'conversation_id' => $conversation->id,
                ]);
            }
        } catch (\Exception $e) {
            Log::error('Error in SendEmailNewMessage listener', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);
        }
    }

    /**
     * Determine if email notification should be sent based on message settings
     *
     * @param  MessageSetting|null  $settings
     * @param  mixed  $conversation
     * @return bool
     */
    protected function shouldSendEmailNotification($settings, $conversation)
    {
        if (!$settings) {
            // If no settings exist, default to sending notifications
            return true;
        }

        // Check if it's a group conversation
        $isGroupChat = $conversation->participants()->count() > 2;

        if ($isGroupChat) {
            return $settings->group_chat;
        } else {
            return $settings->personal_chat;
        }
    }
}
