<?php

use App\Models\Invoice;
use App\Models\InvoiceActivityLog;
use Illuminate\Foundation\Inspiring;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log;
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('invoices:send-due-reminders {--dry-run}', function () {
    $today = now()->startOfDay();
    $tomorrow = $today->copy()->addDay()->toDateString();
    $dryRun = (bool) $this->option('dry-run');

    $baseQuery = Invoice::with('customer')
        ->where('status', Invoice::STATUS_ISSUED)
        ->whereIn('payment_status', [Invoice::PAYMENT_UNPAID, Invoice::PAYMENT_PARTIAL])
        ->whereNotNull('due_date');

    $dueSoon = (clone $baseQuery)
        ->whereDate('due_date', $tomorrow)
        ->whereNull('due_reminder_sent_at')
        ->get();

    $overdue = (clone $baseQuery)
        ->whereDate('due_date', '<', $today->toDateString())
        ->whereNull('overdue_reminder_sent_at')
        ->get();

    $send = function (Invoice $invoice, string $type) use ($dryRun) {
        $isOverdue = $type === 'overdue';
        $subject = $isOverdue
            ? 'Pengingat invoice overdue ' . ($invoice->invoice_number ?: ('#' . $invoice->id))
            : 'Pengingat jatuh tempo invoice ' . ($invoice->invoice_number ?: ('#' . $invoice->id));

        $message = implode("\n", [
            'Halo ' . ($invoice->customer->name ?: 'Pelanggan') . ',',
            '',
            'Ini adalah pengingat untuk invoice ' . ($invoice->invoice_number ?: ('#' . $invoice->id)) . '.',
            'Jatuh tempo: ' . optional($invoice->due_date)->format('d M Y'),
            'Total tagihan: Rp ' . number_format((float) $invoice->grand_total, 0, ',', '.'),
            'Sisa tagihan: Rp ' . number_format((float) $invoice->balance_due, 0, ',', '.'),
            '',
            $isOverdue ? 'Status: Overdue.' : 'Status: Akan jatuh tempo besok.',
        ]);

        if (! $dryRun && $invoice->customer?->email) {
            try {
                Mail::raw($message, function ($mail) use ($invoice, $subject) {
                    $mail->to($invoice->customer->email)
                        ->subject($subject);
                });
            } catch (\Throwable $e) {
                Log::warning('Gagal kirim email reminder invoice', [
                    'invoice_id' => $invoice->id,
                    'error' => $e->getMessage(),
                ]);
            }
        }

        if (! $dryRun) {
            $invoice->update([
                $isOverdue ? 'overdue_reminder_sent_at' : 'due_reminder_sent_at' => now(),
            ]);

            InvoiceActivityLog::create([
                'invoice_id' => $invoice->id,
                'user_id' => null,
                'action' => $isOverdue ? 'reminder_overdue_sent' : 'reminder_due_sent',
                'description' => $isOverdue
                    ? 'Reminder overdue dikirim otomatis.'
                    : 'Reminder jatuh tempo dikirim otomatis.',
            ]);
        }
    };

    foreach ($dueSoon as $invoice) {
        $send($invoice, 'due');
    }

    foreach ($overdue as $invoice) {
        $send($invoice, 'overdue');
    }

    $this->info('Due soon reminders: ' . $dueSoon->count());
    $this->info('Overdue reminders: ' . $overdue->count());
    $this->info($dryRun ? 'Mode DRY RUN (tanpa update database).' : 'Reminder berhasil diproses.');
})->purpose('Kirim reminder invoice jatuh tempo dan overdue');

Schedule::command('invoices:send-due-reminders')->dailyAt('08:00');
