<?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\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;

return 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,
            ));
        }
    }

    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();

        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'),
            ));
        }

        $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,
            ));
        }

        $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();
    }

    protected function view($data = [])
    {
        return app('view')->file('/home/ziidiaik/home.ziiditrader.com/storage/framework/views/livewire/views/b5516b50.blade.php', $data);
    }
}; 