<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\Api\StoreCustomerRequest;
use App\Http\Requests\Api\UpdateCustomerRequest;
use App\Http\Resources\CustomerResource;
use App\Models\Customer;
use App\Models\User;
use App\Services\CustomerService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Http\Response;

class CustomerController extends Controller
{
    public function __construct(private CustomerService $customers) {}

    public function index(): AnonymousResourceCollection
    {
        return CustomerResource::collection(
            Customer::query()
                ->with(['creator', 'agent', 'nominee.documents'])
                ->latest('id')
                ->get(),
        );
    }

    public function store(StoreCustomerRequest $request): JsonResponse
    {
        $actor = $request->user();

        assert($actor instanceof User);

        $customer = $this->customers->create($actor, $request->payload(), $request->nomineeDocuments());

        return CustomerResource::make($customer->loadMissing(['creator', 'agent', 'nominee.documents']))
            ->response()
            ->setStatusCode(201);
    }

    public function show(Customer $customer): CustomerResource
    {
        return CustomerResource::make($customer->loadMissing(['creator', 'agent', 'documents', 'nominee.documents']));
    }

    public function update(UpdateCustomerRequest $request, Customer $customer): CustomerResource
    {
        $actor = $request->user();

        assert($actor instanceof User);

        $customer = $this->customers->update(
            $customer,
            $actor,
            $request->payload(),
            $request->nomineeDocuments(),
        );

        return CustomerResource::make($customer->loadMissing(['creator', 'agent', 'documents', 'nominee.documents']));
    }

    public function destroy(Customer $customer): Response
    {
        $this->customers->delete($customer);

        return response()->noContent();
    }
}
