<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Resources\PaymentResource;
use App\Models\Invoice;
use App\Models\Payment;
use App\Services\LedgerService;
use Illuminate\Http\Request;

class PaymentController extends Controller
{
    public function index(Request $request)
    {
        $query = Payment::with(['invoice.patient', 'receivedBy']);

        if ($request->has('invoice_id')) {
            $query->where('invoice_id', $request->invoice_id);
        }

        if ($request->has('patient_id')) {
            $query->whereHas('invoice', function ($q) use ($request) {
                $q->where('patient_id', $request->patient_id);
            });
        }

        if ($request->has('date_from')) {
            $query->whereDate('payment_date', '>=', $request->date_from);
        }

        if ($request->has('date_to')) {
            $query->whereDate('payment_date', '<=', $request->date_to);
        }

        $payments = $query->orderByDesc('payment_date')->paginate($request->per_page ?? 20);

        return PaymentResource::collection($payments);
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'invoice_id' => 'required|exists:invoices,id',
            'payment_date' => 'required|date',
            'amount' => 'required|numeric|min:0.01',
            'payment_method' => 'required|in:cash,card,bank_transfer,check,insurance,other',
            'reference_number' => 'nullable|string|max:255',
            'notes' => 'nullable|string',
        ]);

        $invoice = Invoice::findOrFail($data['invoice_id']);

        // Check if payment exceeds balance
        if ($data['amount'] > $invoice->balance) {
            return response()->json([
                'message' => 'Payment amount exceeds invoice balance',
                'balance' => $invoice->balance,
            ], 422);
        }

        $data['received_by'] = auth()->id();
        
        // Generate payment number
        $lastId = Payment::max('id') ?? 0;
        $data['payment_number'] = 'PAY-' . date('Y') . '-' . str_pad($lastId + 1, 6, '0', STR_PAD_LEFT);

        $payment = Payment::create($data);

        // Update invoice
        $invoice->paid_amount += $data['amount'];
        $invoice->status = $invoice->paid_amount >= $invoice->total_amount ? 'paid' : 'partial';
        $invoice->save();

        // Create ledger entry
        $ledgerService = new LedgerService();
        $ledgerService->recordPayment($payment);

        return new PaymentResource($payment);
    }

    public function show(Payment $payment)
    {
        return new PaymentResource($payment);
    }

    public function destroy(Payment $payment)
    {
        // Revert invoice payment
        $invoice = $payment->invoice;
        $invoice->paid_amount -= $payment->amount;
        $invoice->status = $invoice->paid_amount <= 0 ? 'sent' : 'partial';
        $invoice->save();

        $payment->delete();

        return response()->json(['message' => 'Payment deleted successfully']);
    }

    public function summary(Request $request)
    {
        $query = Payment::query();

        if ($request->has('date_from')) {
            $query->whereDate('payment_date', '>=', $request->date_from);
        }

        if ($request->has('date_to')) {
            $query->whereDate('payment_date', '<=', $request->date_to);
        }

        return response()->json([
            'total_payments' => $query->count(),
            'total_amount' => $query->sum('amount'),
            'by_method' => $query->selectRaw('payment_method, count(*) as count, sum(amount) as amount')
                ->groupBy('payment_method')
                ->get(),
        ]);
    }
}
