<?php
declare(strict_types=1);

namespace App\Modules\Settings;

use App\Core\Http\Request;
use App\Core\Http\Response;
use App\Core\I18n\Translator;
use App\Core\Security\Csrf;
use App\Core\Support\Flash;
use App\Core\View\Template;
use App\Modules\Auth\AuthService;
use App\Modules\Cron\CronRepository;
use DateInterval;
use DateTimeImmutable;
use App\Core\Constants\IntegrationSources;
use App\Core\Constants\RedirectPaths;
use App\Core\Exceptions\IntegrationConfigException;
use App\Core\Http\RedirectPathResolver;
use Throwable;

final class AllegroIntegrationController
{
    private const OAUTH_STATE_SESSION_KEY = 'allegro_oauth_state';
    private const ORDERS_IMPORT_JOB_TYPE = 'allegro_orders_import';
    private const STATUS_SYNC_JOB_TYPE = 'allegro_status_sync';
    private const ORDERS_IMPORT_DEFAULT_INTERVAL_SECONDS = 300;
    private const ORDERS_IMPORT_DEFAULT_PRIORITY = 20;
    private const ORDERS_IMPORT_DEFAULT_MAX_ATTEMPTS = 3;
    private const STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO = 'allegro_to_orderpro';
    private const STATUS_SYNC_DIRECTION_ORDERPRO_TO_ALLEGRO = 'orderpro_to_allegro';
    private const STATUS_SYNC_DEFAULT_INTERVAL_MINUTES = 15;
    private const ORDERS_IMPORT_DEFAULT_PAYLOAD = [
        'max_pages' => 5,
        'page_limit' => 50,
        'max_orders' => 200,
    ];
    private const OAUTH_SCOPES = [
        AllegroOAuthClient::ORDERS_READ_SCOPE,
        AllegroOAuthClient::ORDERS_WRITE_SCOPE,
        AllegroOAuthClient::SALE_OFFERS_READ_SCOPE,
        AllegroOAuthClient::SHIPMENTS_READ_SCOPE,
        AllegroOAuthClient::SHIPMENTS_WRITE_SCOPE,
    ];

    public function __construct(
        private readonly Template $template,
        private readonly Translator $translator,
        private readonly AuthService $auth,
        private readonly AllegroIntegrationRepository $repository,
        private readonly AllegroStatusMappingRepository $statusMappings,
        private readonly OrderStatusRepository $orderStatuses,
        private readonly CronRepository $cronRepository,
        private readonly AllegroOAuthClient $oauthClient,
        private readonly AllegroOrderImportService $orderImportService,
        private readonly AllegroStatusDiscoveryService $statusDiscoveryService,
        private readonly string $appUrl,
        private readonly AllegroDeliveryMappingController $deliveryController
    ) {
    }

