<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Http\Requests\PaymentStoreRequest;
use App\Http\Requests\RefundTransactionRequest;
use App\Http\Requests\WaiverRequest;
use App\Http\Resources\TransactionResource;
use App\Models\Appointment;
use App\Models\PaymentTransaction;
use App\Services\AccessService;
use App\Services\PaymentService;
use App\Support\ApiResponse;
use Illuminate\Http\Request;

class TransactionController extends Controller
{
    use ApiResponse;

    public function __construct(
        private readonly AccessService $access,
        private readonly PaymentService $payments,
    ) {}

    public function index(Request $request)
    {
        $user = $request->user();

        $query = PaymentTransaction::query()
            ->where('organization_id', $user->organization_id)
            ->whereHas('appointment', function ($appointments) use ($user) {
                $this->access->scopeAppointments($appointments, $user);
            });

        foreach (['appointment_id', 'patient_id', 'location_id'] as $field) {
            if ($request->filled($field)) {
                $query->where($field, $request->integer($field));
            }
        }

        if ($request->filled('type')) {
            $query->where('type', $request->string('type'));
        }
        if ($request->filled('status')) {
            $query->where('status', $request->string('status'));
        }
        if ($request->filled('date_from')) {
            $query->where('created_at', '>=', $request->date('date_from')->startOfDay());
        }
        if ($request->filled('date_to')) {
            $query->where('created_at', '<=', $request->date('date_to')->endOfDay());
        }

        $paginator = $query->orderByDesc('id')
            ->paginate(min(100, max(1, $request->integer('per_page', 20))));

        return $this->paginated($paginator, TransactionResource::collection($paginator->getCollection()));
    }

    public function payment(PaymentStoreRequest $request, Appointment $appointment)
    {
        $transaction = $this->payments->collect($request->user(), $appointment, $request->validated());

        return $this->success(new TransactionResource($transaction), 'Payment recorded.', 201);
    }

    public function waiver(WaiverRequest $request, Appointment $appointment)
    {
        $transaction = $this->payments->waive(
            $request->user(),
            $appointment,
            (float) $request->input('amount'),
            $request->string('reason')->toString()
        );

        return $this->success(new TransactionResource($transaction), 'Waiver recorded.', 201);
    }

    public function refund(RefundTransactionRequest $request, PaymentTransaction $transaction)
    {
        $transaction = $this->payments->refund($request->user(), $transaction, $request->validated());

        return $this->success(new TransactionResource($transaction), 'Refund recorded.', 201);
    }
}
