<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Resources\InvoiceResource;
use App\Models\Invoice;
use App\Models\Payment;
use App\Services\LedgerService;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class InvoiceController extends Controller
{
    public function index(Request $request)
    {
        $query = Invoice::with(['patient', 'currency']);

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

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

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

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

        $invoices = $query->orderByDesc('invoice_date')->paginate($request->per_page ?? 20);

        return InvoiceResource::collection($invoices);
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'patient_id' => 'required|exists:patients,id',
            'invoice_date' => 'required|date',
            'due_date' => 'required|date|after_or_equal:invoice_date',
            'subtotal' => 'required|numeric|min:0',
            'tax_amount' => 'nullable|numeric|min:0',
            'discount_amount' => 'nullable|numeric|min:0',
            'currency_id' => 'required|exists:currencies,id',
            'notes' => 'nullable|string',
        ]);

        $data['created_by'] = auth()->id();
        
        // Calculate total
        $data['total_amount'] = $data['subtotal'] 
            + ($data['tax_amount'] ?? 0) 
            - ($data['discount_amount'] ?? 0);
        $data['paid_amount'] = 0;

        // Generate invoice number
        $lastId = Invoice::max('id') ?? 0;
        $data['invoice_number'] = 'INV-' . date('Y') . '-' . str_pad($lastId + 1, 6, '0', STR_PAD_LEFT);

        $invoice = Invoice::create($data);

        return new InvoiceResource($invoice);
    }

    public function show(Invoice $invoice)
    {
        return new InvoiceResource($invoice);
    }

    public function update(Request $request, Invoice $invoice)
    {
        if (in_array($invoice->status, ['paid', 'cancelled'])) {
            return response()->json(['message' => 'Cannot update paid or cancelled invoice'], 422);
        }

        $data = $request->validate([
            'invoice_date' => 'sometimes|date',
            'due_date' => 'sometimes|date',
            'subtotal' => 'sometimes|numeric|min:0',
            'tax_amount' => 'nullable|numeric|min:0',
            'discount_amount' => 'nullable|numeric|min:0',
            'notes' => 'nullable|string',
            'status' => ['sometimes', Rule::in(['draft', 'sent', 'paid', 'partial', 'overdue', 'cancelled'])],
        ]);

        if (isset($data['subtotal'])) {
            $data['total_amount'] = $data['subtotal'] 
                + ($data['tax_amount'] ?? $invoice->tax_amount) 
                - ($data['discount_amount'] ?? $invoice->discount_amount);
        }

        $invoice->update($data);

        return new InvoiceResource($invoice);
    }

    public function destroy(Invoice $invoice)
    {
        if ($invoice->payments()->exists()) {
            return response()->json(['message' => 'Cannot delete invoice with payments'], 422);
        }

        $invoice->delete();
        return response()->json(['message' => 'Invoice deleted successfully']);
    }

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

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

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

        return response()->json([
            'total_invoices' => $query->count(),
            'total_amount' => $query->sum('total_amount'),
            'total_paid' => $query->sum('paid_amount'),
            'total_outstanding' => $query->sum('balance'),
            'by_status' => $query->selectRaw('status, count(*) as count, sum(total_amount) as amount')
                ->groupBy('status')
                ->get(),
        ]);
    }
}