    public function index(Request $request): Response
    {
        $envParam = trim((string) $request->input('env', ''));
        $activeEnv = in_array($envParam, ['sandbox', 'production'], true)
            ? $envParam
            : $this->repository->getActiveEnvironment();
        $settings = $this->repository->getSettings($activeEnv);

        $tab = trim((string) $request->input('tab', 'integration'));
        if (!in_array($tab, ['integration', 'statuses', 'settings', 'delivery'], true)) {
            $tab = 'integration';
        }
        $defaultRedirectUri = $this->defaultRedirectUri();

        if (trim((string) ($settings['redirect_uri'] ?? '')) === '') {
            $settings['redirect_uri'] = $defaultRedirectUri;
        }
        $this->ensureDefaultSchedulesExist();
        $importIntervalSeconds = $this->currentImportIntervalSeconds();
        $statusSyncDirection = $this->currentStatusSyncDirection();
        $statusSyncIntervalMinutes = $this->currentStatusSyncIntervalMinutes();
        $deliveryServicesData = $tab === 'delivery' ? $this->deliveryController->loadDeliveryServices($settings) : [[], [], ''];
        $deliveryMappings = $this->deliveryController->getDeliveryMappingsRepository();

        $html = $this->template->render('settings/allegro', [
            'title' => $this->translator->get('settings.allegro.title'),
            'activeMenu' => 'settings',
            'activeSettings' => 'allegro',
            'user' => $this->auth->user(),
            'csrfToken' => Csrf::token(),
            'settings' => $settings,
            'activeTab' => $tab,
            'importIntervalSeconds' => $importIntervalSeconds,
            'statusSyncDirection' => $statusSyncDirection,
            'statusSyncIntervalMinutes' => $statusSyncIntervalMinutes,
            'statusMappings' => $this->statusMappings->listMappings(),
            'orderproStatuses' => $this->orderStatuses->listStatuses(),
            'defaultRedirectUri' => $defaultRedirectUri,
            'errorMessage' => (string) Flash::get('settings_error', ''),
            'successMessage' => (string) Flash::get('settings_success', ''),
            'warningMessage' => (string) Flash::get('settings_warning', ''),
            'deliveryMappings' => $deliveryMappings !== null ? $deliveryMappings->listMappings(IntegrationSources::ALLEGRO, 0) : [],
            'orderDeliveryMethods' => $deliveryMappings !== null ? $deliveryMappings->getDistinctOrderDeliveryMethods(IntegrationSources::ALLEGRO, 0) : [],
            'allegroDeliveryServices' => $deliveryServicesData[0],
            'apaczkaDeliveryServices' => $deliveryServicesData[1],
            'allegroDeliveryServicesError' => $deliveryServicesData[2],
            'inpostDeliveryServices' => array_values(array_filter(
                $deliveryServicesData[0],
                static fn(array $svc) => stripos((string) ($svc['carrierId'] ?? ''), 'inpost') !== false
            )),
        ], 'layouts/app');

        return Response::html($html);
    }

    public function save(Request $request): Response
    {
        $redirectTo = RedirectPathResolver::resolve((string) $request->input('return_to', RedirectPaths::ALLEGRO_INTEGRATION), ['/settings/integrations'], RedirectPaths::ALLEGRO_INTEGRATION);
        if (!Csrf::validate((string) $request->input('_token', ''))) {
            Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired'));
            return Response::redirect($redirectTo);
        }

        $environment = trim((string) $request->input('environment', 'sandbox'));
        $clientId = trim((string) $request->input('client_id', ''));
        $redirectUriInput = trim((string) $request->input('redirect_uri', ''));
        $redirectUri = $redirectUriInput !== '' ? $redirectUriInput : $this->defaultRedirectUri();
        $ordersFetchStartDate = trim((string) $request->input('orders_fetch_start_date', ''));

        $validationError = $this->validateSaveInput($environment, $clientId, $redirectUri, $ordersFetchStartDate);
        if ($validationError !== null) {
            Flash::set('settings_error', $validationError);
            return Response::redirect($redirectTo);
        }

        try {
            $this->repository->saveSettings([
                'environment' => $environment,
                'client_id' => $clientId,
                'client_secret' => trim((string) $request->input('client_secret', '')),
                'redirect_uri' => $redirectUri,
                'orders_fetch_enabled' => (string) $request->input('orders_fetch_enabled', '0') === '1',
                'orders_fetch_start_date' => $ordersFetchStartDate,
            ]);
            $this->ensureDefaultSchedulesExist();
            Flash::set('settings_success', $this->translator->get('settings.allegro.flash.saved'));
        } catch (Throwable $exception) {
            Flash::set(
                'settings_error',
                $this->translator->get('settings.allegro.flash.save_failed') . ' ' . $exception->getMessage()
            );
        }

        return Response::redirect($redirectTo);
    }

