<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Resources\InvoiceResource;
use App\Http\Support\ApiInputMapper;
use App\Models\Invoice;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Http\Response;

class InvoiceController extends Controller
{
    public function index(): AnonymousResourceCollection
    {
        $invoices = Invoice::query()->with('client')->orderByDesc('created_at')->get();

        return InvoiceResource::collection($invoices);
    }

    public function show(Invoice $invoice): InvoiceResource
    {
        $invoice->load('client');

        return new InvoiceResource($invoice);
    }

    public function store(Request $request): JsonResponse
    {
        $data = ApiInputMapper::invoice($request->all());
        $data['invoice_number'] = $this->nextInvoiceNumber();
        $invoice = Invoice::query()->create($data);
        $invoice->load('client');

        return (new InvoiceResource($invoice))
            ->response()
            ->setStatusCode(Response::HTTP_CREATED);
    }

    public function update(Request $request, Invoice $invoice): InvoiceResource
    {
        $data = ApiInputMapper::invoice($request->all());
        if ($request->filled('invoiceNumber')) {
            $data['invoice_number'] = $request->input('invoiceNumber');
        }
        $invoice->update($data);
        $invoice->load('client');

        return new InvoiceResource($invoice->fresh());
    }

    public function destroy(Invoice $invoice): JsonResponse
    {
        $invoice->delete();

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

    private function nextInvoiceNumber(): string
    {
        $year = (int) date('Y');
        $prefix = 'INV-'.$year.'-';
        $last = Invoice::query()
            ->where('invoice_number', 'like', $prefix.'%')
            ->orderByDesc('id')
            ->value('invoice_number');
        $n = 1;
        if ($last && preg_match('/^'.preg_quote($prefix, '/').'(\d+)$/', $last, $m)) {
            $n = (int) $m[1] + 1;
        }

        return $prefix.str_pad((string) $n, 3, '0', STR_PAD_LEFT);
    }
}
