<?php

use App\Models\Investment;
use App\Models\Wallet;
use App\Models\WalletTransaction;
use App\Jobs\Vrm\SendMail;
use App\Mail\AdminTransactionMail;
use App\Mail\WalletTransactionMail;
use App\Services\DefaultCurrencyService;
use App\Services\MemberNotificationService;
use App\Services\Vrm\InvestmentEmailService;
use App\Traits\Vrm\Livewire\WithNotifications;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\Computed;
use Livewire\Component;
use Livewire\WithPagination;

new class extends Component {
    use WithNotifications;
    use WithPagination;

    public string $status = 'all';
    public string $search = '';
    public array $maturityInputs = [];

    public function updatedStatus(): void
    {
        $this->resetPage('investments_page');
    }

    public function updatedSearch(): void
    {
        $this->resetPage('investments_page');
    }

    public function updateMaturity(int $investmentId): void
    {
        $investment = Investment::query()->find($investmentId);

        if (! $investment) {
            $this->notifyError(__('Investment not found.'));

            return;
        }

        $value = trim((string) data_get($this->maturityInputs, (string) $investmentId, ''));
        if ($value === '') {
            $this->notifyError(__('Please provide a maturity date and time.'));

            return;
        }

        try {
            $maturesAt = Carbon::parse($value);
        } catch (\Throwable) {
            $this->notifyError(__('Invalid maturity date and time.'));

            return;
        }

        if ($maturesAt->lessThan($investment->started_at)) {
            $this->notifyError(__('Maturity date cannot be before investment start.'));

            return;
        }

        $durationHours = max(1, (int) $investment->started_at->diffInHours($maturesAt));

        $investment->matures_at = $maturesAt;
        $investment->duration_hours = $durationHours;
        $investment->duration_days = max(1, (int) ceil($durationHours / 24));
        $investment->save();

        $this->notifySuccess(__('Investment maturity updated successfully.'));
    }

    public function closeAsSuccess(int $investmentId): void
    {
        $notifiedInvestment = null;

        DB::transaction(function () use ($investmentId, &$notifiedInvestment): void {
            $investment = Investment::query()
                ->whereKey($investmentId)
                ->with('user')
                ->lockForUpdate()
                ->first();

            if (! $investment) {
                $this->notifyError(__('Investment not found.'));

                return;
            }

            if (! $investment->is_active) {
                $this->notifyError(__('Only active investments can be closed.'));

                return;
            }

            $wallet = Wallet::query()->whereKey($investment->wallet_id)->lockForUpdate()->first();
            if (! $wallet) {
                $this->notifyError(__('Wallet not found for this investment.'));

                return;
            }

            $returnAmount = (float) $investment->expected_return_amount;
            $principalAmount = (float) $investment->principal_amount;

            $wallet->balance = (float) $wallet->balance + $returnAmount;
            $wallet->earned_amount = (float) $wallet->earned_amount + ($returnAmount - $principalAmount);
            $wallet->save();

            $investment->status = 'claimed';
            $investment->is_active = false;
            $investment->claimed_at = now();
            $investment->matures_at = now();
            $investment->save();

            WalletTransaction::query()->create([
                'wallet_id' => $wallet->id,
                'user_id' => $investment->user_id,
                'type' => 'investment_credit',
                'status' => 'completed',
                'amount' => $returnAmount,
                'currency_code' => $this->currencyCode,
                'description' => __('Investment completed by admin'),
                'meta' => [
                    'investment_id' => $investment->id,
                    'principal_amount' => $principalAmount,
                    'admin_completed' => true,
                ],
            ]);

            $notifiedInvestment = $investment;

            $this->notifySuccess(__('Investment closed as success.'));
        });

        if ($notifiedInvestment?->user?->email) {
            app(InvestmentEmailService::class)->sendInvestmentClaimed(
                $notifiedInvestment->user->email,
                $notifiedInvestment->user->name,
                $this->currencyCode,
                (float) $notifiedInvestment->expected_return_amount,
            );
        }

        $adminEmail = config('mail.admin_address', 'admin@fxinvest.io');
        if ($notifiedInvestment && filled($adminEmail)) {
            SendMail::dispatch((string) $adminEmail, mailable: new AdminTransactionMail(
                $notifiedInvestment->user?->name ?? 'Unknown',
                $notifiedInvestment->user?->email ?? 'unknown@example.com',
                (float) $notifiedInvestment->expected_return_amount,
                $this->currencyCode,
                'investment',
                'approved',
                'admin',
                (string) $notifiedInvestment->id,
            ), notificationType: 'admin_transaction');
        }

        if ($notifiedInvestment) {
            app(MemberNotificationService::class)->notifyInvestmentReviewed($notifiedInvestment, 'approved');
            app(MemberNotificationService::class)->notifyInvestmentCompleted($notifiedInvestment);
        }
    }

    public function closeAsFailure(int $investmentId): void
    {
        $investment = Investment::query()->with('user')->find($investmentId);

        if (! $investment) {
            $this->notifyError(__('Investment not found.'));

            return;
        }

        if (! $investment->is_active) {
            $this->notifyError(__('Only active investments can be closed.'));

            return;
        }

        $investment->status = 'failed';
        $investment->is_active = false;
        $investment->claimed_at = now();
        $investment->matures_at = now();
        $investment->save();

        app(MemberNotificationService::class)->notifyInvestmentReviewed($investment, 'rejected');

        if ($investment->user?->email) {
            SendMail::dispatch($investment->user->email, mailable: new WalletTransactionMail(
                $investment->user->name,
                'investment',
                $this->currencyCode,
                (float) $investment->principal_amount,
                'rejected',
                $investment->user->phone,
                (string) $investment->id,
                now()->format('M j, Y g:i A'),
            ), notificationType: 'user_transaction');
        }

        $adminEmail = config('mail.admin_address', 'admin@fxinvest.io');
        if (filled($adminEmail)) {
            SendMail::dispatch((string) $adminEmail, mailable: new AdminTransactionMail(
                $investment->user?->name ?? 'Unknown',
                $investment->user?->email ?? 'unknown@example.com',
                (float) $investment->principal_amount,
                $this->currencyCode,
                'investment',
                'rejected',
                'admin',
                (string) $investment->id,
            ), notificationType: 'admin_transaction');
        }

        $this->notifySuccess(__('Investment closed as failure.'));
    }

    #[Computed]
    public function investments()
    {
        return Investment::query()
            ->with(['user', 'package'])
            ->when($this->status !== 'all', fn ($query) => $query->where('status', $this->status))
            ->when($this->search !== '', function ($query): void {
                $query->whereHas('user', function ($userQuery): void {
                    $userQuery->where('name', 'like', "%{$this->search}%")
                        ->orWhere('email', 'like', "%{$this->search}%");
                });
            })
            ->latest()
            ->paginate(12, ['*'], 'investments_page');
    }

    #[Computed]
    public function currencyCode(): string
    {
        return app(DefaultCurrencyService::class)->code();
    }
}; ?>

