<?php

declare(strict_types=1);

namespace Maestro\Core\Support;

use Illuminate\Support\Facades\Storage;
use Maestro\Core\Models\MaestroAppSetting;
use Maestro\Core\Services\MicrosoftAuthService;

final class MaestroAppSettingsPresenter
{
    /**
     * Logo URLs when using shipped defaults are omitted (null): the SPA uses bundled assets.
     * Non-null values are overrides stored on the public disk.
     *
     * @return array{
     *   theme: array<string, mixed>|null,
     *   logos: array<string, string|null>,
     *   publicPage: array{enabled: bool, mode: string, rootMode: string},
     *   login: array{
     *     providers: array{microsoft: bool, google: bool, apple: bool},
     *     providersStored: array{microsoft: bool|null, google: bool, apple: bool},
     *     microsoftConfigured: bool,
     *   },
     *   maestroCore: array{npm: string|null, composer: string|null}
     * }
     */
    public static function toArray(?MaestroAppSetting $row = null): array
    {
        $row ??= MaestroAppSetting::instance();

        return [
            'theme' => $row->theme,
            'logos' => [
                'sidebar' => self::storagePublicUrlOrNull($row->logo_sidebar_path),
                'header' => self::storagePublicUrlOrNull($row->logo_header_path),
                'compact' => self::storagePublicUrlOrNull($row->logo_compact_path),
                'favicon' => self::storagePublicUrlOrNull($row->favicon_path),
                'loginHero' => self::storagePublicUrlOrNull($row->login_hero_path),
            ],
            'offerDocumentBackgrounds' => self::offerDocumentBackgroundEntries($row),
            'publicPage' => self::publicPageSettings($row),
            'login' => self::loginSettings($row),
            'maestroCore' => MaestroCoreVersions::toArray(),
        ];
    }

    /**
     * @return array{enabled: bool, mode: string, rootMode: string}
     */
    private static function publicPageSettings(MaestroAppSetting $row): array
    {
        $settings = is_array($row->public_page) ? $row->public_page : [];

        $enabled = array_key_exists('enabled', $settings)
            ? filter_var($settings['enabled'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)
            : false;
        $mode = isset($settings['mode']) && is_string($settings['mode'])
            ? $settings['mode']
            : 'core_default';

        if (! in_array($mode, ['core_default', 'customer_override'], true)) {
            $mode = 'core_default';
        }

        $rootMode = isset($settings['root_mode']) && is_string($settings['root_mode'])
            ? $settings['root_mode']
            : 'login';
        if (! in_array($rootMode, ['dashboard', 'login', 'public'], true)) {
            $rootMode = 'login';
        }

        return [
            'enabled' => $enabled ?? false,
            'mode' => $mode,
            'rootMode' => $rootMode,
        ];
    }

    /**
     * @return array{
     *   providers: array{microsoft: bool, google: bool, apple: bool},
     *   providersStored: array{microsoft: bool|null, google: bool, apple: bool},
     *   microsoftConfigured: bool,
     * }
     */
    private static function loginSettings(MaestroAppSetting $row): array
    {
        $settings = is_array($row->login) ? $row->login : [];
        $providers = is_array($settings['providers'] ?? null) ? $settings['providers'] : [];

        $storedMicrosoft = array_key_exists('microsoft', $providers)
            ? self::nullableBoolean($providers['microsoft'])
            : null;
        $storedGoogle = array_key_exists('google', $providers)
            ? (self::nullableBoolean($providers['google']) ?? false)
            : false;
        $storedApple = array_key_exists('apple', $providers)
            ? (self::nullableBoolean($providers['apple']) ?? false)
            : false;

        $microsoftConfigured = MicrosoftAuthService::isConfigured();
        $effectiveMicrosoft = $microsoftConfigured && $storedMicrosoft !== false;

        return [
            'providers' => [
                'microsoft' => $effectiveMicrosoft,
                'google' => $storedGoogle === true,
                'apple' => $storedApple === true,
            ],
            'providersStored' => [
                'microsoft' => $storedMicrosoft,
                'google' => $storedGoogle === true,
                'apple' => $storedApple === true,
            ],
            'microsoftConfigured' => $microsoftConfigured,
        ];
    }

    private static function nullableBoolean(mixed $value): ?bool
    {
        if ($value === null) {
            return null;
        }

        $parsed = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);

        return $parsed ?? (bool) $value;
    }

    private static function storagePublicUrlOrNull(?string $storageRelativePath): ?string
    {
        if ($storageRelativePath === null || $storageRelativePath === '') {
            return null;
        }

        return Storage::disk('public')->url($storageRelativePath);
    }

    /**
     * @return list<array{path: string, url: string}>
     */
    private static function offerDocumentBackgroundEntries(MaestroAppSetting $row): array
    {
        $paths = $row->offer_document_background_paths ?? [];
        if (! is_array($paths)) {
            return [];
        }

        $out = [];
        foreach ($paths as $path) {
            if (! is_string($path) || $path === '') {
                continue;
            }
            $out[] = [
                'path' => $path,
                'url' => Storage::disk('public')->url($path),
            ];
        }

        return $out;
    }
}
