<?php

namespace App\Http\Controllers\Api;

use App\Models\Invoice;
use App\Models\Payment;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;

class PaymentController extends BaseApiController
{
    protected string $model = Payment::class;
    protected array $with = ['invoice'];
    protected array $searchable = ['referenceNumber', 'paymentMethod'];
    protected array $filters = ['invoice' => 'invoice_id'];

    protected function rules(Request $request, ?Model $model = null): array
    {
        $required = $model ? 'sometimes' : 'required';
        return [
            'invoice' => "$required|string|exists:invoices,id",
            'referenceNumber' => 'nullable|string',
            'paymentMethod' => 'nullable|string',
            'paymentDate' => 'nullable|date',
            'paymentAmount' => 'nullable|numeric',
            'notes' => 'nullable|string',
        ];
    }

    protected function transform(Request $request, array $data): array
    {
        if (array_key_exists('invoice', $data)) {
            $data['invoice_id'] = $data['invoice'];
            unset($data['invoice']);
        }
        return $data;
    }

    public function store(Request $request): \Illuminate\Http\JsonResponse
    {
        $response = parent::store($request);
        $this->recomputeInvoice($request->input('invoice'));
        return $response;
    }

    public function update(Request $request, string $id): \Illuminate\Http\JsonResponse
    {
        $response = parent::update($request, $id);
        $payment = Payment::find($id);
        if ($payment) $this->recomputeInvoice($payment->invoice_id);
        return $response;
    }

    public function destroy(string $id): \Illuminate\Http\JsonResponse
    {
        $payment = Payment::find($id);
        $invoiceId = $payment?->invoice_id;
        $response = parent::destroy($id);
        if ($invoiceId) $this->recomputeInvoice($invoiceId);
        return $response;
    }

    private function recomputeInvoice(?string $invoiceId): void
    {
        if (!$invoiceId) return;
        $invoice = Invoice::find($invoiceId);
        if (!$invoice) return;
        $paid = (float) Payment::where('invoice_id', $invoiceId)->sum('paymentAmount');
        $invoice->paidAmount = $paid;
        if ($paid >= (float) $invoice->amount && (float) $invoice->amount > 0) {
            $invoice->status = 'PAID';
        } elseif ($paid > 0) {
            $invoice->status = 'PARTIAL';
        }
        $invoice->save();
    }
}
