<?php

namespace App\Http\Controllers\Admin;

use App\Core\Repositories\CustomerRepository;
use App\Core\Repositories\InvoiceRepository;
use App\Core\Repositories\PaymentRepository;
use App\Core\Services\Payment\PaymentService;
use App\Http\Controllers\Controller;
use App\Models\BankAccount;
use App\Models\Payment;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class PaymentController extends Controller
{
    public function __construct(
        private PaymentService $paymentService,
        private InvoiceRepository $invoiceRepository,
        private PaymentRepository $paymentRepository,
        private CustomerRepository $customerRepository
    ) {}

    /**
     * Display a listing of payments
     */
    public function index(Request $request): View
    {
        $this->authorize('viewAny', Payment::class);

        $filters = [
            'status' => $request->get('status'),
            'customer_id' => $request->get('customer_id'),
            'invoice_id' => $request->get('invoice_id'),
            'date_from' => $request->get('date_from'),
            'date_to' => $request->get('date_to'),
        ];

        $payments = $this->paymentRepository->getPaginated(15, $filters);
        $customers = $this->customerRepository->getAll();

        return view('admin.payments.index', [
            'payments' => $payments,
            'customers' => $customers,
            'filters' => $filters,
        ]);
    }

    /**
     * Show the form for creating a new payment
     */
    public function create(Request $request): View
    {
        $this->authorize('create', Payment::class);

        $invoiceId = $request->get('invoice_id');
        $invoice = $invoiceId ? $this->invoiceRepository->getById($invoiceId) : null;

        $invoices = $this->invoiceRepository->getAll();

        $bankAccounts = BankAccount::where('is_active', true)
            ->orderBy('is_default', 'desc')
            ->orderBy('account_name')
            ->get();

        return view('admin.payments.create', [
            'invoice' => $invoice,
            'invoices' => $invoices,
            'bankAccounts' => $bankAccounts,
        ]);
    }

    /**
     * Store a newly created payment
     */
    public function store(Request $request): RedirectResponse
    {
        $this->authorize('create', Payment::class);

        $validated = $request->validate([
            'invoice_id' => 'required|exists:invoices,id',
            'amount' => 'required|numeric|min:0.01',
            'payment_method' => 'nullable|in:cash,bank_transfer,account_transfer,credit_card,paypal,stripe,cheque,online_payment,other',
            'payment_date' => 'required|date',
            'bank_account_id' => 'nullable|exists:bank_accounts,id',
            'notes' => 'nullable|string',
            'transaction_id' => 'nullable|string',
            'reference' => 'nullable|string',
        ]);

        $invoice = $this->invoiceRepository->getById($validated['invoice_id']);

        if (! $invoice) {
            return redirect()->back()->withErrors(['invoice_id' => 'Invoice not found.']);
        }

        $payment = $this->paymentService->recordPayment($invoice, $validated);

        return redirect()
            ->route('admin.payments.show', $payment)
            ->with('success', 'Payment recorded successfully.');
    }

    /**
     * Display the specified payment
     */
    public function show(Payment $payment): View
    {
        $this->authorize('view', $payment);

        $payment->load(['invoice', 'customer']);

        return view('admin.payments.show', [
            'payment' => $payment,
        ]);
    }

    /**
     * Refund a payment
     */
    public function refund(Payment $payment): RedirectResponse
    {
        $this->authorize('refund', $payment);

        $this->paymentService->refundPayment($payment);

        return redirect()
            ->route('admin.payments.show', $payment)
            ->with('success', 'Payment refunded successfully.');
    }
}
