<?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Application>
 */
class ApplicationFactory extends Factory
{
    /**
     * Define the model's default state.
     *
     * @return array<string, mixed>
     */
    public function definition(): array
    {
        // Popular apps that likely have icons in selfh.st/icons
        $apps = [
            'Nextcloud',
            'Plex',
            'Jellyfin',
            'Home Assistant',
            'Grafana',
            'Portainer',
            'Sonarr',
            'Radarr',
            'Lidarr',
            'Bazarr',
            'Overseerr',
            'Tautulli',
            'Ombi',
            'Jackett',
            'qBittorrent',
            'Transmission',
            'SABnzbd',
            'NZBGet',
            'Synology',
            'FreeNAS',
            'UniFi',
            'pfSense',
            'OPNsense',
            'Pi-hole',
            'AdGuard',
            'Bitwarden',
            'Vaultwarden',
            'PhotoPrism',
            'Immich',
            'Paperless',
            'Bookstack',
            'TiddlyWiki',
            'Joplin',
            'Standard Notes',
            'Trilium',
            'Monica',
            'Firefly III',
            'Invoice Ninja',
            'Crater',
            'Akaunting',
            'Ghost',
            'WordPress',
            'Discourse',
            'Flarum',
            'NodeBB',
            'Rocket.Chat',
            'Mattermost',
            'Element',
            'Synapse',
            'Jitsi',
            'BigBlueButton',
            'Jami',
            'Mumble',
            'TeamSpeak',
            'Discord',
            'Gitea',
            'GitLab',
            'Forgejo',
            'Gogs',
            'Sourcehut',
            'Drone',
            'Jenkins',
            'Buildbot',
            'TeamCity',
            'Bamboo',
            'SonarQube',
            'Sentry',
            'Uptime Kuma',
            'Healthchecks',
            'Cachet',
            'Zabbix',
            'Nagios',
            'Icinga',
            'LibreNMS',
            'PRTG',
            'Proxmox',
            'ESXi',
            'XCP-ng',
            'Harvester',
            'Rancher'
        ];

        $appName = fake()->randomElement($apps);
        $kebabName = str($appName)->kebab()->toString();

        return [
            'name' => $appName,
            'client_id' => fake()->uuid(),
            'client_secret' => fake()->regexify('[A-Za-z0-9]{40}'),
            'redirect_uri' => fake()->url() . '/auth/callback',
            'icon' => "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/{$kebabName}.webp",
        ];
    }

    /**
     * Indicate that the application has no icon.
     */
    public function withoutIcon(): static
    {
        return $this->state(fn (array $attributes) => [
            'icon' => null,
        ]);
    }

    /**
     * Indicate that the application uses a custom icon URL.
     */
    public function withCustomIcon(string $iconUrl = null): static
    {
        return $this->state(fn (array $attributes) => [
            'icon' => $iconUrl ?? fake()->imageUrl(100, 100, 'apps', true),
        ]);
    }

    /**
     * Create an application with localhost redirect URI for testing.
     */
    public function localhost(int $port = 3000): static
    {
        return $this->state(fn (array $attributes) => [
            'redirect_uri' => "http://localhost:{$port}/auth/callback",
        ]);
    }

    /**
     * Create an application with HTTPS redirect URI.
     */
    public function secure(): static
    {
        return $this->state(fn (array $attributes) => [
            'redirect_uri' => 'https://' . fake()->domainName() . '/auth/callback',
        ]);
    }

    /**
     * Create a Grafana application for testing.
     */
    public function grafana(): static
    {
        return $this->state(fn (array $attributes) => [
            'name' => 'Grafana',
            'redirect_uri' => 'https://grafana.' . fake()->domainName() . '/login/generic_oauth',
            'icon' => 'https://cdn.jsdelivr.net/gh/selfhst/icons/webp/grafana.webp',
        ]);
    }

    /**
     * Create a Nextcloud application for testing.
     */
    public function nextcloud(): static
    {
        return $this->state(fn (array $attributes) => [
            'name' => 'Nextcloud',
            'redirect_uri' => 'https://cloud.' . fake()->domainName() . '/apps/user_oidc/code',
            'icon' => 'https://cdn.jsdelivr.net/gh/selfhst/icons/webp/nextcloud.webp',
        ]);
    }

    /**
     * Create a test application with predictable values.
     */
    public function testApp(): static
    {
        return $this->state(fn (array $attributes) => [
            'name' => 'Test Application',
            'client_id' => 'test-client-id',
            'client_secret' => 'test-client-secret',
            'redirect_uri' => 'http://localhost:3000/auth/callback',
            'icon' => null,
        ]);
    }
}