    public function saveImportSettings(Request $request): Response
    {
        $csrfError = $this->validateCsrf((string) $request->input('_token', ''));
        if ($csrfError !== null) {
            return $csrfError;
        }

        $intervalMinutesRaw = (int) $request->input('orders_import_interval_minutes', 5);
        $intervalMinutes = max(1, min(1440, $intervalMinutesRaw));

        $statusSyncDirection = trim((string) $request->input(
            'status_sync_direction',
            self::STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO
        ));

        $statusSyncIntervalRaw = (int) $request->input(
            'status_sync_interval_minutes',
            self::STATUS_SYNC_DEFAULT_INTERVAL_MINUTES
        );
        $statusSyncInterval = max(1, min(1440, $statusSyncIntervalRaw));

        $validationError = $this->validateImportSettingsInput(
            $intervalMinutesRaw,
            $intervalMinutes,
            $statusSyncDirection,
            $statusSyncIntervalRaw,
            $statusSyncInterval
        );
        if ($validationError !== null) {
            Flash::set('settings_error', $validationError);
            return Response::redirect(RedirectPaths::ALLEGRO_SETTINGS_TAB);
        }

        $existing = $this->findImportSchedule();
        $priority = (int) ($existing['priority'] ?? self::ORDERS_IMPORT_DEFAULT_PRIORITY);
        $maxAttempts = (int) ($existing['max_attempts'] ?? self::ORDERS_IMPORT_DEFAULT_MAX_ATTEMPTS);
        $payload = is_array($existing['payload'] ?? null)
            ? (array) $existing['payload']
            : self::ORDERS_IMPORT_DEFAULT_PAYLOAD;
        $enabled = array_key_exists('enabled', $existing)
            ? (bool) $existing['enabled']
            : true;
        $statusSchedule = $this->findStatusSyncSchedule();
        $statusPriority = (int) ($statusSchedule['priority'] ?? self::ORDERS_IMPORT_DEFAULT_PRIORITY);
        $statusMaxAttempts = (int) ($statusSchedule['max_attempts'] ?? self::ORDERS_IMPORT_DEFAULT_MAX_ATTEMPTS);
        $statusEnabled = array_key_exists('enabled', $statusSchedule)
            ? (bool) $statusSchedule['enabled']
            : true;

        try {
            $this->cronRepository->upsertSchedule(
                self::ORDERS_IMPORT_JOB_TYPE,
                $intervalMinutes * 60,
                $priority,
                $maxAttempts,
                $payload,
                $enabled
            );
            $this->cronRepository->upsertSchedule(
                self::STATUS_SYNC_JOB_TYPE,
                $statusSyncInterval * 60,
                $statusPriority,
                $statusMaxAttempts,
                null,
                $statusEnabled
            );
            $this->cronRepository->upsertSetting('allegro_status_sync_direction', $statusSyncDirection);
            $this->cronRepository->upsertSetting('allegro_status_sync_interval_minutes', (string) $statusSyncInterval);
            Flash::set('settings_success', $this->translator->get('settings.allegro.flash.import_settings_saved'));
        } catch (Throwable $exception) {
            Flash::set(
                'settings_error',
                $this->translator->get('settings.allegro.flash.import_settings_save_failed') . ' ' . $exception->getMessage()
            );
        }

        return Response::redirect(RedirectPaths::ALLEGRO_SETTINGS_TAB);
    }

    public function startOAuth(Request $request): Response
    {
        $csrfError = $this->validateCsrf((string) $request->input('_token', ''));
        if ($csrfError !== null) {
            return $csrfError;
        }

        try {
            $credentials = $this->requireOAuthCredentials();
            $state = bin2hex(random_bytes(24));
            $_SESSION[self::OAUTH_STATE_SESSION_KEY] = $state;

            $url = $this->oauthClient->buildAuthorizeUrl(
                (string) $credentials['environment'],
                (string) $credentials['client_id'],
                (string) $credentials['redirect_uri'],
                $state,
                self::OAUTH_SCOPES
            );

            return Response::redirect($url);
        } catch (Throwable $exception) {
            Flash::set('settings_error', $exception->getMessage());
            return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
        }
    }

