<?php

use App\Models\Investment;
use App\Models\InvestmentPackage;
use App\Models\WalletTransaction;
use App\Jobs\Vrm\SendMail;
use App\Mail\AdminTransactionMail;
use App\Mail\DepositRequestRejectedMail;
use App\Mail\WalletTransactionMail;
use App\Services\DefaultCurrencyService;
use App\Services\Investment\SubscriptionService;
use App\Services\Sms\SmsNotifier;
use App\Services\Vrm\InvestmentEmailService;
use App\Traits\Vrm\Livewire\WithNotifications;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Computed;
use Livewire\Component;
use Livewire\WithPagination;

return new class extends Component {
    use WithNotifications;
    use WithPagination;

    public string $status = 'pending';

    #[Computed]
    public function subscriptionRequests()
    {
        return WalletTransaction::query()
            ->with(['user', 'wallet'])
            ->whereIn('type', ['deposit_request', 'mpesa_deposit_request'])
            ->where('meta->intent', SubscriptionService::META_INTENT_SUBSCRIPTION)
            ->when($this->status !== 'all', fn ($query) => $query->where('status', $this->status))
            ->latest()
            ->paginate(12, ['*'], 'requests_page');
    }

    #[Computed]
    public function subscriptions()
    {
        return Investment::query()
            ->with(['user', 'package'])
            ->latest()
            ->paginate(12, ['*'], 'subscriptions_page');
    }

    public function approve(int $transactionId): void
    {
        $transaction = WalletTransaction::query()->with(['wallet', 'user'])->find($transactionId);

        if (! $transaction || $transaction->status !== 'pending') {
            $this->notifyError(__('Request not available for approval.'));

            return;
        }

        if (($transaction->meta['intent'] ?? null) !== SubscriptionService::META_INTENT_SUBSCRIPTION) {
            $this->notifyError(__('Request is not a subscription request.'));

            return;
        }

        $packageId = (int) ($transaction->meta['package_id'] ?? 0);
        $amount = (float) ($transaction->meta['amount'] ?? $transaction->amount);

        $package = InvestmentPackage::query()->find($packageId);

        if (! $package || ! $transaction->wallet || ! $transaction->user) {
            $this->notifyError(__('Subscription details are incomplete for this request.'));

            return;
        }

        DB::transaction(function () use ($transaction, $package, $amount): void {
            $wallet = $transaction->wallet;

            $wallet->balance = (float) $wallet->balance + (float) $transaction->amount;
            $wallet->save();

            $transaction->status = 'approved';
            $transaction->approved_by = auth()->id();
            $transaction->approved_at = now();
            $transaction->save();

            app(SubscriptionService::class)->createSubscription($transaction->user, $wallet, $package, $amount);

            $meta = $transaction->meta ?? [];
            $meta['subscription_fulfilled'] = true;
            $transaction->meta = $meta;
            $transaction->save();
        });

        $transaction->refresh();

        if ($transaction->user?->email) {
            SendMail::dispatch($transaction->user->email, mailable: new WalletTransactionMail(
                $transaction->user->name,
                'deposit',
                $transaction->currency_code,
                (float) $transaction->amount,
                'approved',
                $transaction->phone_number ?: data_get($transaction->meta, 'phone_number', $transaction->user->phone),
                $transaction->transaction_code ?? data_get($transaction->meta, 'reference'),
                $transaction->updated_at?->format('M j, Y g:i A'),
            ));
            app(InvestmentEmailService::class)->sendSubscriptionCreated(
                $transaction->user->email,
                $transaction->user->name,
                $package->name,
                app(DefaultCurrencyService::class)->code(),
                $amount,
            );
        }
        app(SmsNotifier::class)->sendToPhone(
            $transaction->phone_number ?: data_get($transaction->meta, 'phone_number', $transaction->user?->phone),
            "Deposit request approved. Subscription request approved for {$package->name}.",
        );

        $adminEmail = config('mail.admin_address', 'admin@fxinvest.io');
        if (filled($adminEmail)) {
            SendMail::dispatch((string) $adminEmail, mailable: new AdminTransactionMail(
                $transaction->user?->name ?? 'Unknown',
                $transaction->user?->email ?? 'unknown@example.com',
                $amount,
                app(DefaultCurrencyService::class)->code(),
                'investment',
                'approved',
                'subscription',
                $transaction->transaction_code ?? data_get($transaction->meta, 'reference'),
            ));

            app(SmsNotifier::class)->sendToAdmins(
                "Subscription request approved for ".($transaction->user?->name ?? 'member').": ".app(DefaultCurrencyService::class)->code().' '.number_format((float) $amount, 2).'.',
            );
        }

        $this->notifySuccess(__('Subscription request approved.'));
    }

    public function reject(int $transactionId): void
    {
        $transaction = WalletTransaction::query()->with(['wallet', 'user'])->find($transactionId);

        if (! $transaction || $transaction->status !== 'pending') {
            $this->notifyError(__('Request not available for rejection.'));

            return;
        }

        if (($transaction->meta['intent'] ?? null) !== SubscriptionService::META_INTENT_SUBSCRIPTION) {
            $this->notifyError(__('Request is not a subscription request.'));

            return;
        }

        $transaction->status = 'rejected';
        $transaction->approved_by = auth()->id();
        $transaction->approved_at = now();
        $transaction->save();

        if ($transaction->user?->email) {
            SendMail::dispatch($transaction->user->email, mailable: new DepositRequestRejectedMail(
                $transaction->user->name,
                $transaction->currency_code,
                (float) $transaction->amount,
                $transaction->transaction_code ?? data_get($transaction->meta, 'reference'),
            ));
        }
        app(SmsNotifier::class)->sendToPhone(
            $transaction->phone_number ?: data_get($transaction->meta, 'phone_number', $transaction->user?->phone),
            'Deposit request rejected. Subscription request rejected.',
        );

        $adminEmail = config('mail.admin_address', 'admin@fxinvest.io');
        if (filled($adminEmail)) {
            SendMail::dispatch((string) $adminEmail, mailable: new AdminTransactionMail(
                $transaction->user?->name ?? 'Unknown',
                $transaction->user?->email ?? 'unknown@example.com',
                (float) (data_get($transaction->meta, 'amount') ?? $transaction->amount),
                app(DefaultCurrencyService::class)->code(),
                'investment',
                'rejected',
                'subscription',
                $transaction->transaction_code ?? data_get($transaction->meta, 'reference'),
            ));

            app(SmsNotifier::class)->sendToAdmins(
                "Subscription request rejected for ".($transaction->user?->name ?? 'member').": ".app(DefaultCurrencyService::class)->code().' '.number_format((float) (data_get($transaction->meta, 'amount') ?? $transaction->amount), 2).'.',
            );
        }

        $this->notifySuccess(__('Subscription request rejected.'));
    }

    protected function view($data = [])
    {
        return app('view')->file('/home/ziidfelj/home.ziidi.trade/storage/framework/views/livewire/views/8162ab37.blade.php', $data);
    }
}; 