<?php

use App\Mail\TestMailketing;
use App\Models\Order;
use App\Models\Payment;
use App\Models\Subscription;
use App\Models\WebhookEvent;
use App\Services\Billing\PayPalPlanSyncService;
use App\Services\Billing\PaypalWebhookProcessor;
use App\Services\LiveSqlImportService;
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Schedule;

Artisan::command('inspire', function () {
    $this->comment(Inspiring::quote());
})->purpose('Display an inspiring quote');

Artisan::command('dewemoji:import-live-sql {path : Absolute path to dewemojiAPI_DB.sql} {--truncate : Truncate target tables first} {--batch=500 : Insert batch size}', function () {
    $path = (string) $this->argument('path');
    $truncate = (bool) $this->option('truncate');
    $batch = (int) $this->option('batch');

    $importer = app(LiveSqlImportService::class);
    $importer->import($path, $truncate, $batch, $this->output);
})->purpose('Import live SQL dump into the current database');

Artisan::command('dewemoji:webhooks:process {--limit=100 : Max events to process} {--status=pending,received : Comma-separated statuses}', function () {
    $limit = (int) $this->option('limit');
    $statuses = array_filter(array_map('trim', explode(',', (string) $this->option('status'))));

    if (empty($statuses)) {
        $this->error('No statuses provided.');

        return 1;
    }

    $processor = app(PaypalWebhookProcessor::class);

    $events = WebhookEvent::query()
        ->whereIn('status', $statuses)
        ->orderBy('id')
        ->limit($limit)
        ->get();

    $processed = 0;
    $failed = 0;

    foreach ($events as $event) {
        try {
            if ($event->provider === 'paypal') {
                $processor->process((string) ($event->event_type ?? ''), $event->payload ?? []);
            }
            $event->update([
                'status' => 'processed',
                'processed_at' => now(),
                'error' => null,
            ]);
            $processed++;
        } catch (\Throwable $e) {
            $event->update([
                'status' => 'error',
                'processed_at' => now(),
                'error' => $e->getMessage(),
            ]);
            $failed++;
        }
    }

    $this->info("Processed {$processed} events, failed {$failed}.");

    return 0;
})->purpose('Process pending webhook events');

Schedule::command('dewemoji:webhooks:process --limit=200')->everyMinute()->withoutOverlapping();

Artisan::command('paypal:sync-plans {--mode=both : sandbox|live|both}', function () {
    $mode = (string) $this->option('mode');
    $service = app(PayPalPlanSyncService::class);

    $runMode = match ($mode) {
        'sandbox' => ['sandbox'],
        'live' => ['live'],
        default => ['sandbox', 'live'],
    };

    foreach ($runMode as $env) {
        $this->info("Syncing PayPal plans: {$env}");
        $result = $service->sync($env);
        $this->line("Created: {$result['created']} · Updated: {$result['updated']} · Deactivated: {$result['deactivated']} · Skipped: {$result['skipped']}");
    }
})->purpose('Create/rotate PayPal plans based on pricing plans');

Artisan::command('mailketing:test {email : Recipient email address}', function () {
    $email = (string) $this->argument('email');

    try {
        Mail::to($email)->send(new TestMailketing);
        $this->info("Mailketing test email sent to {$email}.");

        return 0;
    } catch (\Throwable $e) {
        $this->error('Mailketing test failed: '.$e->getMessage());

        return 1;
    }
})->purpose('Send a Mailketing API test email');

Artisan::command('dewemoji:normalize-statuses', function () {
    $subs = Subscription::query()
        ->where('status', 'cancelled')
        ->update(['status' => 'canceled']);

    $orders = Order::query()
        ->where('status', 'cancelled')
        ->update(['status' => 'canceled']);

    $payments = Payment::query()
        ->where('status', 'cancelled')
        ->update(['status' => 'canceled']);

    $this->info("Normalized statuses: subscriptions={$subs}, orders={$orders}, payments={$payments}");

    return 0;
})->purpose('Normalize legacy cancelled status spelling to canceled');