    public function oauthCallback(Request $request): Response
    {
        $error = trim((string) $request->input('error', ''));
        if ($error !== '') {
            $description = trim((string) $request->input('error_description', ''));
            $message = $this->translator->get('settings.allegro.flash.oauth_failed');
            if ($description !== '') {
                $message .= ' ' . $description;
            }
            Flash::set('settings_error', $message);
            return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
        }

        $state = trim((string) $request->input('state', ''));
        $expectedState = trim((string) ($_SESSION[self::OAUTH_STATE_SESSION_KEY] ?? ''));
        unset($_SESSION[self::OAUTH_STATE_SESSION_KEY]);
        $authorizationCode = trim((string) $request->input('code', ''));

        $validationError = $this->validateOAuthCallbackParams($state, $expectedState, $authorizationCode);
        if ($validationError !== null) {
            Flash::set('settings_error', $validationError);
            return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
        }

        try {
            $credentials = $this->requireOAuthCredentials();
            $token = $this->oauthClient->exchangeAuthorizationCode(
                (string) $credentials['environment'],
                (string) $credentials['client_id'],
                (string) $credentials['client_secret'],
                (string) $credentials['redirect_uri'],
                $authorizationCode
            );

            $expiresAt = null;
            if ((int) ($token['expires_in'] ?? 0) > 0) {
                $expiresAt = (new DateTimeImmutable('now'))
                    ->add(new DateInterval('PT' . (int) $token['expires_in'] . 'S'))
                    ->format('Y-m-d H:i:s');
            }

            $this->repository->saveTokens(
                (string) ($token['access_token'] ?? ''),
                (string) ($token['refresh_token'] ?? ''),
                (string) ($token['token_type'] ?? ''),
                (string) ($token['scope'] ?? ''),
                $expiresAt
            );

            Flash::set('settings_success', $this->translator->get('settings.allegro.flash.oauth_connected'));
        } catch (Throwable $exception) {
            Flash::set('settings_error', $this->translator->get('settings.allegro.flash.oauth_failed') . ' ' . $exception->getMessage());
        }

        return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
    }

    public function importSingleOrder(Request $request): Response
    {
        $csrfError = $this->validateCsrf((string) $request->input('_token', ''));
        if ($csrfError !== null) {
            return $csrfError;
        }

        $checkoutFormId = trim((string) $request->input('checkout_form_id', ''));
        if ($checkoutFormId === '') {
            Flash::set('settings_error', $this->translator->get('settings.allegro.flash.checkout_form_id_required'));
            return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
        }

        try {
            $result = $this->orderImportService->importSingleOrder($checkoutFormId);
            $imageDiagnostics = is_array($result['image_diagnostics'] ?? null) ? $result['image_diagnostics'] : [];
            Flash::set(
                'settings_success',
                $this->translator->get('settings.allegro.flash.import_single_ok', [
                    'source_order_id' => (string) ($result['source_order_id'] ?? $checkoutFormId),
                    'local_id' => (string) ((int) ($result['order_id'] ?? 0)),
                    'action' => !empty($result['created'])
                        ? $this->translator->get('settings.allegro.import_action.created')
                        : $this->translator->get('settings.allegro.import_action.updated'),
                ]) . ' '
                . $this->translator->get('settings.allegro.flash.import_single_media_summary', [
                    'with_image' => (string) ((int) ($imageDiagnostics['with_image'] ?? 0)),
                    'total_items' => (string) ((int) ($imageDiagnostics['total_items'] ?? 0)),
                    'without_image' => (string) ((int) ($imageDiagnostics['without_image'] ?? 0)),
                ])
            );

            $warningDetails = $this->buildImportImageWarningMessage($imageDiagnostics);
            if ($warningDetails !== '') {
                Flash::set('settings_warning', $warningDetails);
            }
        } catch (Throwable $exception) {
            Flash::set(
                'settings_error',
                $this->translator->get('settings.allegro.flash.import_single_failed') . ' ' . $exception->getMessage()
            );
        }

        return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
    }

    private function defaultRedirectUri(): string
    {
        $base = trim($this->appUrl);
        if ($base === '') {
            $base = 'http://localhost:8000';
        }

        return rtrim($base, '/') . RedirectPaths::ALLEGRO_OAUTH_CALLBACK_PATH;
    }

    private function validateCsrf(string $token): ?Response
    {
        if (Csrf::validate($token)) {
            return null;
        }

        Flash::set('settings_error', $this->translator->get('auth.errors.csrf_expired'));
        return Response::redirect(RedirectPaths::ALLEGRO_INTEGRATION);
    }

    /**
     * @return array<string, string>
     */
    private function requireOAuthCredentials(): array
    {
        $credentials = $this->repository->getOAuthCredentials();
        if ($credentials === null) {
            throw new IntegrationConfigException($this->translator->get('settings.allegro.flash.credentials_missing'));
        }

        return $credentials;
    }

