<?php

namespace App\Services\Rental;

use App\Models\Rental\Receipt;
use App\Models\Rental\Rental;
use Illuminate\Support\Facades\DB;

class ReceiptService
{
    public function createReceipt(array $data)
    {
        return DB::transaction(function () use ($data) {
            $rental = null;
            $customerId = null;

            if ($data['rental_id'] ?? null) {
                $rental = Rental::findOrFail($data['rental_id']);
                
                // Check if contract is cancelled
                if ($rental->status === 'cancelled') {
                    throw new \Exception('Cannot create receipt for a cancelled contract.');
                }
                
                $customerId = $rental->customer_id;
            } else {
                $customerId = $data['customer_id'] ?? null;
            }

            $receipt = Receipt::create([
                'receipt_number' => $this->generateReceiptNumber(),
                'rental_id' => $rental->id ?? null,
                'customer_id' => $customerId,
                'amount' => $data['amount'],
                'payment_method' => $data['payment_method'],
                'payment_type' => $data['payment_type'],
                'reference_number' => $data['reference_number'] ?? null,
                'notes' => $data['notes'] ?? null,
                'received_by' => auth()->id(),
                'status' => 'confirmed',
                'receipt_date' => now(),
            ]);

            if ($rental) {
                $this->updateRentalBalances($rental);
            }

            return $receipt;
        });
    }

    public function cancelReceipt(Receipt $receipt)
    {
        return DB::transaction(function () use ($receipt) {
            if ($receipt->status === 'cancelled') {
                return $receipt;
            }

            $receipt->update(['status' => 'cancelled']);
            $this->updateRentalBalances($receipt->rental);

            return $receipt;
        });
    }

    public function updateRentalBalances(Rental $rental)
    {
        $paidAmount = $rental->receipts()
            ->where('status', 'confirmed')
            ->sum('amount');

        $rental->update([
            'paid_amount' => $paidAmount,
            'remaining_amount' => $rental->total_amount - $paidAmount
        ]);
    }

    private function generateReceiptNumber()
    {
        $year = date('Y');
        $lastReceipt = Receipt::whereYear('created_at', $year)
            ->orderBy('id', 'desc')
            ->first();

        $nextNumber = $lastReceipt ? ((int) substr($lastReceipt->receipt_number, -6)) + 1 : 1;
        
        return sprintf('RC-%s-%06d', $year, $nextNumber);
    }
}
