import type {RenderParams} from '@gravity-ui/app-layout';

import type {
    AppEnvironment,
    AppInstallation,
    DLGlobalData,
    DLUser,
    TenantSettings,
} from '../../../shared';
import {FALLBACK_LANGUAGES, Language, USER_SETTINGS_KEY} from '../../../shared';
import type {AppLayoutSettings, GetLayoutConfig} from '../../types/app-layout';
import {addTranslationsScript} from '../../utils/language';

import {getChartkitLayoutSettings, getPlatform} from './utils';

export const getOpensourceLayoutConfig: GetLayoutConfig = async (args) => {
    const {req, res, settingsId} = args;

    const config = req.ctx.config;
    const requestId = req.id || '';

    const getAppLayoutSettings = req.ctx.get('getAppLayoutSettings');

    const appLayoutSettings: AppLayoutSettings = getAppLayoutSettings(req, res, settingsId);

    const regionalEnvConfig = req.ctx.config.regionalEnvConfig;

    const allowLanguages = (regionalEnvConfig?.allowLanguages || FALLBACK_LANGUAGES) as Language[];

    const cookie = req.cookies[USER_SETTINGS_KEY];
    let lang = Language.En;
    let theme;
    try {
        const preparedCookie = JSON.parse(cookie);
        lang = preparedCookie.language;
        theme = preparedCookie.theme;
    } catch {
        console.warn('no userSettings in cookie');
    }

    const isAllowed = allowLanguages.includes(lang || '');
    if (!isAllowed) {
        lang = Language.En;
    }

    const isAuthEnabled = req.ctx.config.isAuthEnabled;

    // TODO: check and remove optional props;
    let user: DLUser = {lang} as DLUser;
    const userSettings = {};
    let iamUserId = '';
    const {scripts: chartkitScripts, inlineScripts: chartkitInlineScripts} =
        getChartkitLayoutSettings(config.chartkitSettings);

    if (isAuthEnabled) {
        const authUser = req.ctx.get('user');
        iamUserId = authUser?.userId as string;
        const profile = authUser?.profile;
        user = {
            ...user,
            uid: iamUserId,
            roles: authUser?.roles,
            ...profile,
        };
    }

    const tenantSettings: TenantSettings = {
        defaultColorPaletteId: res.locals.tenantDefaultColorPaletteId,
    };

    const DL: DLGlobalData = {
        user,
        userSettings,
        iamUserId,
        deviceType: getPlatform(req.headers['user-agent']),
        requestId,
        env: config.appEnv as AppEnvironment,
        installationType: config.appInstallation as AppInstallation,
        serviceName: config.serviceName,
        endpoints: config.endpoints.ui,
        features: config.features,
        meta: req.ctx.getMetadata(),
        chartkitSettings: config.chartkitSettings,
        defaultColorPaletteId: config.defaultColorPaletteId,
        allowLanguages,
        headersMap: req.ctx.config.headersMap,
        isAuthEnabled,
        ymapApiKey: config.chartkitSettings?.yandexMap?.token,
        connectorIcons: res.locals.connectorIcons,
        apiPrefix: config.apiPrefix,
        releaseVersion: config.releaseVersion,
        docsUrl: config.docsUrl,
        orderedAuthRoles: config.orderedAuthRoles,
        authSignupDisabled: req.ctx.config.authSignupDisabled,
        authCookieName: req.ctx.config.authCookieName,
        tenantSettings,
        ...appLayoutSettings.DL,
    };
    const renderConfig: RenderParams<{DL: DLGlobalData}> = {
        nonce: req.nonce,
        data: {DL},
        lang,
        icon: {
            type: 'image/ico',
            href: config.faviconUrl,
            sizes: '32x32',
        },
        inlineScripts: ['window.DL = window.__DATA__.DL', ...chartkitInlineScripts],
        scripts: [addTranslationsScript({allowLanguages, lang}), ...chartkitScripts],
        links: [],
        pluginsOptions: {
            layout: {name: appLayoutSettings.bundleName},
            ...(theme ? {uikit: {theme}} : {}),
        },
        ...appLayoutSettings.renderConfig,
    };

    return renderConfig;
};