    private function isValidHttpUrl(string $url): bool
    {
        $trimmed = trim($url);
        if ($trimmed === '') {
            return false;
        }

        if (filter_var($trimmed, FILTER_VALIDATE_URL) === false) {
            return false;
        }

        $scheme = strtolower((string) parse_url($trimmed, PHP_URL_SCHEME));
        return $scheme === 'http' || $scheme === 'https';
    }

    private function isValidDate(string $value): bool
    {
        if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $value) !== 1) {
            return false;
        }

        $date = DateTimeImmutable::createFromFormat('Y-m-d', $value);
        return $date instanceof DateTimeImmutable && $date->format('Y-m-d') === $value;
    }

    /**
     * @param array<string, mixed> $imageDiagnostics
     */
    private function buildImportImageWarningMessage(array $imageDiagnostics): string
    {
        $withoutImage = (int) ($imageDiagnostics['without_image'] ?? 0);
        if ($withoutImage <= 0) {
            return '';
        }

        $reasonCountsRaw = $imageDiagnostics['reason_counts'] ?? [];
        if (!is_array($reasonCountsRaw) || $reasonCountsRaw === []) {
            return $this->translator->get('settings.allegro.flash.import_single_media_warning_generic', [
                'without_image' => (string) $withoutImage,
            ]);
        }

        $parts = [];
        foreach ($reasonCountsRaw as $reason => $countRaw) {
            $count = (int) $countRaw;
            if ($count <= 0) {
                continue;
            }
            $parts[] = $this->reasonLabel((string) $reason) . ': ' . $count;
        }

        if ($parts === []) {
            return $this->translator->get('settings.allegro.flash.import_single_media_warning_generic', [
                'without_image' => (string) $withoutImage,
            ]);
        }

        return $this->translator->get('settings.allegro.flash.import_single_media_warning', [
            'without_image' => (string) $withoutImage,
            'reasons' => implode(', ', $parts),
        ]);
    }

    private function reasonLabel(string $reasonCode): string
    {
        return match ($reasonCode) {
            'missing_offer_id' => 'brak ID oferty',
            'missing_in_checkout_form' => 'brak obrazka w checkout form',
            'missing_in_offer_api' => 'brak obrazka w API oferty',
            'offer_api_access_denied_403' => 'brak uprawnien API ofert (403)',
            'offer_api_unauthorized_401' => 'token nieautoryzowany dla API ofert (401)',
            'offer_api_not_found_404' => 'oferta nie znaleziona (404)',
            'offer_api_request_failed' => 'blad zapytania do API oferty',
            default => str_starts_with($reasonCode, 'offer_api_http_')
                ? 'blad API oferty (' . str_replace('offer_api_http_', '', $reasonCode) . ')'
                : $reasonCode,
        };
    }

    private function currentImportIntervalSeconds(): int
    {
        $schedule = $this->findImportSchedule();
        $value = (int) ($schedule['interval_seconds'] ?? self::ORDERS_IMPORT_DEFAULT_INTERVAL_SECONDS);
        return max(60, min(86400, $value));
    }

    /**
     * @return array<string, mixed>
     */
    private function findImportSchedule(): array
    {
        try {
            $schedules = $this->cronRepository->listSchedules();
        } catch (Throwable) {
            return [];
        }

        foreach ($schedules as $schedule) {
            if (!is_array($schedule)) {
                continue;
            }
            if ((string) ($schedule['job_type'] ?? '') !== self::ORDERS_IMPORT_JOB_TYPE) {
                continue;
            }
            return $schedule;
        }

        return [];
    }

    /**
     * @return array<string, mixed>
     */
    private function findStatusSyncSchedule(): array
    {
        try {
            $schedules = $this->cronRepository->listSchedules();
        } catch (Throwable) {
            return [];
        }

        foreach ($schedules as $schedule) {
            if (!is_array($schedule)) {
                continue;
            }
            if ((string) ($schedule['job_type'] ?? '') !== self::STATUS_SYNC_JOB_TYPE) {
                continue;
            }
            return $schedule;
        }

        return [];
    }

    private function currentStatusSyncDirection(): string
    {
        $value = trim($this->cronRepository->getStringSetting(
            'allegro_status_sync_direction',
            self::STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO
        ));

        if (!in_array($value, $this->allowedStatusSyncDirections(), true)) {
            return self::STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO;
        }

        return $value;
    }

    private function currentStatusSyncIntervalMinutes(): int
    {
        return $this->cronRepository->getIntSetting(
            'allegro_status_sync_interval_minutes',
            self::STATUS_SYNC_DEFAULT_INTERVAL_MINUTES,
            1,
            1440
        );
    }

    /**
     * @return array<int, string>
     */
    private function allowedStatusSyncDirections(): array
    {
        return [
            self::STATUS_SYNC_DIRECTION_ALLEGRO_TO_ORDERPRO,
            self::STATUS_SYNC_DIRECTION_ORDERPRO_TO_ALLEGRO,
        ];
    }

    private function validateSaveInput(
        string $environment,
        string $clientId,
        string $redirectUri,
        string $ordersFetchStartDate
    ): ?string {
        if (!in_array($environment, ['sandbox', 'production'], true)) {
            return $this->translator->get('settings.allegro.validation.environment_invalid');
        }
        if ($clientId !== '' && mb_strlen($clientId) > 128) {
            return $this->translator->get('settings.allegro.validation.client_id_too_long');
        }
        if (!$this->isValidHttpUrl($redirectUri)) {
            return $this->translator->get('settings.allegro.validation.redirect_uri_invalid');
        }
        if ($ordersFetchStartDate !== '' && !$this->isValidDate($ordersFetchStartDate)) {
            return $this->translator->get('settings.allegro.validation.orders_fetch_start_date_invalid');
        }
        return null;
    }

    private function validateImportSettingsInput(
        int $intervalMinutesRaw,
        int $intervalMinutes,
        string $statusSyncDirection,
        int $statusSyncIntervalRaw,
        int $statusSyncInterval
    ): ?string {
        if ($intervalMinutesRaw !== $intervalMinutes) {
            return $this->translator->get('settings.allegro.validation.orders_import_interval_invalid');
        }
        if (!in_array($statusSyncDirection, $this->allowedStatusSyncDirections(), true)) {
            return $this->translator->get('settings.allegro.validation.status_sync_direction_invalid');
        }
        if ($statusSyncIntervalRaw !== $statusSyncInterval) {
            return $this->translator->get('settings.allegro.validation.status_sync_interval_invalid');
        }
        return null;
    }

    private function validateOAuthCallbackParams(
        string $state,
        string $expectedState,
        string $authorizationCode
    ): ?string {
        if ($state === '' || $expectedState === '' || !hash_equals($expectedState, $state)) {
            return $this->translator->get('settings.allegro.flash.oauth_state_invalid');
        }
        if ($authorizationCode === '') {
            return $this->translator->get('settings.allegro.flash.oauth_code_missing');
        }
        return null;
    }

    private function ensureDefaultSchedulesExist(): void
    {
        try {
            if ($this->findImportSchedule() === []) {
                $this->cronRepository->upsertSchedule(
                    self::ORDERS_IMPORT_JOB_TYPE,
                    self::ORDERS_IMPORT_DEFAULT_INTERVAL_SECONDS,
                    self::ORDERS_IMPORT_DEFAULT_PRIORITY,
                    self::ORDERS_IMPORT_DEFAULT_MAX_ATTEMPTS,
                    self::ORDERS_IMPORT_DEFAULT_PAYLOAD,
                    true
                );
            }
            if ($this->findStatusSyncSchedule() === []) {
                $this->cronRepository->upsertSchedule(
                    self::STATUS_SYNC_JOB_TYPE,
                    self::STATUS_SYNC_DEFAULT_INTERVAL_MINUTES * 60,
                    self::ORDERS_IMPORT_DEFAULT_PRIORITY,
                    self::ORDERS_IMPORT_DEFAULT_MAX_ATTEMPTS,
                    null,
                    true
                );
            }
        } catch (Throwable) {
            // non-critical: schedules will be created when user explicitly saves import settings
        }
    }
}
