<?php

namespace App\Services;

use App\Models\Booking;
use App\Models\Invoice;
use App\Models\Transaction;
use Carbon\Carbon;

class BalanceService
{
    /**
     * Calculate all balance metrics for a specific booking.
     * (Rule 2: Smart Balance Engine)
     */
    public function calculateForBooking(Booking $booking)
    {
        $totalPrice = $booking->total_price - $booking->discount;
        $downPayment = $booking->booking_amount;
        
        // Invoices related to this booking (customer + property combination)
        $invoices = Invoice::where('customer_id', $booking->customer_id)
            ->where('property_id', $booking->property_id)
            ->get();
            
        $invoiceIds = $invoices->pluck('id');
        
        // Paid amount is the sum of approved transactions linked to these invoices
        $paid = Transaction::whereIn('invoice_id', $invoiceIds)
            ->where('status', 'Approved')
            ->sum('amount');
            
        // Also consider unassigned transactions (no invoice_id) for this customer as advance?
        // For strict property-level accounting, it's safer to only count transactions linked to property invoices.
        // If a customer has multiple properties, unlinked transactions are ambiguous.
            
        $remaining = max(0, $totalPrice - $paid);
        
        // Overdue includes explicitly 'Overdue' invoices and 'Unpaid' ones past their date
        $overdue = $invoices->where('status', 'Overdue')->sum('amount');
        
        $unpaidOverdue = $invoices->where('status', 'Unpaid')
            ->filter(function($invoice) {
                return Carbon::parse($invoice->date)->isPast();
            })->sum('amount');
            
        $totalOverdue = $overdue + $unpaidOverdue;
        
        // Advance payment logic: if Paid > sum of all due/billed invoices
        $totalBilled = $invoices->sum('amount');
        $advance = max(0, $paid - $totalBilled);
        
        return [
            'total_price' => $totalPrice,
            'down_payment' => $downPayment,
            'paid' => $paid,
            'remaining' => $remaining,
            'overdue' => $totalOverdue,
            'advance' => $advance,
            'total_billed' => $totalBilled,
        ];
    }

    /**
     * Validate if a new payment amount exceeds the outstanding balance.
     * (Rule 6: Payment Intelligence)
     */
    public function exceedsOutstandingBalance(Booking $booking, $paymentAmount)
    {
        $balances = $this->calculateForBooking($booking);
        
        // If payment is strictly for remaining balance and not marked as advance
        if ($paymentAmount > $balances['remaining']) {
            return true;
        }
        
        return false;
    }
}
