<?php

declare(strict_types=1);

namespace App\Filament\Concerns;

use App\Models\ManagedEnvironment;
use Filament\Facades\Filament;
use Illuminate\Database\Eloquent\Model;

trait UsesAdminEnvironmentFilterQueryParameter
{
    /**
     * @param  array<string, mixed>  $parameters
     */
    public static function getUrl(array $parameters = [], bool $isAbsolute = true, ?string $panel = null, ?Model $tenant = null): string
    {
        $panelId = $panel ?? Filament::getCurrentOrDefaultPanel()?->getId() ?? 'admin';

        if ($panelId !== 'admin') {
            return parent::getUrl($parameters, $isAbsolute, $panelId, $tenant);
        }

        $environment = $tenant instanceof ManagedEnvironment ? $tenant : null;
        $parameterTenant = $parameters['tenant'] ?? null;

        if (! $environment instanceof ManagedEnvironment && $parameterTenant instanceof ManagedEnvironment) {
            $environment = $parameterTenant;
        }

        unset($parameters['tenant']);

        $url = parent::getUrl($parameters, $isAbsolute, $panelId, null);

        return $environment instanceof ManagedEnvironment
            ? static::withEnvironmentId($url, $environment)
            : $url;
    }

    private static function withEnvironmentId(string $url, ManagedEnvironment $environment): string
    {
        $parts = parse_url($url);

        if (! is_array($parts)) {
            return $url;
        }

        $query = [];
        parse_str((string) ($parts['query'] ?? ''), $query);
        $query['environment_id'] = (int) $environment->getKey();
        unset($query['tenant'], $query['tenant_id'], $query['managed_environment_id'], $query['tenant_scope'], $query['environment']);

        $parts['query'] = http_build_query($query, '', '&', PHP_QUERY_RFC3986);

        $rebuilt = '';

        if (isset($parts['scheme'])) {
            $rebuilt .= $parts['scheme'].'://';
        }

        if (isset($parts['host'])) {
            $rebuilt .= $parts['host'];
        }

        if (isset($parts['port'])) {
            $rebuilt .= ':'.$parts['port'];
        }

        $rebuilt .= $parts['path'] ?? '';

        if (($parts['query'] ?? '') !== '') {
            $rebuilt .= '?'.$parts['query'];
        }

        if (isset($parts['fragment'])) {
            $rebuilt .= '#'.$parts['fragment'];
        }

        return $rebuilt;
    }
}
