<?php

namespace App\Console\Commands;

use App\Models\DirectBookingRequest;
use App\Models\Booking;
use App\Models\Payment;
use Illuminate\Console\Command;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;

class CleanupExpiredBookingRequests extends Command
{
    protected $signature = 'booking-requests:cleanup';
    protected $description = 'Clean up expired and outdated booking requests, bookings and payments';

    public function handle()
    {
        Log::info('🔄 BOOKING CLEANUP - Starting cleanup process');
        $this->info('Starting booking system cleanup...');

        $results = [];

        try {
            // 1. Expire booking requests that passed their expiry date
            $results['expired_requests'] = $this->expireBookingRequests();

            // 2. Expire requests where start date has passed
            $results['start_date_passed'] = $this->expireStartDatePassedRequests();

            // 3. Clean up expired payments
            $results['expired_payments'] = $this->cleanupExpiredPayments();

            // 4. Clean up expired bookings
            $results['expired_bookings'] = $this->cleanupExpiredBookings();

            // 5. Clean up very old requests
            $results['old_requests'] = $this->cleanupOldRequests();

            // 6. Notify about expiring requests
            $results['notified_requests'] = $this->notifyExpiringRequests();

            // Log summary
            Log::info('🎯 BOOKING CLEANUP - Completed successfully', $results);

            $this->info("Cleanup completed! Results:");
            $this->info("- Expired {$results['expired_requests']} booking requests");
            $this->info("- Expired {$results['start_date_passed']} requests with passed start date");
            $this->info("- Cleaned up {$results['expired_payments']} expired payments");
            $this->info("- Cleaned up {$results['expired_bookings']} expired bookings");
            $this->info("- Deleted {$results['old_requests']} old booking requests");
            $this->info("- Notified about {$results['notified_requests']} expiring requests");

            $this->info('Booking system cleanup completed successfully!');

            return Command::SUCCESS;

        } catch (\Exception $e) {
            Log::error('❌ BOOKING CLEANUP - Failed:', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);

            $this->error('Cleanup failed: ' . $e->getMessage());
            return Command::FAILURE;
        }
    }

    private function expireBookingRequests()
    {
        $expiredCount = 0;

        DirectBookingRequest::expired()
            ->where('request_status', 'pending')
            ->chunk(100, function ($requests) use (&$expiredCount) {
                foreach ($requests as $request) {
                    try {
                        $request->expire();
                        $expiredCount++;

                        Log::info('✅ AUTO EXPIRE - Booking request expired:', [
                            'booking_request_id' => $request->booking_request_id
                        ]);
                    } catch (\Exception $e) {
                        Log::error('❌ AUTO EXPIRE - Failed:', [
                            'booking_request_id' => $request->booking_request_id,
                            'error' => $e->getMessage()
                        ]);
                    }
                }
            });

        return $expiredCount;
    }

    private function expireStartDatePassedRequests()
    {
        $expiredCount = 0;

        DirectBookingRequest::startDatePassed()
            ->where('request_status', 'pending')
            ->chunk(100, function ($requests) use (&$expiredCount) {
                foreach ($requests as $request) {
                    try {
                        $request->expire();
                        $expiredCount++;
                    } catch (\Exception $e) {
                        Log::error('❌ START DATE EXPIRE - Failed:', [
                            'booking_request_id' => $request->booking_request_id,
                            'error' => $e->getMessage()
                        ]);
                    }
                }
            });

        return $expiredCount;
    }

    private function cleanupExpiredPayments()
    {
        $expiredCount = 0;

        Payment::expired()
            ->chunk(100, function ($payments) use (&$expiredCount) {
                foreach ($payments as $payment) {
                    try {
                        $payment->markAsExpired();
                        $expiredCount++;
                    } catch (\Exception $e) {
                        Log::error('❌ PAYMENT CLEANUP - Failed:', [
                            'payment_id' => $payment->payment_id,
                            'error' => $e->getMessage()
                        ]);
                    }
                }
            });

        return $expiredCount;
    }

    private function cleanupExpiredBookings()
    {
        $expiredCount = 0;

        Booking::expired()
            ->chunk(100, function ($bookings) use (&$expiredCount) {
                foreach ($bookings as $booking) {
                    try {
                        $booking->markAsCancelled('Auto-cancelled due to payment expiry');
                        $expiredCount++;
                    } catch (\Exception $e) {
                        Log::error('❌ BOOKING CLEANUP - Failed:', [
                            'booking_id' => $booking->booking_id,
                            'error' => $e->getMessage()
                        ]);
                    }
                }
            });

        return $expiredCount;
    }

    private function cleanupOldRequests()
    {
        return DirectBookingRequest::where('created_at', '<', now()->subDays(30))
            ->whereIn('request_status', ['rejected', 'cancelled', 'expired'])
            ->delete();
    }

    private function notifyExpiringRequests()
    {
        $aboutToExpire = DirectBookingRequest::aboutToExpire(24)->get();

        foreach ($aboutToExpire as $request) {
            $this->sendExpiryNotification($request);
        }

        return $aboutToExpire->count();
    }

    private function sendExpiryNotification($bookingRequest)
    {
        try {
            $babysitter = $bookingRequest->babysitter;
            $parent = $bookingRequest->parent;
            $remainingHours = $bookingRequest->getRemainingHours();

            // Log the notification
            Log::info("🔔 EXPIRY NOTIFICATION - Booking request {$bookingRequest->booking_request_id} expires in {$remainingHours} hours.", [
                'booking_request_id' => $bookingRequest->booking_request_id,
                'babysitter_id' => $babysitter->user_id,
                'parent_id' => $parent->user_id,
                'remaining_hours' => $remainingHours
            ]);

            // You can integrate with Laravel Notifications here
            // Example:
            // $babysitter->notify(new BookingRequestExpiring($bookingRequest));
            // $parent->notify(new BookingRequestExpiring($bookingRequest));

        } catch (\Exception $e) {
            Log::error('❌ EXPIRY NOTIFICATION - Failed to send:', [
                'booking_request_id' => $bookingRequest->booking_request_id,
                'error' => $e->getMessage()
            ]);
        }
    }
}
