/**
 * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com). All Rights Reserved.
 *
 * This software is the property of WSO2 LLC. and its suppliers, if any.
 * Dissemination of any information or reproduction of any material contained
 * herein in any form is strictly forbidden, unless permitted by WSO2 expressly.
 * You may not alter or remove any copyright or other notice from copies of this content.
 */

import { IdentifiableComponentInterface, SBACInterface } from "@wso2is/core/models";
import { CommonUtils } from "@wso2is/core/utils";
import {
    DataTable, EmptyPlaceholder, LinkButton, PrimaryButton, TableActionsInterface, TableColumnInterface
} from "@wso2is/react-components";
import { getEmptyPlaceholderIllustrations } from "apps/console/src/features/core";
import React, { FunctionComponent, ReactElement, ReactNode, SyntheticEvent, useState } from "react";
import { useTranslation } from "react-i18next";
import { Header, Icon, Label, SemanticICONS } from "semantic-ui-react";
import { ExtendedFeatureConfigInterface } from "../../../../configs/models";
import { APIResourcePanesCommonPropsInterface, APIResourcePermissionInterface } from "../../models";

/**
 * Prop-types for the API resources page component.
 */
interface PermissionListAPIResourceInterface extends SBACInterface<ExtendedFeatureConfigInterface>,
    IdentifiableComponentInterface, APIResourcePanesCommonPropsInterface {
    /**
     * List of API resource permissions
     */
    permissionList: APIResourcePermissionInterface[];
    /**
     * Search results for API resources permissions
     */
    serachedPermissionList: APIResourcePermissionInterface[]
    /**
     * Clear the search query.
     */
    clearSearchPermission: () => void;
    /**
     * Set the permission to be removed.
     */
    setRemovePermission: (permission: APIResourcePermissionInterface) => void;
    /**
     * Open add permission modal.
     */
    setTriggerAddAPIResourcePermissionModal: () => void;
}

/**
 * API Resources listing page.
 *
 * @param props - Props injected to the component.
 * @returns API Resources Page component
 */
