<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Api\Concerns\ScopesApiToAccount;
use App\Models\Bill;
use App\Models\Visit;
use App\Services\Care\BillService;
use App\Services\Care\OrganizationResolver;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class BillController extends Controller
{
    use ScopesApiToAccount;

    public function __construct(
        protected BillService $bills,
    ) {}

    public function index(Request $request): JsonResponse
    {
        $this->authorizeAbility($request, 'bills.view');
        $organization = $this->organization($request);
        $branchScope = app(OrganizationResolver::class)->branchScope($this->member($request));

        $bills = $this->bills->list(
            $this->ownerRef($request),
            $organization->id,
            $request->only(['status', 'patient_id', 'per_page']),
            $branchScope,
        );

        return response()->json($bills);
    }

    public function generate(Request $request, Visit $visit): JsonResponse
    {
        $this->authorizeAbility($request, 'bills.manage');
        $this->authorizeVisit($request, $visit);

        $bill = $this->bills->generateFromVisit($visit, $this->ownerRef($request), $this->ownerRef($request));

        return response()->json($bill, 201);
    }

    public function show(Request $request, Bill $bill): JsonResponse
    {
        $this->authorizeAbility($request, 'bills.view');
        $this->authorizeBill($request, $bill);

        return response()->json($bill->load(['patient', 'lineItems', 'payments']));
    }

    public function recordPayment(Request $request, Bill $bill): JsonResponse
    {
        $this->authorizeAbility($request, 'payments.manage');
        $this->authorizeBill($request, $bill);

        $manualMethods = array_keys(collect(config('care.payment_methods', []))->except(['gateway'])->all());

        $payment = $this->bills->recordPayment(
            $bill,
            $this->ownerRef($request),
            $request->validate([
                'amount_minor' => ['required', 'integer', 'min:1'],
                'method' => ['required', 'string', 'in:'.implode(',', $manualMethods)],
                'reference' => ['nullable', 'string', 'max:100'],
            ]),
            $this->ownerRef($request),
        );

        return response()->json($payment, 201);
    }

    protected function authorizeBill(Request $request, Bill $bill): void
    {
        $this->authorizeOwner($request, $bill);
        abort_unless($bill->organization_id === $this->organization($request)->id, 404);
    }

    protected function authorizeVisit(Request $request, Visit $visit): void
    {
        $this->authorizeOwner($request, $visit);
        abort_unless($visit->organization_id === $this->organization($request)->id, 404);
    }
}
