<?php

namespace App\Console\Commands;

use App\Models\PaymentReminder;
use App\Models\ShoppingPayment;
use App\Services\PaymentReminderService;
use Carbon\Carbon;
use Illuminate\Console\Command;

/**
 * Command für automatische Zahlungserinnerungen
 * 
 * Dieser Command wird als Cron-Job ausgeführt und sendet automatisch
 * Zahlungserinnerungen basierend auf den konfigurierten Intervallen.
 * 
 * Verwendung:
 * php artisan payments:reminders
 * 
 * Cron-Job Konfiguration (täglich um 9:00 Uhr):
 * 0 9 * * * cd /path/to/project && php artisan payments:reminders >> /dev/null 2>&1
 * 
 * Oder für stündliche Ausführung:
 * 0 * * * * cd /path/to/project && php artisan payments:reminders >> /dev/null 2>&1
 * 
 * Logs werden automatisch in storage/logs/laravel.log geschrieben
 */
class PaymentsReminders extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'payments:reminders';
    protected $description = 'Run Payments Reminders';

    private $timeStart;
    private $dev = false;
    private $paymentReminderService;
    private $stats = [
        'total_processed' => 0,
        'reminders_sent' => 0,
        'errors' => 0,
        'skipped' => 0
    ];

    public function __construct(PaymentReminderService $paymentReminderService)
    {
        parent::__construct();
        $this->paymentReminderService = $paymentReminderService;
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        \Log::info('Starting PaymentsReminders Command', ['timestamp' => now()]);
        $this->info('RUN Command Payments Reminders: '.date('d.m.Y H:i'));
        $this->timeStart = microtime(true);

        try {
            $this->functionReminder();
            
            $executionTime = round(microtime(true) - $this->timeStart, 2);
            $this->info("\n=== PAYMENT REMINDERS ABGESCHLOSSEN ===");
            $this->info("Ausführungszeit: {$executionTime} Sekunden");
            $this->info("Statistiken:");
            $this->info("  - Gesamt verarbeitet: {$this->stats['total_processed']}");
            $this->info("  - Erinnerungen gesendet: {$this->stats['reminders_sent']}");
            $this->info("  - Fehler: {$this->stats['errors']}");
            $this->info("  - Übersprungen: {$this->stats['skipped']}");
            
            \Log::info('PaymentsReminders Command completed successfully', [
                'execution_time' => $executionTime,
                'stats' => $this->stats
            ]);
            return 0;
        } catch (\Exception $e) {
            \Log::error('PaymentsReminders Command failed', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
            $this->error('Command failed: ' . $e->getMessage());
            return 1;
        }
    }

    /**
     * Hauptfunktion für die Verarbeitung der Zahlungserinnerungen
     */
    private function functionReminder()
    {
        $this->info('=== STARTE PAYMENT REMINDERS ===');
        
        // Hole alle aktiven PaymentReminder und gruppiere sie nach clearingtype
        $payment_reminders = PaymentReminder::where('active', true)->get();
        $this->info("Gefundene aktive PaymentReminder: " . $payment_reminders->count());
        
        if ($payment_reminders->isEmpty()) {
            $this->warn("Keine aktiven PaymentReminder gefunden!");
            return;
        }
        
        // Finde für jeden clearingtype das kleinste Intervall (in Tagen)
        $intervals = $this->paymentReminderService->getActiveIntervals();

        $this->info("Gefundene clearingtypes mit kleinsten Intervallen:");
        foreach($intervals as $clearingtype => $interval){
            $this->line("  - {$clearingtype}: {$interval} Tage");
        }

        // Verarbeite jeden clearingtype mit seinem kleinsten Intervall
        foreach($intervals as $clearingtype => $interval){
            $this->info("\n--- Verarbeite clearingtype: {$clearingtype} mit Intervall: {$interval} Tage ---");
            
            $date = Carbon::now()->subDays($interval);
            $this->line("Suche Zahlungen vor: " . $date->format('d.m.Y H:i:s'));

            // Hole nur die neueste ShoppingPayment pro shopping_order_id
            $shopping_payments = $this->paymentReminderService->getOpenPaymentsForClearingType($clearingtype, $interval);
                
            $this->info("Gefundene offene Zahlungen für {$clearingtype}: " . $shopping_payments->count());
            
            if ($shopping_payments->isEmpty()) {
                $this->line("  Keine Zahlungen für {$clearingtype} gefunden.");
                continue;
            }
            
            // Verarbeite jede Zahlung
            foreach($shopping_payments as $shopping_payment){
                $this->processPayment($shopping_payment, $clearingtype);
            }
        }
    }

    /**
     * Verarbeitet eine einzelne Zahlung und sendet ggf. eine Erinnerung
     */
    private function processPayment($shopping_payment, $clearingtype)
    {
        $this->stats['total_processed']++;
        
        try {
            $this->line("  Verarbeite Order ID: {$shopping_payment->shopping_order_id}, Created: {$shopping_payment->created_at->format('d.m.Y H:i:s')}, Amount: {$shopping_payment->amount}, Reminder: {$shopping_payment->reminder}");
            
            // Prüfe ob eine Erinnerung gesendet werden soll
            if ($this->shouldSendReminder($shopping_payment, $clearingtype)) {
                $this->sendReminderForPayment($shopping_payment);
            } else {
                $this->line("    ⏭️  Übersprungen - Keine Erinnerung fällig");
                $this->stats['skipped']++;
            }
            
        } catch (\Exception $e) {
            $this->error("    ❌ Fehler bei Order ID {$shopping_payment->shopping_order_id}: " . $e->getMessage());
            $this->stats['errors']++;
            
            \Log::error('Error processing payment reminder', [
                'order_id' => $shopping_payment->shopping_order_id,
                'payment_id' => $shopping_payment->id,
                'error' => $e->getMessage()
            ]);
        }
    }

    /**
     * Prüft ob eine Erinnerung für diese Zahlung gesendet werden soll
     * 
     * Logik:
     * - Erste Erinnerung: Nach X Tagen ab Bestelldatum
     * - Weitere Erinnerungen: Nach Y Tagen ab letzter Erinnerung
     */
    private function shouldSendReminder($shopping_payment, $clearingtype)
    {
        // Hole alle aktiven Erinnerungen für diesen Clearingtype
        $payment_reminders = PaymentReminder::where('active', true)
            ->where('clearingtype', $clearingtype)
            ->orderBy('interval', 'asc')
            ->get();

        if ($payment_reminders->isEmpty()) {
            return false;
        }

        // Wenn alle Erinnerungen bereits gesendet wurden
        if ($shopping_payment->reminder >= $payment_reminders->count()) {
            return false;
        }

        // Hole die nächste Erinnerung
        $next_reminder = $payment_reminders[$shopping_payment->reminder];
        
        // Wenn noch keine Erinnerung gesendet wurde, prüfe das erste Intervall
        if ($shopping_payment->reminder == 0) {
            $daysSinceOrder = $shopping_payment->created_at->diffInDays(now());
            return $daysSinceOrder >= $next_reminder->interval;
        }
        
        // Wenn bereits Erinnerungen gesendet wurden, prüfe das nächste Intervall
        if ($shopping_payment->reminder_date) {
            $current_reminder = $payment_reminders[$shopping_payment->reminder - 1];
            $interval_difference = $next_reminder->interval - $current_reminder->interval;
            
            $next_reminder_date = Carbon::parse($shopping_payment->reminder_date)->addDays($interval_difference);
            return now()->gte($next_reminder_date);
        }
        
        return false;
    }

    /**
     * Sendet eine Erinnerung für eine spezifische Zahlung
     */
    private function sendReminderForPayment($shopping_payment)
    {
        try {
            $this->line("    📧 Sende Erinnerung...");
            
            $result = $this->paymentReminderService->sendReminder($shopping_payment);
            
            if ($result) {
                $this->line("    ✅ Erinnerung erfolgreich gesendet");
                $this->stats['reminders_sent']++;
                
                // Log für Cron-Job
                \Log::info('Payment reminder sent via cron', [
                    'order_id' => $shopping_payment->shopping_order_id,
                    'payment_id' => $shopping_payment->id,
                    'reminder_count' => $shopping_payment->reminder + 1,
                    'email' => $shopping_payment->shopping_order->shopping_user->billing_email ?? 'N/A'
                ]);
            } else {
                $this->line("    ⚠️  Keine Erinnerung gesendet (keine weitere Erinnerung verfügbar)");
                $this->stats['skipped']++;
            }
            
        } catch (\Exception $e) {
            $this->error("    ❌ Fehler beim Senden der Erinnerung: " . $e->getMessage());
            $this->stats['errors']++;
            
            \Log::error('Error sending payment reminder', [
                'order_id' => $shopping_payment->shopping_order_id,
                'payment_id' => $shopping_payment->id,
                'error' => $e->getMessage()
            ]);
        }
    }
}