<?php

namespace App\Http\Requests\Sales;

use App\Http\Requests\BaseFormRequest;
use App\Models\TaxInvoice;
use App\Models\SalesPayment;
use App\Models\SalesCreditNote;
use App\Models\SalesDebitNote;
use Illuminate\Validation\Validator;

class StorePaymentRequest extends BaseFormRequest
{
    public function rules(): array
    {
        return [
            'invoice_id' => 'required|exists:tax_invoices,id',
            'payment_date' => 'required|date|before_or_equal:today',
            'payment_amount' => 'required|numeric|min:0.01|max:99999999.99',
            'payment_method' => 'required|string|in:cash,cheque,bank_transfer,upi,neft,rtgs,card,other',
            'reference_no' => 'nullable|string|max:100',
            'notes' => 'nullable|string|max:2000',
        ];
    }

    /**
     * Configure the validator instance.
     */
    public function withValidator(Validator $validator): void
    {
        $validator->after(function (Validator $validator) {
            $this->validatePaymentAmount($validator);
        });
    }

    /**
     * Validate payment doesn't exceed outstanding balance
     */
    protected function validatePaymentAmount(Validator $validator): void
    {
        $invoiceId = $this->input('invoice_id');
        $paymentAmount = floatval($this->input('payment_amount', 0));

        if (!$invoiceId) {
            return;
        }

        $invoice = TaxInvoice::find($invoiceId);
        if (!$invoice) {
            return;
        }

        // Calculate outstanding balance
        $totalAmount = floatval($invoice->total_amount ?? 0);
        $existingPayments = SalesPayment::where('invoice_id', $invoiceId)->sum('payment_amount');
        $creditAmount = SalesCreditNote::where('invoice_no', $invoice->invoice_no)->sum('amount');
        $debitAmount = SalesDebitNote::where('invoice_no', $invoice->invoice_no)->sum('amount');

        // Balance = Invoice + Debit Notes - Payments - Credit Notes
        $balance = $totalAmount + floatval($debitAmount) - floatval($existingPayments) - floatval($creditAmount);

        if ($paymentAmount > $balance) {
            $validator->errors()->add(
                'payment_amount',
                'Payment amount (₹' . number_format($paymentAmount, 2) . ') exceeds outstanding balance (₹' . number_format($balance, 2) . ').'
            );
        }
    }

    public function attributes(): array
    {
        return [
            'invoice_id' => 'Invoice',
            'payment_date' => 'Payment Date',
            'payment_amount' => 'Payment Amount',
            'payment_method' => 'Payment Method',
            'reference_no' => 'Reference Number',
        ];
    }

    public function messages(): array
    {
        return [
            'payment_date.before_or_equal' => 'Payment date cannot be in the future.',
            'payment_amount.max' => 'Payment amount cannot exceed ₹9,99,99,999.99.',
            'payment_method.in' => 'Please select a valid payment method.',
        ];
    }
}
