/**
 * 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 { FormValue } from "@wso2is/forms";
import { EmphasizedSegment } from "@wso2is/react-components";
import React, { FunctionComponent, ReactElement, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Grid } from "semantic-ui-react";
import { PermissionMappingList } from "./permission-mapping-list";
import { PermissionMappingListItem } from "./permission-mapping-list-item";
import { ExtendedFeatureConfigInterface } from "../../../../../configs/models";
import { APIResourcePermissionInterface } from "../../../models";

/**
 * Prop-types for the API resources page component.
 */
interface AddAPIResourcePermissionsInterface extends SBACInterface<ExtendedFeatureConfigInterface>,
    IdentifiableComponentInterface {
    /**
     * Initial permission list.
     */
    initialPermissions: Map<string, APIResourcePermissionInterface>;
    /**
     * Trigger add permission form submit action.
     */
    triggerAddPermission: boolean;
    /**
     * API Resource permissions list.
     */
    apiResourcePermissionsListData: APIResourcePermissionInterface[];
    /**
     * is API Resource permissions list loading.
     */
    isAPIResourcePermissionsListLoading: boolean;
    /**
     * set the current permission identifier.
     */
    setCurrentPermissionIdentifierValue: (permissionIdentifier: string) => void;
    /**
     * Callback to be trigger to get the permission list.
     */
    mutateAPIResourcePermissionsFetchRequest: () => void;
    /**
     * Set the trigger add permission form submit action.
     */
    setAddPermission: () => void;
    /**
     * Set the permission list.
     */
    setPermissionsList : (permissions: Map<string, APIResourcePermissionInterface>) => void;
    /**
     * Set the latest permission form values.
     */
    setLatestPermissionFormValues: (formValue: Map<string, FormValue>) => void;
}

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

    const {
        initialPermissions,
        triggerAddPermission,
        apiResourcePermissionsListData,
        isAPIResourcePermissionsListLoading,
        mutateAPIResourcePermissionsFetchRequest,
        setCurrentPermissionIdentifierValue,
        setAddPermission,
        setPermissionsList,
        setLatestPermissionFormValues
    } = props;

    const { t } = useTranslation();

    const [ addedPermissions, setAddedPermissions ] 
        = useState<Map<string, APIResourcePermissionInterface>>(initialPermissions ? initialPermissions : new Map());

    /**
     * Update the permission list when the added permissions map is updated.
     */
    useEffect(() => {
        setPermissionsList(addedPermissions);
    }, [ addedPermissions ]);
    
    /**
     * Update the permission map when a new permission is added or deleted.
     * 
     * @param permission - The permission to be added or deleted.  `APIResourcePermissionInterface`
     * @param action - The action to be performed. `set` or `delete`
     */
    const updatePermissions = (permission: APIResourcePermissionInterface, action : "set" | "delete"): void => {
        const updatedPermissions: Map<string, APIResourcePermissionInterface> = new Map(addedPermissions);

        switch (action) {
            case "set":
                updatedPermissions.set(permission.name, permission);

                break;
            
            case "delete":
                updatedPermissions.delete(permission.name);

                break;
        
            default:
                break;
        }
        setAddedPermissions(updatedPermissions);
    };

    return (
        <Grid>
            <Grid.Row columns={ 1 }>
                <Grid.Column width={ 16 }>
                    <EmphasizedSegment className="mb-3">
                        <PermissionMappingListItem
                            addedPermissions={ addedPermissions }
                            updatePermissions={ updatePermissions }
                            triggerAddPermission={ triggerAddPermission }
                            setAddPermission={ setAddPermission }
                            setLatestPermissionFormValues={ setLatestPermissionFormValues }
                            setCurrentPermissionIdentifierValue={ setCurrentPermissionIdentifierValue }
                            apiResourcePermissionsListData={ apiResourcePermissionsListData }
                            isAPIResourcePermissionsListLoading={ isAPIResourcePermissionsListLoading }
                            mutateAPIResourcePermissionsFetchRequest={ mutateAPIResourcePermissionsFetchRequest } />
                    </EmphasizedSegment>
                </Grid.Column>
                <Grid.Column width={ 16 }>
                    <React.Fragment>
                        <p className="permission-list-label mb-1">
                            { t("extensions:develop.apiResource.wizard.addApiResource.steps.permissions.form." +
                                "fields.permissionList.label") }
                        </p>
                        <EmphasizedSegment className="mt-0">
                            <PermissionMappingList 
                                addedPermissions={ addedPermissions }
                                updatePermissions={ updatePermissions } />
                        </EmphasizedSegment>
                    </React.Fragment>
                </Grid.Column>
            </Grid.Row>
        </Grid>
    );
};