export const PermissionListAPIResource: FunctionComponent<PermissionListAPIResourceInterface> = (
    props: PermissionListAPIResourceInterface
): ReactElement => {

    const {
        permissionList,
        serachedPermissionList,
        isAPIResourceDataLoading,
        isSubmitting,
        isReadOnly,
        isManagedByChoreo,
        clearSearchPermission,
        setRemovePermission,
        setTriggerAddAPIResourcePermissionModal,
        ["data-componentid"]: componentId
    } = props;

    const { t } = useTranslation();

    const [ clickedPermission, setClickedPermission ] = useState<APIResourcePermissionInterface>(undefined);

    /**
     * Resolves data table actions.
     *
     * @returns `TableActionsInterface[]`
     */
    const resolveTableActions = (): TableActionsInterface[] => {
        const actions: TableActionsInterface[] = [
            {
                "data-componentid": `${componentId}-item-copy-button`,
                icon: (): SemanticICONS => "copy",
                onClick: (e: SyntheticEvent, permission: APIResourcePermissionInterface): void => {
                    copyValueToClipboard(e, permission);
                },
                popupText: (permission: APIResourcePermissionInterface): string => {
                    return clickedPermission?.name === permission.name
                        ? t("extensions:develop.apiResource.tabs.permissions.copiedPopupText")
                        : t("extensions:develop.apiResource.tabs.permissions.copyPopupText");
                },
                renderer: "semantic-icon"
            },
            {
                "data-componentid": `${componentId}-item-delete-button`,
                hidden: () => isReadOnly || isManagedByChoreo,
                icon: (): SemanticICONS => "trash alternate",
                onClick: (e: SyntheticEvent, permission: APIResourcePermissionInterface): void => {
                    removePermission(permission);
                },
                popupText: (): string => t("extensions:develop.apiResource.tabs.permissions.removePermissionPopupText"),
                renderer: "semantic-icon"
            }
        ];

        return actions;
    };

    /**
     * Resolves data table columns.
     * First column is the permission name and the second column is the description.
     *
     * @returns `TableColumnInterface[]`
     */
    const resolveTableColumns = (): TableColumnInterface[] => {
        return [
            {
                allowToggleVisibility: false,
                dataIndex: "displayName",
                id: "displayName",
                key: "displayName",
                render: (permission: APIResourcePermissionInterface): ReactNode => (
                    <Header as="h6" data-testid={ `${componentId}-permission-display-name` }>
                        <Header.Content>
                            { permission.displayName }
                            <Header.Subheader>
                                <Label size="medium" className="ml-0 mt-2">
                                    <Label.Detail className="ml-0">{ permission.name }</Label.Detail>
                                </Label>
                            </Header.Subheader>
                        </Header.Content>
                    </Header>
                ),
                title: t("extensions:develop.apiResource.tabs.permissions.form.fields.permission.label"),
                width: 3
            },
            {
                allowToggleVisibility: false,
                dataIndex: "description",
                id: "description",
                key: "description",
                render: (permission: APIResourcePermissionInterface): ReactNode => (
                    <Header as="h6" data-testid={ `${componentId}-description` }>
                        <Header.Content>
                            <Header.Subheader>
                                { permission.description }
                            </Header.Subheader>
                        </Header.Content>
                    </Header>
                ),
                title: t("extensions:develop.apiResource.tabs.permissions.form.fields.description.label")
            },
            {
                allowToggleVisibility: false,
                dataIndex: "action",
                id: "actions",
                key: "actions",
                textAlign: "right",
                title: t("extensions:develop.apiResource.tabs.permissions.form.fields.permission.label")
            }
        ];
    };

    /**
     * Empty placeholder for the API resource permissions list.
     * 
     * @returns `ReactElement`
     */
    const showPlaceholders = (): ReactElement => {
        if (permissionList?.length === 0) {
            return ( 
                <EmptyPlaceholder
                    subtitle = { !isManagedByChoreo && 
                        [ t("extensions:develop.apiResource.tabs.permissions.empty.subTitle") ] }
                    title={ t("extensions:develop.apiResource.tabs.permissions.empty.title") }
                    image={ getEmptyPlaceholderIllustrations().emptyList }
                    action={
                        !isManagedByChoreo && (<PrimaryButton
                            data-componentid= { `${componentId}-add-permission-button` }
                            onClick={ setTriggerAddAPIResourcePermissionModal }>
                            <Icon name="add" />
                            { t("extensions:develop.apiResource.tabs.permissions.button") }
                        </PrimaryButton>)
                    }
                    imageSize="tiny"
                />
            );
        }
        if (serachedPermissionList?.length === 0) {
            return (
                <EmptyPlaceholder
                    subtitle={ [ t("extensions:develop.apiResource.tabs.permissions.emptySearch.subTitle.0"),
                        t("extensions:develop.apiResource.tabs.permissions.emptySearch.subTitle.1") ] }
                    title={ t("extensions:develop.apiResource.tabs.permissions.emptySearch.title") }
                    image={ getEmptyPlaceholderIllustrations().emptySearch }
                    action={
                        (<LinkButton onClick={ clearSearchPermission }>
                            { t("extensions:develop.apiResource.tabs.permissions.emptySearch.viewAll") }
                        </LinkButton>)
                    }
                    imageSize="tiny"
                />
            );
        }
        
        return null;
    };

    /**
     * Handels the remove permission action.
     *
     * @param permission - `APIResourcePermissionInterface`
     */
    const removePermission = (permission: APIResourcePermissionInterface): void => {
        setRemovePermission(permission);
    };

    /**
     * Copies the value to the users clipboard.
     *
     * @param event - `MouseEvent<HTMLButtonElement>`
     * @param permission - `APIResourcePermissionInterface`
     */
    const copyValueToClipboard = async (event: SyntheticEvent, permission: APIResourcePermissionInterface) => {
        event.stopPropagation();
        await CommonUtils.copyTextToClipboard(permission.name);

        // Set the clicked permission.
        setClickedPermission(permission);
    };

    return (
        <DataTable<APIResourcePermissionInterface>
            className="oidc-scopes-table"
            columnCount={ 3 }
            isLoading={ isAPIResourceDataLoading || isSubmitting }
            loadingStateOptions={ {
                count: 10,
                imageType: "square"
            } }
            onRowClick={ copyValueToClipboard }
            showHeader={ false }
            placeholders={ showPlaceholders() }
            transparent={ permissionList?.length === 0 || serachedPermissionList?.length === 0 }
            data-testid={ componentId }
            actions={ resolveTableActions() }
            columns={ resolveTableColumns() }
            data={ serachedPermissionList }
        />
    );
};

/**
 * Default props for the component.
 */
PermissionListAPIResource.defaultProps = {
    "data-componentid": "permission-list-api-resource"
};
