<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;

class Booking extends Model
{
    use HasFactory;

    protected $primaryKey = 'booking_id';

    protected $fillable = [
        'booking_request_id',
        'parent_id',
        'babysitter_id',
        'occupation_category_id',
        'start_date',
        'end_date',
        'total_weeks',
        'expected_hours_per_week',
        'agreed_hourly_rate',
        'total_hours',
        'subtotal_amount',
        'commission_rate',
        'commission_amount',
        'total_amount',
        'babysitter_earnings',
        'booking_status',
        'payment_status',
        'scheduled_completion_at',
        'confirmed_at',
        'payment_made_at',
        'started_at',
        'completed_at',
        'cancelled_at'
    ];

    protected $casts = [
        'start_date' => 'date',
        'end_date' => 'date',
        'agreed_hourly_rate' => 'decimal:2',
        'total_hours' => 'decimal:2',
        'subtotal_amount' => 'decimal:2',
        'commission_rate' => 'decimal:2',
        'commission_amount' => 'decimal:2',
        'total_amount' => 'decimal:2',
        'babysitter_earnings' => 'decimal:2',
        'scheduled_completion_at' => 'datetime',
        'confirmed_at' => 'datetime',
        'payment_made_at' => 'datetime',
        'started_at' => 'datetime',
        'completed_at' => 'datetime',
        'cancelled_at' => 'datetime',
        'created_at' => 'datetime',
        'updated_at' => 'datetime'
    ];

    // ✅ ENHANCED: Status Check Methods - ALL SCENARIOS COVERED
    public function canConfirmAfterPayment(): bool
    {
        return $this->booking_status === 'pending_payment' &&
               $this->payment_status === 'pending';
    }

    public function canStart(): bool
    {
        return $this->booking_status === 'confirmed' &&
               $this->payment_status === 'paid';
    }

    public function canComplete(): bool
    {
        // ✅ ALLOW COMPLETION IN MULTIPLE SCENARIOS:

        // 1. Booking is active (normal flow)
        $isActive = $this->booking_status === 'active';

        // 2. End date has passed (automatic completion scenario)
        $endDatePassed = $this->end_date && $this->end_date->isPast();

        // 3. Manual completion by parent/babysitter (even if end date not reached)
        $canManuallyComplete = $this->booking_status === 'active' &&
                              $this->start_date &&
                              $this->start_date->isPast();

        // 4. Emergency completion (admin or special cases)
        $hasValidPayment = $this->payment_status === 'paid';

        return ($isActive && $hasValidPayment) ||
               $endDatePassed ||
               $canManuallyComplete;
    }

    public function canCancel(): bool
    {
        return in_array($this->booking_status, ['pending_payment', 'confirmed']) &&
               !in_array($this->payment_status, ['paid', 'refunded']);
    }

    public function canRefund(): bool
    {
        return $this->payment_status === 'paid' &&
               in_array($this->booking_status, ['pending_payment', 'confirmed', 'active']) &&
               $this->payment_made_at &&
               $this->payment_made_at->gt(now()->subDays(7)); // Refund within 7 days
    }

    public function isActive(): bool
    {
        return $this->booking_status === 'active';
    }

    public function isCompleted(): bool
    {
        return $this->booking_status === 'completed';
    }

    public function isPaid(): bool
    {
        return $this->payment_status === 'paid';
    }

    public function isPendingPayment(): bool
    {
        return $this->booking_status === 'pending_payment' &&
               $this->payment_status === 'pending';
    }

    // ✅ NEW: Check if booking can be manually completed
    public function canManuallyComplete(): bool
    {
        return $this->booking_status === 'active' &&
               $this->payment_status === 'paid' &&
               $this->started_at !== null;
    }

    // ✅ NEW: Check if booking is overdue (end date passed but not completed)
    public function isOverdueBooking(): bool
    {
        return $this->end_date &&
               $this->end_date->isPast() &&
               !in_array($this->booking_status, ['completed', 'cancelled']);
    }

    // ✅ NEW: Check if booking should be auto-completed
    public function shouldAutoComplete(): bool
    {
        // Auto-complete if end date passed and booking is active
        return $this->end_date &&
               $this->end_date->isPast() &&
               $this->booking_status === 'active';
    }

    // Scopes
    public function scopeActive($query)
    {
        return $query->where('booking_status', 'active');
    }

    public function scopeCompleted($query)
    {
        return $query->where('booking_status', 'completed');
    }

    public function scopePendingPayment($query)
    {
        return $query->where('booking_status', 'pending_payment');
    }

    public function scopeByParent($query, $parentId)
    {
        return $query->where('parent_id', $parentId);
    }

    public function scopeByBabysitter($query, $babysitterId)
    {
        return $query->where('babysitter_id', $babysitterId);
    }

    public function scopePaid($query)
    {
        return $query->where('payment_status', 'paid');
    }

