<?php

namespace App\Http\Controllers\Tenant;

use App\Http\Controllers\Controller;
use App\Models\BillPayment;
use App\Models\UserWallet;
use App\Services\ActivityLogger;
use App\Services\BillPaymentService;
use App\Services\VirtualAccountService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\View\View;
use InvalidArgumentException;

class StaffWalletController extends Controller
{
    public function index(Request $request): View
    {
        $wallet = $this->wallet($request);

        return view('tenant.staff-wallet.index', [
            'wallet' => $wallet->load(['transactions' => fn ($query) => $query->latest()->limit(20)]),
            'billPayments' => BillPayment::with(['walletTransaction'])
                ->where('user_wallet_id', $wallet->id)
                ->latest()
                ->paginate(12)
                ->withQueryString(),
            'billPaymentServiceTypes' => BillPaymentService::serviceTypes(),
            'billPaymentProviders' => BillPaymentService::providers(),
            'billPaymentPackages' => BillPaymentService::packages(),
            'walletStats' => [
                'spent_today' => BillPayment::where('user_wallet_id', $wallet->id)
                    ->where('status', BillPayment::STATUS_SUCCESSFUL)
                    ->whereDate('created_at', today())
                    ->sum('total_amount'),
                'spent_month' => BillPayment::where('user_wallet_id', $wallet->id)
                    ->where('status', BillPayment::STATUS_SUCCESSFUL)
                    ->whereBetween('created_at', [now()->startOfMonth(), now()->endOfMonth()])
                    ->sum('total_amount'),
                'transactions' => $wallet->transactions()->count(),
            ],
        ]);
    }

    public function createVirtualAccount(Request $request, VirtualAccountService $accounts): RedirectResponse
    {
        $wallet = $this->wallet($request);
        $result = $accounts->createForStaffWallet($wallet);

        return back()->with($result['successful'] ? 'status' : 'warning', $result['message']);
    }

    public function payBill(Request $request, BillPaymentService $billPayments): RedirectResponse
    {
        $serviceTypes = array_keys(BillPaymentService::serviceTypes());
        $validated = $request->validate([
            'service_type' => ['required', Rule::in($serviceTypes)],
            'provider' => ['required', 'string', 'max:100'],
            'customer_identifier' => ['required', 'string', 'max:100'],
            'package_name' => ['nullable', 'string', 'max:150'],
            'amount' => ['required', 'numeric', 'min:1'],
            'notes' => ['nullable', 'string', 'max:1000'],
        ]);

        $providers = BillPaymentService::providers()[$validated['service_type']] ?? [];
        if (! in_array($validated['provider'], $providers, true)) {
            return back()->with('warning', 'Select a valid provider for this bill type.')->withInput();
        }

        try {
            $payment = $billPayments->userWalletPurchase($request->user(), $this->wallet($request), $validated);
        } catch (InvalidArgumentException $exception) {
            return back()->with('warning', $exception->getMessage())->withInput();
        }

        $message = $payment->status === BillPayment::STATUS_SUCCESSFUL
            ? 'Bill payment successful. Reference: '.$payment->reference
            : 'Bill payment submitted and pending provider confirmation. Reference: '.$payment->reference;

        return back()->with('status', $message);
    }

    private function wallet(Request $request): UserWallet
    {
        $user = $request->user();

        $wallet = UserWallet::firstOrCreate(
            ['tenant_id' => $user->tenant_id, 'user_id' => $user->id],
            [
                'currency' => $user->tenant?->settings['currency'] ?? 'NGN',
                'balance' => 0,
                'status' => 'active',
            ],
        );

        if ($wallet->wasRecentlyCreated) {
            ActivityLogger::log('staff_wallet_created', 'Staff wallet created for '.$user->name.'.', $wallet);
        }

        return $wallet;
    }
}
