<?php

use App\Models\Security;
use App\Models\SecurityOrder;
use App\Models\WalletTransaction;
use App\Services\DefaultCurrencyService;
use App\Services\Trading\TradingSettingsService;
use App\Models\Wallet;
use Illuminate\Database\Eloquent\Collection;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Layout;
use Livewire\Component;

return new #[Layout('layouts.trading')] class extends Component {
    public bool $showBalance = true;

    public function toggleBalanceVisibility(): void
    {
        $this->showBalance = !$this->showBalance;
    }

    #[Computed]
    public function wallet(): Wallet
    {
        return Wallet::query()->firstOrCreate(['user_id' => auth()->id()], ['currency_code' => app(DefaultCurrencyService::class)->code()]);
    }

    #[Computed]
    public function securities(): array
    {
        return Security::query()->where('is_active', true)->with('latestLog')->orderBy('trading_name')->get()->map(fn(Security $security): array => $this->mapSecurityForDisplay($security))->values()->all();
    }

    #[Computed]
    public function holdings(): array
    {
        return auth()
            ->user()
            ->portfolioHoldings()
            ->with('security')
            ->get()
            ->map(function ($holding): array {
                $latestPrice = (float) $holding->security->latestPrice();
                $currentValue = (float) $holding->quantity * $latestPrice;
                $gainLossPercent = (float) $holding->average_buy_price > 0 ? (($latestPrice - (float) $holding->average_buy_price) / (float) $holding->average_buy_price) * 100 : 0;

                return [
                    'symbol' => $holding->security->trading_name,
                    'name' => $holding->security->name,
                    'current_value' => $currentValue,
                    'gain_loss_percent' => $gainLossPercent,
                ];
            })
            ->all();
    }

    #[Computed]
    public function portfolio(): array
    {
        $inTrade = collect($this->holdings)->sum('current_value');
        $wallet = $this->wallet;
        $invested = auth()->user()->portfolioHoldings()->sum('total_invested');
        $gainLoss = $invested > 0 ? (($inTrade - (float) $invested) / (float) $invested) * 100 : 0;

        return [
            'balance' => (float) $wallet->balance,
            'inTrade' => (float) $inTrade,
            'gainLoss' => (float) $gainLoss,
            'currency' => app(DefaultCurrencyService::class)->code(),
        ];
    }

    #[Computed]
    public function watchlist(): array
    {
        return auth()
            ->user()
            ->watchlistItems()
            ->with('security')
            ->latest()
            ->limit(5)
            ->get()
            ->map(
                fn($item): array => [
                    'id' => $item->security->id,
                    'symbol' => $item->security->trading_name,
                    'name' => $item->security->name,
                    'price' => (float) $item->security->latestPrice(),
                    'change' => $item->security->latestChangePercent(),
                ],
            )
            ->all();
    }

    #[Computed]
    public function newestSecurity(): ?array
    {
        $security = Security::query()->latest()->first();

        if (!$security) {
            return null;
        }

        return [
            'name' => $security->name,
            'symbol' => $security->trading_name,
        ];
    }

    /** Pending orders (trades) + pending wallet transactions (deposits/withdrawals). */
    #[Computed]
    public function pendingTransactionsCount(): int
    {
        $orders = SecurityOrder::query()
            ->where('user_id', auth()->id())
            ->where('status', 'pending')
            ->count();

        $walletRequests = WalletTransaction::query()
            ->where('user_id', auth()->id())
            ->where('status', 'pending')
            ->count();

        return $orders + $walletRequests;
    }

    #[Computed]
    public function isMarketOpen(): bool
    {
        return app(TradingSettingsService::class)->isMarketOpen();
    }

    /** Default currency from ATU Currency (used for display where wallet is not in scope, e.g. marquee). */
    #[Computed]
    public function defaultCurrencyCode(): string
    {
        return app(DefaultCurrencyService::class)->code();
    }

    #[Computed]
    public function recentTransactions(): Collection
    {
        return WalletTransaction::query()
            ->where('user_id', auth()->id())
            ->latest()
            ->limit(10)
            ->get();
    }

    #[Computed]
    public function annualNetRatePercent(): float
    {
        $rawValue = auth()->user()?->getMeta('annual_net_rate_percent', 0);

        if (!is_numeric($rawValue)) {
            return 0.0;
        }

        return max(0, (float) $rawValue);
    }

    private function mapSecurityForDisplay(Security $security): array
    {
        return [
            'id' => $security->id,
            'symbol' => strtoupper((string) $security->trading_name),
            'name' => (string) ($security->name ?: $security->trading_name),
            'price' => $security->latestPrice(),
            'change' => $security->latestChangePercent(),
            'logo' => $security->logo,
            'initials' => $this->buildInitials((string) $security->trading_name, (string) ($security->name ?: $security->trading_name)),
        ];
    }

    private function buildInitials(string $symbol, string $name): string
    {
        $lettersOnly = preg_replace('/[^A-Z]/', '', strtoupper($symbol)) ?? '';
        if ($lettersOnly !== '') {
            return substr($lettersOnly, 0, 2);
        }

        $nameParts = preg_split('/\s+/', trim($name)) ?: [];
        $initials = collect($nameParts)->filter()->take(2)->map(fn(string $part): string => strtoupper(substr($part, 0, 1)))->implode('');

        return $initials !== '' ? $initials : 'ST';
    }

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