<div>
    <x-admin-panel>
        <x-slot name="header">{{ __('Investment Portfolio') }}</x-slot>
        <x-slot name="desc">{{ __('Review member package subscriptions, gain progress, and maturity status.') }}</x-slot>

        {!! $this->renderNotification() !!}

        <div class="mb-4 grid gap-4 md:grid-cols-2">
            <div>
                <label class="block text-sm/6 font-medium text-gray-900 dark:text-gray-100">{{ __('Status Filter') }}</label>
                <select wire:model.live="status"
                    class="mt-1 block w-full rounded-md bg-white dark:bg-gray-700 px-3 py-1.5 text-base text-gray-900 dark:text-gray-100 outline-1 -outline-offset-1 outline-gray-300 dark:outline-gray-600 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6">
                    <option value="all">{{ __('All') }}</option>
                    <option value="active">{{ __('Active') }}</option>
                    <option value="claimed">{{ __('Claimed') }}</option>
                    <option value="cancelled">{{ __('Cancelled') }}</option>
                    <option value="failed">{{ __('Failed') }}</option>
                </select>
            </div>
            <div>
                <label class="block text-sm/6 font-medium text-gray-900 dark:text-gray-100">{{ __('Search Member') }}</label>
                <input type="text" wire:model.live.debounce.300ms="search"
                    class="mt-1 block w-full rounded-md bg-white dark:bg-gray-700 px-3 py-1.5 text-base text-gray-900 dark:text-gray-100 outline-1 -outline-offset-1 outline-gray-300 dark:outline-gray-600 placeholder:text-gray-400 dark:placeholder:text-gray-500 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6"
                    placeholder="{{ __('Search by member name or email...') }}" />
            </div>
        </div>

        <div class="overflow-hidden shadow-sm ring-1 ring-black/5 dark:ring-white/10 sm:rounded-lg mt-2">
            <table class="min-w-full divide-y divide-gray-300 dark:divide-gray-600">
                <thead class="bg-gray-50 dark:bg-gray-700">
                    <tr>
                        <th class="py-3.5 pr-3 pl-4 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">{{ __('Member') }}</th>
                        <th class="py-3.5 px-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">{{ __('Package') }}</th>
                        <th class="py-3.5 px-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">{{ __('Principal') }}</th>
                        <th class="py-3.5 px-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">{{ __('Expected') }}</th>
                        <th class="py-3.5 px-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">{{ __('Accrued') }}</th>
                        <th class="py-3.5 px-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">{{ __('Progress') }}</th>
                        <th class="py-3.5 px-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">{{ __('Status') }}</th>
                        <th class="py-3.5 pr-4 pl-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">{{ __('Matures') }}</th>
                        <th class="py-3.5 pr-4 pl-3 text-left text-sm font-semibold text-gray-900 dark:text-gray-100">{{ __('Actions') }}</th>
                    </tr>
                </thead>
                <tbody class="bg-white dark:bg-gray-800">
                    @forelse ($this->investments as $investment)
                        <tr class="even:bg-gray-50 dark:even:bg-gray-800/50">
                            <td class="py-4 pr-3 pl-4 text-sm text-gray-900 dark:text-gray-100">
                                <p class="font-semibold">{{ $investment->user?->name ?? '-' }}</p>
                                <p class="text-xs text-gray-500">{{ $investment->user?->email ?? '-' }}</p>
                            </td>
                            <td class="py-4 px-3 text-sm text-gray-900 dark:text-gray-100">{{ $investment->package?->name ?? '-' }}</td>
                            <td class="py-4 px-3 text-sm text-gray-900 dark:text-gray-100">{{ $this->currencyCode }} {{ number_format((float) $investment->principal_amount, 2) }}</td>
                            <td class="py-4 px-3 text-sm text-gray-900 dark:text-gray-100">{{ $this->currencyCode }} {{ number_format((float) $investment->expected_return_amount, 2) }}</td>
                            <td class="py-4 px-3 text-sm text-gray-900 dark:text-gray-100">{{ $this->currencyCode }} {{ number_format((float) $investment->accrued_amount, 2) }}</td>
                            <td class="py-4 px-3 text-sm text-gray-900 dark:text-gray-100">
                                <div class="w-40">
                                    <div class="h-2 rounded bg-gray-200 dark:bg-gray-700">
                                        <div class="h-2 rounded bg-indigo-500" style="width: {{ max(0, min(100, (int) round($investment->progress_ratio * 100))) }}%"></div>
                                    </div>
                                    <p class="mt-1 text-xs text-gray-500">{{ number_format($investment->progress_ratio * 100, 1) }}%</p>
                                </div>
                            </td>
                            <td class="py-4 px-3 text-sm text-gray-900 dark:text-gray-100">{{ ucfirst($investment->status) }}</td>
                            <td class="py-4 pr-4 pl-3 text-sm text-gray-500 dark:text-gray-400">{{ $investment->matures_at?->format('M j, Y g:i A') ?? '-' }}</td>
                            <td class="py-4 pr-4 pl-3 text-sm text-gray-500 dark:text-gray-400">
                                @if ($investment->is_active)
                                    <div class="flex w-64 flex-col gap-2">
                                        <div class="flex items-center gap-2">
                                            <input
                                                type="datetime-local"
                                                wire:model="maturityInputs.{{ $investment->id }}"
                                                value="{{ ($maturityInputs[$investment->id] ?? $investment->matures_at?->format('Y-m-d\\TH:i')) }}"
                                                class="block w-full rounded-md border border-gray-300 bg-white px-2 py-1 text-xs text-gray-900 outline-none focus:border-indigo-500 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100"
                                            />
                                            <button type="button" wire:click="updateMaturity({{ $investment->id }})"
                                                class="rounded bg-gray-900 px-2 py-1 text-xs font-semibold text-white dark:bg-gray-100 dark:text-gray-900">
                                                {{ __('Save') }}
                                            </button>
                                        </div>
                                        <div class="flex gap-2">
                                            <button type="button" wire:confirm="{{ __('Close this investment as success?') }}" wire:click="closeAsSuccess({{ $investment->id }})"
                                                class="rounded bg-emerald-600 px-2 py-1 text-xs font-semibold text-white">
                                                {{ __('Mark Success') }}
                                            </button>
                                            <button type="button" wire:confirm="{{ __('Close this investment as failure?') }}" wire:click="closeAsFailure({{ $investment->id }})"
                                                class="rounded bg-rose-600 px-2 py-1 text-xs font-semibold text-white">
                                                {{ __('Mark Failure') }}
                                            </button>
                                        </div>
                                    </div>
                                @else
                                    <span class="text-xs text-gray-400">{{ __('Closed') }}</span>
                                @endif
                            </td>
                        </tr>
                    @empty
                        <tr>
                            <td colspan="9" class="py-6 text-center text-sm text-gray-500 dark:text-gray-400">{{ __('No investments found.') }}</td>
                        </tr>
                    @endforelse
                </tbody>
            </table>
        </div>

        <div class="mt-4">{{ $this->investments->links() }}</div>
    </x-admin-panel>
</div>
