<?php

namespace App\Jobs;

use Carbon\Carbon;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Namu\WireChat\Enums\Actions;
use Namu\WireChat\Models\Message;

class DeleteExpiredWireChatMessagesJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * Create a new job instance.
     */
    public function __construct()
    {
        $this->onQueue('low');
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        // Disappearing messages always enabled - this prevents orphaned messages
        Log::info('WireChat disappearing messages: Starting cleanup');

        $deletedCount = 0;
        $deletedKeptCount = 0;

        // Get all conversations with disappearing settings
        $conversations = \Namu\WireChat\Models\Conversation::whereNotNull('disappearing_started_at')
            ->whereNotNull('disappearing_duration')
            ->get();

        Log::info("WireChat disappearing messages: Found {$conversations->count()} conversations with disappearing enabled");

        foreach ($conversations as $conversation) {
            // Get regular messages (not kept) that should be deleted
            $messages = $conversation->messages()
                ->withoutGlobalScopes()
                ->where(function ($query) {
                    // Messages that are not kept
                    $query->whereNull('kept_at')
                        // Or messages that are kept but have delete actions or are trashed
                        ->orWhere(function ($query) {
                            $query->whereNotNull('kept_at') // Kept messages
                                ->where(function ($query) {
                                    $query->whereNotNull('deleted_at') // Trashed
                                        ->orWhereHas('actions', function ($query) {
                                            $query->where('type', Actions::DELETE);
                                        });
                                });
                        });
                })
                // Only messages created AFTER disappearing was enabled
                ->where('created_at', '>', $conversation->disappearing_started_at)
                ->get();

            foreach ($messages as $message) {
                $createdAt = $message->created_at;

                if ($createdAt && $createdAt->isFuture()) {
                    continue; // Skip future messages
                }

                // Check if message is older than the conversation's duration
                if ($createdAt && $createdAt->diffInSeconds(now()) > $conversation->disappearing_duration) {
                    try {
                        Log::info("WireChat disappearing messages: Deleting message {$message->id} (age: {$createdAt->diffInSeconds(now())}s, limit: {$conversation->disappearing_duration}s)");
                        $message->forceDelete();
                        $deletedCount++;
                    } catch (\Exception $e) {
                        Log::error("WireChat disappearing messages: Failed to delete message {$message->id}: {$e->getMessage()}");
                    }
                }
            }

            // Get kept messages that should be deleted based on kept_messages_duration
            $keptMessagesDurationDays = timebank_config('wirechat.disappearing_messages.kept_messages_duration');
            if ($keptMessagesDurationDays !== null && timebank_config('wirechat.disappearing_messages.allow_users_to_keep', true)) {
                $keptMessagesDuration = $keptMessagesDurationDays * 86400; // Convert days to seconds
                $keptMessages = $conversation->messages()
                    ->withoutGlobalScopes()
                    ->whereNotNull('kept_at')
                    ->whereNull('deleted_at')
                    ->whereDoesntHave('actions', function ($query) {
                        $query->where('type', Actions::DELETE);
                    })
                    ->where('kept_at', '>', $conversation->disappearing_started_at)
                    ->get();

                foreach ($keptMessages as $keptMessage) {
                    $keptAt = $keptMessage->kept_at;

                    if ($keptAt && $keptAt->isFuture()) {
                        continue; // Skip future kept messages
                    }

                    // Check if kept message is older than the kept messages duration
                    if ($keptAt && $keptAt->diffInSeconds(now()) > $keptMessagesDuration) {
                        try {
                            Log::info("WireChat disappearing messages: Deleting kept message {$keptMessage->id} (kept for: {$keptAt->diffInSeconds(now())}s, limit: {$keptMessagesDuration}s)");
                            $keptMessage->forceDelete();
                            $deletedKeptCount++;
                        } catch (\Exception $e) {
                            Log::error("WireChat disappearing messages: Failed to delete kept message {$keptMessage->id}: {$e->getMessage()}");
                        }
                    }
                }
            }
        }

        Log::info("WireChat disappearing messages: Deleted {$deletedCount} expired messages and {$deletedKeptCount} expired kept messages");
    }
}