    public function scopeRefundable($query)
    {
        return $query->where('payment_status', 'paid')
                    ->whereIn('booking_status', ['pending_payment', 'confirmed', 'active'])
                    ->where('payment_made_at', '>', now()->subDays(7));
    }

    public function scopeExpired($query)
    {
        return $query->where('booking_status', 'pending_payment')
                    ->where('created_at', '<', now()->subHours(24));
    }

    // ✅ NEW: Scope for overdue bookings
    public function scopeOverdueBookings($query)
    {
        return $query->where('end_date', '<', now())
                    ->where('booking_status', 'active');
    }

    // ✅ NEW: Scope for auto-completable bookings
    public function scopeAutoCompletable($query)
    {
        return $query->where('end_date', '<', now())
                    ->where('booking_status', 'active')
                    ->where('payment_status', 'paid');
    }

    // ✅ NEW: Scope for manually completable bookings
    public function scopeManuallyCompletable($query)
    {
        return $query->where('booking_status', 'active')
                    ->where('payment_status', 'paid')
                    ->whereNotNull('started_at');
    }

    // ✅ NEW: Scope for upcoming bookings
    public function scopeUpcomingBookings($query)
    {
        return $query->where('start_date', '>', now())
                    ->whereIn('booking_status', ['confirmed', 'pending_payment']);
    }

    // Relationships
    public function bookingRequest()
    {
        return $this->belongsTo(DirectBookingRequest::class, 'booking_request_id', 'booking_request_id');
    }

    public function parent()
    {
        return $this->belongsTo(User::class, 'parent_id', 'user_id');
    }

    public function babysitter()
    {
        return $this->belongsTo(User::class, 'babysitter_id', 'user_id');
    }

    public function occupationCategory()
    {
        return $this->belongsTo(OccupationCategory::class, 'occupation_category_id', 'category_id');
    }

    public function payments()
    {
        return $this->hasMany(Payment::class, 'booking_id', 'booking_id');
    }

    // ✅ ADDED: Reviews relationship
    public function reviews()
    {
        return $this->hasMany(Review::class, 'booking_id', 'booking_id');
    }

    // Methods
    public function markAsConfirmed()
    {
        if ($this->booking_status !== 'pending_payment') {
            throw new \Exception('Booking is not in pending payment status');
        }

        $this->update([
            'booking_status' => 'confirmed',
            'confirmed_at' => now()
        ]);

        Log::info('✅ BOOKING CONFIRMED - Successfully:', [
            'booking_id' => $this->booking_id,
            'parent_id' => $this->parent_id,
            'babysitter_id' => $this->babysitter_id
        ]);
    }

    public function markAsActive()
    {
        if (!$this->canStart()) {
            throw new \Exception('Booking cannot be started in current status');
        }

        $this->update([
            'booking_status' => 'active',
            'started_at' => now()
        ]);

        Log::info('🎯 BOOKING STARTED - Marked as active:', [
            'booking_id' => $this->booking_id,
            'start_date' => $this->start_date,
            'started_at' => now()
        ]);
    }

    public function markAsCompleted($reason = null)
    {
        if (!$this->canComplete()) {
            throw new \Exception('Booking cannot be completed in current status: ' . $this->booking_status . '. Payment: ' . $this->payment_status);
        }

        $updateData = [
            'booking_status' => 'completed',
            'completed_at' => now()
        ];

        if ($reason) {
            $updateData['completion_reason'] = $reason;
        }

        $this->update($updateData);

        Log::info('🏁 BOOKING COMPLETED - Successfully:', [
            'booking_id' => $this->booking_id,
            'duration_weeks' => $this->total_weeks,
            'total_amount' => $this->total_amount,
            'reason' => $reason ?? 'manual_completion'
        ]);
    }

    // ✅ NEW: Force complete booking (for admin/special cases)
    public function forceComplete($reason = 'admin_force_complete')
    {
        $this->update([
            'booking_status' => 'completed',
            'completed_at' => now(),
            'completion_reason' => $reason
        ]);

        Log::warning('🔧 BOOKING FORCE COMPLETED - Admin action:', [
            'booking_id' => $this->booking_id,
            'reason' => $reason,
            'previous_status' => $this->getOriginal('booking_status')
        ]);
    }

    // ✅ NEW: Auto complete booking when end date passes
    public function autoCompleteIfNeeded()
    {
        if ($this->shouldAutoComplete()) {
            $this->markAsCompleted('auto_completed_end_date_passed');
            return true;
        }
        return false;
    }

    public function markAsCancelled($reason = null)
    {
        if (!$this->canCancel()) {
            throw new \Exception('Booking cannot be cancelled in current status');
        }

        $this->update([
            'booking_status' => 'cancelled',
            'cancelled_at' => now(),
            'cancellation_reason' => $reason
        ]);

        Log::info('❌ BOOKING CANCELLED - Marked as cancelled:', [
            'booking_id' => $this->booking_id,
            'reason' => $reason,
            'cancelled_at' => now()
        ]);
    }

