import type { FC } from 'react';
import React, { useState, useMemo } from 'react';
import { FieldValidator } from '@theorchard/field-validator';
import { AppConfigContext } from './appConfigContext';
import type { SuiteAppConfig } from './types';
import type { Dict } from '@theorchard/field-validator';

const validateFeatureFlags = (featureFlags?: Dict) => {
    if (!featureFlags) return undefined;

    return Object.entries(featureFlags).reduce(
        (flags, [key, value]) => ({
            ...flags,
            [key]: value === 'enabled' || value === true,
        }),
        {}
    );
};

export const validateAppConfig = (validator: FieldValidator): SuiteAppConfig => ({
    ...validator.subject,
    appName: validator.str('appName'),
    appUpdated: validator.optStr('appUpdated'),
    appTitle: validator.optStr('appTitle'),
    appVersion: validator.optStr('appVersion') || '1.0.0',
    auth0Audience: validator.str('auth0Audience'),
    auth0ClientId: validator.str('auth0ClientId'),
    auth0Domain: validator.str('auth0Domain'),
    auth0OrgId: validator.optStr('auth0OrgId'),
    auth0RedirectUri: validator.optStr('auth0RedirectUri'),
    auth0StoreTokenInClient: validator.optBool('auth0StoreTokenInClient'),
    authTokenInvalidationUrl: validator.optStr('authTokenInvalidationUrl'),
    brand: validator.str('brand'),
    cdnUrl: validator.str('cdnUrl'),
    datadogApplicationId: validator.optStr('datadogApplicationId'),
    datadogClientToken: validator.optStr('datadogClientToken'),
    datadogSessionReplayRecording: validator.optBool('datadogSessionReplayRecording'),
    defaultProfileType: validator.optStr('defaultProfileType'),
    secondaryProfileTypes: validator.arrayStr('secondaryProfileTypes', []),
    deployTimestamp: validator.optStr('deployTimestamp'),
    environment: validator.str('environment'),
    featureFlagFilter: validator.optStr('featureFlagFilter'),
    gitCommit: validator.optStr('gitCommit'),
    graphqlUrl: validator.str('graphqlUrl'),
    locale: validator.optStr('locale'),
    segmentWriteKey: validator.optStr('segmentWriteKey'),
    sentryDsn: validator.optStr('sentryDsn'),
    userFeatureFlags: validateFeatureFlags(validator.optObj('userFeatureFlags')),
});

export interface AppConfigProviderProps {
    children?: React.ReactNode;
    config: SuiteAppConfig;
    validate?: <T extends SuiteAppConfig>(
        baseConfig: SuiteAppConfig,
        validator: FieldValidator
    ) => T;
}

export const AppConfigProvider: FC<AppConfigProviderProps> = ({ children, config, validate }) => {
    const [appConfig, setConfig] = useState<SuiteAppConfig>(config);

    const validatedConfig = useMemo(() => {
        const validator = new FieldValidator(appConfig);
        const validated = validateAppConfig(validator);

        if (validate) return validate(validated, validator);
        return validated;
    }, [appConfig, validate]);

    return (
        <AppConfigContext.Provider value={{ config: validatedConfig, setConfig }}>
            {validatedConfig && children}
        </AppConfigContext.Provider>
    );
};
