<?php

namespace App\Support;

use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Facades\Route;

class UserProfileMenu
{
    /**
     * Standard signed-in profile links for Ladill product apps.
     * Not used by Ladill Mail (mail.ladill.com) — that app keeps a mailbox-specific menu.
     *
     * @return list<array<string, mixed>>
     */
    public static function items(?Authenticatable $user = null): array
    {
        $user ??= auth()->user();

        if (! $user) {
            return [];
        }

        $items = [];

        foreach ([
            ['label' => 'Home', 'path' => '', 'host' => 'home'],
            ['label' => 'Profile', 'path' => 'profile'],
            ['label' => 'Account Settings', 'path' => 'account-settings'],
            ['label' => 'Dashboard', 'path' => 'dashboard'],
            ['label' => 'Billing', 'path' => 'billing'],
        ] as $link) {
            $href = self::platformUrl($link['host'] ?? 'account', $link['path']);

            if (self::isCurrentMenuLink($link, $href)) {
                continue;
            }

            $items[] = [
                'type' => 'link',
                'label' => $link['label'],
                'href' => $href,
            ];
        }

        if (Route::has((string) config('billing.wallet_balance_route', 'wallet.balance'))) {
            $items[] = ['type' => 'wallet'];
        }

        if (self::userIsAdmin($user)) {
            $adminHref = self::platformUrl('account', 'admin');

            if (! self::isCurrentMenuLink(['path' => 'admin', 'host' => 'account'], $adminHref)) {
                $items[] = [
                    'type' => 'link',
                    'label' => 'Admin',
                    'href' => $adminHref,
                ];
            }
        }

        if (Route::has('logout')) {
            $items[] = [
                'type' => 'logout',
                'label' => 'Logout',
                'action' => route('logout'),
            ];
        }

        return $items;
    }

    private static function platformUrl(string $host, string $path = ''): string
    {
        if ($host === 'home') {
            if (function_exists('ladill_home_url')) {
                return ladill_home_url($path);
            }

            $domain = config('app.home_domain');
            if (! $domain) {
                $platform = (string) config('app.platform_domain', parse_url((string) config('app.url', ''), PHP_URL_HOST) ?: '');
                $domain = $platform !== '' ? 'home.'.$platform : (string) config('app.account_domain');
            }

            return self::absoluteUrl((string) $domain, $path);
        }

        if (function_exists('ladill_account_url')) {
            return ladill_account_url($path);
        }

        return self::absoluteUrl((string) config('app.account_domain'), $path);
    }

    /**
     * Hide a menu link when the signed-in user is already on that destination.
     *
     * @param  array{label?: string, path?: string, host?: string}  $link
     */
    private static function isCurrentMenuLink(array $link, string $href): bool
    {
        if (app()->runningInConsole() && ! app()->runningUnitTests()) {
            return false;
        }

        $request = request();
        if (! $request) {
            return false;
        }

        $linkHost = strtolower((string) parse_url($href, PHP_URL_HOST));
        $currentHost = strtolower($request->getHost());

        if ($linkHost === '' || $linkHost !== $currentHost) {
            return false;
        }

        $currentPath = trim($request->getPathInfo(), '/');
        $targetPath = trim((string) parse_url($href, PHP_URL_PATH), '/');

        if (($link['host'] ?? 'account') === 'home') {
            return $currentPath === '';
        }

        if (($link['path'] ?? '') === 'dashboard') {
            return in_array($currentPath, ['dashboard', 'account'], true)
                || ($targetPath !== '' && self::pathMatchesSection($currentPath, $targetPath));
        }

        return self::pathMatchesSection($currentPath, $targetPath);
    }

    private static function pathMatchesSection(string $currentPath, string $targetPath): bool
    {
        if ($targetPath === '') {
            return $currentPath === '';
        }

        return $currentPath === $targetPath
            || str_starts_with($currentPath, $targetPath.'/');
    }

    private static function absoluteUrl(string $domain, string $path = ''): string
    {
        $base = 'https://'.trim($domain, '/');

        if ($path === '') {
            return $base;
        }

        return $base.'/'.ltrim($path, '/');
    }

    private static function userIsAdmin(Authenticatable $user): bool
    {
        if (method_exists($user, 'isAdmin')) {
            return $user->isAdmin();
        }

        return (bool) ($user->is_admin ?? false);
    }
}