    public function markPaymentAsPaid()
    {
        if (!$this->canConfirmAfterPayment()) {
            throw new \Exception('Booking cannot be marked as paid in current status');
        }

        $this->update([
            'payment_status' => 'paid',
            'booking_status' => 'confirmed',
            'payment_made_at' => now(),
            'confirmed_at' => now()
        ]);

        Log::info('💰 BOOKING PAID - Payment confirmed:', [
            'booking_id' => $this->booking_id,
            'total_amount' => $this->total_amount,
            'payment_made_at' => now()
        ]);
    }

    public function markAsRefunded($refundAmount = null)
    {
        $this->update([
            'payment_status' => 'refunded',
            'refunded_amount' => $refundAmount ?? $this->total_amount,
            'booking_status' => 'cancelled',
            'cancelled_at' => now()
        ]);

        Log::info('💸 BOOKING REFUNDED - Successfully:', [
            'booking_id' => $this->booking_id,
            'refund_amount' => $refundAmount ?? $this->total_amount,
            'refunded_at' => now()
        ]);
    }

    public function calculateRemainingHours()
    {
        $completedHours = 0; // You can integrate with time tracking later

        // If booking is completed, all hours are done
        if ($this->isCompleted()) {
            return 0;
        }

        // If booking is active, calculate based on elapsed time
        if ($this->isActive() && $this->started_at) {
            $elapsedHours = $this->started_at->diffInHours(now());
            $completedHours = min($elapsedHours, $this->total_hours);
        }

        return max(0, $this->total_hours - $completedHours);
    }

    public function calculateEarningsToDate()
    {
        $completedHours = 0;

        if ($this->isActive() && $this->started_at) {
            $elapsedHours = $this->started_at->diffInHours(now());
            $completedHours = min($elapsedHours, $this->total_hours);
        } elseif ($this->isCompleted()) {
            $completedHours = $this->total_hours;
        }

        return $completedHours * $this->agreed_hourly_rate;
    }

    public function calculateProgressPercentage()
    {
        if ($this->total_hours <= 0) {
            return 0;
        }

        $remainingHours = $this->calculateRemainingHours();
        $completedHours = $this->total_hours - $remainingHours;

        return round(($completedHours / $this->total_hours) * 100, 2);
    }

    public function getDurationDetails()
    {
        if (!$this->start_date) {
            return null;
        }

        $start = $this->start_date;
        $end = $this->end_date ?: $start->copy()->addWeeks($this->total_weeks);

        return [
            'start_date' => $start,
            'end_date' => $end,
            'total_days' => $start->diffInDays($end),
            'total_weeks' => $this->total_weeks,
            'is_ongoing' => $this->isActive() && now()->between($start, $end),
            'is_upcoming' => $start->isFuture(),
            'is_completed' => $end->isPast() || $this->isCompleted()
        ];
    }

    // ✅ NEW: Get booking completion eligibility details
    public function getCompletionEligibility()
    {
        return [
            'can_complete' => $this->canComplete(),
            'can_manual_complete' => $this->canManuallyComplete(),
            'should_auto_complete' => $this->shouldAutoComplete(),
            'is_overdue' => $this->isOverdueBooking(),
            'current_status' => $this->booking_status,
            'payment_status' => $this->payment_status,
            'start_date' => $this->start_date,
            'end_date' => $this->end_date,
            'started_at' => $this->started_at,
            'completed_at' => $this->completed_at,
            'reasons' => [
                'active_with_payment' => $this->booking_status === 'active' && $this->payment_status === 'paid',
                'end_date_passed' => $this->end_date && $this->end_date->isPast(),
                'start_date_passed' => $this->start_date && $this->start_date->isPast(),
                'has_started' => $this->started_at !== null
            ]
        ];
    }

    // ✅ NEW: Get reviews summary for this booking
    public function getReviewsSummary()
    {
        $reviews = $this->reviews;

        if ($reviews->isEmpty()) {
            return null;
        }

        $parentToBabysitter = $reviews->where('review_type', 'parent_to_babysitter');
        $babysitterToParent = $reviews->where('review_type', 'babysitter_to_parent');

        return [
            'total_reviews' => $reviews->count(),
            'parent_to_babysitter' => [
                'count' => $parentToBabysitter->count(),
                'average_rating' => $parentToBabysitter->avg('rating'),
                'would_recommend_percentage' => $parentToBabysitter->where('would_recommend', true)->count() / max(1, $parentToBabysitter->count()) * 100
            ],
            'babysitter_to_parent' => [
                'count' => $babysitterToParent->count(),
                'average_rating' => $babysitterToParent->avg('rating'),
                'would_recommend_percentage' => $babysitterToParent->where('would_recommend', true)->count() / max(1, $babysitterToParent->count()) * 100
            ]
        ];
    }
}
