<?php

namespace App\Livewire;

use App\Models\CollateralAsset;
use App\Models\EarnApplication;
use App\Services\CoinGeckoService;
use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use Livewire\WithFileUploads;

class EarnStakingCalculator extends Component
{
    use WithFileUploads;

    public ?int $assetId = null;
    public string $stakeAmountCoin = '100';
    public int $durationDays = 30;

    public ?float $estimatedReturnsUsd = null;

    public bool $modalOpen = false;
    public ?string $walletAddress = null;
    public ?string $walletProviderName = null;
    public ?string $network = null;

    public $paymentProof;

    public function mount(): void
    {
        $first = CollateralAsset::query()->where('is_active', true)->orderBy('symbol')->first();
        $this->assetId = $first?->id;

        $this->updateEstimates();
    }

    public function render()
    {
        $assets = CollateralAsset::query()
            ->where('is_active', true)
            ->orderBy('symbol')
            ->get(['id', 'symbol', 'name', 'staking_apr']);

        return view('livewire.earn-staking-calculator', [
            'assets' => $assets,
        ]);
    }

    public function updatedAssetId(): void
    {
        $this->updateEstimates();
    }

    public function updatedStakeAmountCoin(): void
    {
        $this->updateEstimates();
    }

    public function updatedDurationDays(): void
    {
        $this->updateEstimates();
    }

    private function updateEstimates(): void
    {
        if (! $this->assetId) {
            $this->estimatedReturnsUsd = null;
            return;
        }

        $asset = CollateralAsset::query()->find($this->assetId);
        if (! $asset || ! $asset->gecko_id) {
            $this->estimatedReturnsUsd = null;
            return;
        }

        $stakeAmountCoin = (float) $this->stakeAmountCoin;
        if ($stakeAmountCoin <= 0) {
            $this->estimatedReturnsUsd = 0.0;
            return;
        }

        $days = (int) $this->durationDays;
        if ($days < 7) {
            $days = 7;
        }

        $coinGeckoService = app(CoinGeckoService::class);
        $prices = $coinGeckoService->getUsdPrices([$asset->gecko_id]);
        $priceUsd = $prices[$asset->gecko_id]['usd'] ?? null;

        if (! $priceUsd) {
            $this->estimatedReturnsUsd = null;
            return;
        }

        $apr = (float) $asset->staking_apr; // fraction (0.12 = 12%)
        $years = $days / 365;

        $stakeUsd = $stakeAmountCoin * (float) $priceUsd;
        $returnsUsd = $stakeUsd * $apr * $years; // simple interest

        $this->estimatedReturnsUsd = $returnsUsd;
    }

    public function startStakingNow(): void
    {
        $asset = CollateralAsset::query()->findOrFail($this->assetId);

        $this->validate([
            'stakeAmountCoin' => ['required', 'numeric', 'min:0.00000001'],
            'durationDays' => ['required', 'integer', 'min:7', 'max:365'],
        ]);

        $this->updateEstimates();

        $this->walletAddress = $asset->earn_deposit_address;
        $this->walletProviderName = $asset->wallet_provider_name;
        $this->network = $asset->network;

        $this->modalOpen = true;
    }

    public function submitStaking(): void
    {
        if (! Auth::check()) {
            $this->addError('auth', 'Please sign in to start earning.');
            return;
        }

        $asset = CollateralAsset::query()->findOrFail($this->assetId);

        $this->validate([
            'paymentProof' => ['required', 'file', 'max:5120'],
        ]);

        $paymentPath = $this->paymentProof->store('uploads/payment-proofs', 'public');

        EarnApplication::create([
            'user_id' => Auth::id(),
            'collateral_asset_id' => $asset->id,
            'stake_amount_coin' => (float) $this->stakeAmountCoin,
            'duration_days' => (int) $this->durationDays,
            'apr_at_submission' => (float) $asset->staking_apr,
            'estimated_returns_usd' => $this->estimatedReturnsUsd,
            'status' => 'payment_proof_submitted',
            'payout_wallet_address' => $asset->earn_deposit_address,
            'wallet_provider_name' => $asset->wallet_provider_name,
            'network' => $asset->network,
            'payment_proof_path' => $paymentPath,
            'submitted_at' => now(),
            'payment_proof_submitted_at' => now(),
        ]);

        $this->paymentProof = null;
        $this->modalOpen = false;

        session()->flash('success', 'Staking application submitted. Admin will review your proof of payment.');
    }
}
