import * as React from 'react';
import { Spinner, Box, Text, Heading } from '@gluestack-ui/themed';
import { PermissionType, Visibility, IConfigurationsFlattenedKeys } from 'common';
import { IPreDefinedPermissions } from '@adminide-stack/core';
import { useSetting, usePermissionAutoFetch } from '@adminide-stack/platform-client';
import { get } from 'lodash-es';
import { URI } from '@vscode-alt/monaco-editor/esm/vs/base/common/uri';

export interface IWithConfigurationProps {
    children?: React.ReactElement;
    configKey: IConfigurationsFlattenedKeys;
    permissionKeys?: IPreDefinedPermissions[];
    permissionTypes?: PermissionType[];
    resourceName?: string;
    settingsUri?: URI;
}

export const WithConfiguration = (props: IWithConfigurationProps) => {
    const { configKey, children, permissionKeys, resourceName, permissionTypes } = props;

    const {
        data,
        loading: settingsLoading,
        updateConfiguration: _,
    } = useSetting({
        configKey,
        overrides: { resource: props.settingsUri },
    });
    // const { data: permissions, loading: permissionLoading } = usePermissionAutoFetch();
    const { permissions, loading: permissionLoading } = usePermissionAutoFetch();

    const isPrivate = React.useMemo(() => Visibility.Private === data, [data]);

    const hasPermission = React.useMemo(() => {
        if (isPrivate && permissions && Array.isArray(permissionKeys)) {
            return permissionKeys.some((key) => permissionTypes.includes(get(permissions?.resolveConfiguration, key)));
        }
        return false;
    }, [isPrivate, permissions]);

    const isLoading = React.useMemo(() => permissionLoading || settingsLoading, [permissionLoading, settingsLoading]);

    if (isLoading) {
        return <Spinner color={'#ff5a00'} />;
    }

    // if public or has permission
    if (!isPrivate || hasPermission) {
        return children;
    }

    if (!hasPermission) {
        return (
            <Box>
                <Heading>Missing Permission</Heading>
                <Text>{`You don't have the required permission to access ${resourceName || 'this resource'} `}</Text>
            </Box>
        );
    }
    return (
        <Box>
            <Heading>{`Private ${resourceName || 'Resource'}`}</Heading>
            <Text>{`You are trying to access private ${resourceName || 'resource'}.`}</Text>
        </Box>
    );
};

WithConfiguration.defaultProps = {
    permissionTypes: [PermissionType.Allow],
};

export const WithConfigurationContainer = (props: IWithConfigurationProps) => <WithConfiguration {...props} />;
