<?php

declare(strict_types=1);

namespace App\Console\Commands;

use App\Models\WinbackCampaign;
use App\Notifications\WinbackEmailNotification;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;

class ProcessWinbackCampaigns extends Command
{
    protected $signature = 'winback:process';

    protected $description = 'Process active win-back campaigns and send scheduled emails';

    public function handle(): int
    {
        $activeCampaigns = WinbackCampaign::active()->get();

        if ($activeCampaigns->isEmpty()) {
            $this->info('No active win-back campaigns found.');

            return self::SUCCESS;
        }

        $emailsSent = 0;

        foreach ($activeCampaigns as $campaign) {
            $recipients = $campaign->recipients()
                ->where('reactivated', false)
                ->whereNull('unsubscribed_at')
                ->with('user')
                ->get();

            foreach ($recipients as $recipient) {
                if (! $recipient->isActive()) {
                    continue;
                }

                $emailSequence = $campaign->email_sequence;

                // Check if all emails have been sent
                if ($recipient->current_email_index >= count($emailSequence)) {
                    continue;
                }

                $currentEmail = $emailSequence[$recipient->current_email_index];
                $delayDays = (int) $currentEmail['delay_days'];

                // Determine the reference date (last email sent or enrollment date)
                $referenceDate = $recipient->last_email_sent_at ?? $recipient->created_at;

                // Check if enough time has elapsed
                $daysSinceReference = (int) abs(now()->diffInDays($referenceDate));
                if ($daysSinceReference < $delayDays) {
                    continue;
                }

                try {
                    $recipient->user->notify(new WinbackEmailNotification(
                        $campaign,
                        $recipient,
                        $currentEmail,
                    ));

                    $recipient->update([
                        'current_email_index' => $recipient->current_email_index + 1,
                        'last_email_sent_at' => now(),
                    ]);

                    $emailsSent++;

                    Log::info('Win-back email sent', [
                        'campaign_id' => $campaign->id,
                        'recipient_id' => $recipient->id,
                        'email_index' => $recipient->current_email_index,
                    ]);
                } catch (\Exception $e) {
                    Log::error('Failed to send win-back email', [
                        'campaign_id' => $campaign->id,
                        'recipient_id' => $recipient->id,
                        'error' => $e->getMessage(),
                    ]);
                }
            }
        }

        $this->info("Win-back processing complete. {$emailsSent} email(s) sent.");

        return self::SUCCESS;
    }
}
