/**
 * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.com). All Rights Reserved.
 *
 * This software is the property of WSO2 Inc. 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 { TestableComponentInterface } from "@wso2is/core/models";
import { CodeEditor, GenericIcon, Heading, Text } from "@wso2is/react-components";
import React, { FunctionComponent, ReactElement, ReactNode, useEffect, useState } from "react";
import { Button, Divider, Icon } from "semantic-ui-react";
import { dotNetSDKInstallerConfigCode, tomcatOIDCSamplePropertiesFileCode } from "./code-blocks";
import { SDKMeta } from "./meta";
import { SupportedTraditionalOIDCAppTechnologyTypes } from "./models";
import {
    ApplicationInterface,
    ApplicationTemplateInterface
} from "../../../../features/applications";
import { Config, getTechnologyLogos } from "../../../../features/core/configs";
import TomcatLogo from "../../../assets/images/icons/tomcat-icon.svg";
import {
    VerticalStepper,
    VerticalStepperStepInterface
} from "../../../components/component-extensions/application/vertical-stepper";

interface TryoutSamplesPropsInterface extends TestableComponentInterface {
    application: ApplicationInterface;
    template: ApplicationTemplateInterface;
    technology: SupportedTraditionalOIDCAppTechnologyTypes;
    inboundProtocolConfig: any;
}

/**
 * Tryout Samples of Single Page Applications.
 *
 * @param {TryoutSamplesPropsInterface} props - Props injected into the component.
 * @return {React.ReactElement}
 */
export const TryoutSamples: FunctionComponent<TryoutSamplesPropsInterface> = (
    props: TryoutSamplesPropsInterface
): ReactElement => {

    const {
        inboundProtocolConfig,
        technology,
        [ "data-testid" ]: testId
    } = props;

    const [ authConfig, setAuthConfig ] = useState(undefined);

    useEffect(() => {
        if (inboundProtocolConfig == undefined) {
            return;
        }

        const configs = {
            clientID: inboundProtocolConfig.oidc.clientId,
            clientSecret: inboundProtocolConfig.oidc.clientSecret,
            serverOrigin: Config.getDeploymentConfig().serverHost
        };

        setAuthConfig(configs);
    }, [ inboundProtocolConfig ]);

    const generateSampleDownloadStep = (technology: SupportedTraditionalOIDCAppTechnologyTypes) => {

        if (technology === SupportedTraditionalOIDCAppTechnologyTypes.TOMCAT_OIDC_AGENT) {
            return (
                <>
                    <p>Click on the button below to download the sample.</p>
                    <Button
                        basic
                        data-testid={ `${ testId }-download-oidc-tomcat-sample` }
                        className="sample-action-button download"
                        onClick={ () => window.open(SDKMeta.tomcatOIDCAgent.sample.artifact, "") }
                    >
                        <GenericIcon
                            transparent
                            icon={ TomcatLogo }
                            size="mini"
                            spaced="right"
                            floated="left"
                        />
                        Download { technology } Sample
                        <Icon name="download" className="ml-2" />
                    </Button>
                    <Button
                        basic
                        className="sample-action-button github"
                        onClick={ () => window.open(SDKMeta.tomcatOIDCAgent.sample.repository, "") }
                    >
                        View source on GitHub
                        <Icon name="github" className="ml-2" />
                    </Button>
                </>
            );
        }

        if (technology === SupportedTraditionalOIDCAppTechnologyTypes.DOT_NET) {
            return (
                <>
                    <p>Click on the button below to download the sample.</p>
                    <Button
                        basic
                        data-testid={ `${ testId }-download-dotnet-sample` }
                        className="sample-action-button download"
                        onClick={ () => window.open(SDKMeta.dotNet.sample.artifact, "") }
                    >
                        <GenericIcon
                            transparent
                            icon={ getTechnologyLogos().dotNet }
                            size="mini"
                            spaced="right"
                            floated="left"
                        />
                        Download { technology } Sample
                        <Icon name="download" className="ml-2" />
                    </Button>
                    <Button
                        basic
                        className="sample-action-button github"
                        onClick={ () => window.open(SDKMeta.dotNet.sample.repository, "") }
                    >
                        View source on GitHub
                        <Icon name="github" className="ml-2" />
                    </Button>
                </>
            );
        }
    };

    const generateIntegrateCode = (technology: SupportedTraditionalOIDCAppTechnologyTypes) => {

        if (!authConfig) {
            return null;
        }

        if (technology === SupportedTraditionalOIDCAppTechnologyTypes.TOMCAT_OIDC_AGENT) {
            return tomcatOIDCSamplePropertiesFileCode(authConfig);
        }

        if (technology === SupportedTraditionalOIDCAppTechnologyTypes.DOT_NET) {
            return dotNetSDKInstallerConfigCode(authConfig);
        }
    };

    const generateConfigureStep = (technology: SupportedTraditionalOIDCAppTechnologyTypes) => {

        if (technology === SupportedTraditionalOIDCAppTechnologyTypes.TOMCAT_OIDC_AGENT) {
            return (
                <>
                    <Text>
                        Update the the <code className="inline-code">oidc-sample-app.properties</code>
                        file in <code className="inline-code">&#60;APP_HOME&#62;/WEB-INF/classes</code>
                        with the following.
                    </Text>
                    <div className="code-segment">
                        <CodeEditor
                            readOnly
                            withClipboardCopy
                            showLineNumbers
                            language="htmlmixed"
                            sourceCode={
                                generateIntegrateCode(SupportedTraditionalOIDCAppTechnologyTypes.TOMCAT_OIDC_AGENT)
                            }
                            options={ {
                                lineWrapping: true
                            } }
                            height="100%"
                            theme="dark"
                        />
                    </div>
                    <Divider hidden/>
                </>
            );
        }

        if (technology === SupportedTraditionalOIDCAppTechnologyTypes.DOT_NET) {
            return (
                <>
                    <Text>
                        Double click the <code className="inline-code">PickupManagerOIDC-v0.1.1.msi</code> and
                        follow the on-screen guidance until you get to the app configuration window.
                    </Text>
                    <Text>
                        Fill the corresponding fields with the following information.
                    </Text>
                    <div className="code-segment">
                        <CodeEditor
                            oneLiner
                            readOnly
                            withClipboardCopy
                            showLineNumbers
                            className="application-sample-config-editor"
                            language="htmlmixed"
                            sourceCode={ generateIntegrateCode(technology) }
                            beautify={ true }
                            options={ {
                                lineWrapping: true
                            } }
                            height="100%"
                            theme="dark"
                        />
                    </div>
                    <Divider hidden/>
                    <Text>
                        Continue the on-screen guidance and complete the installation.
                    </Text>
                </>
            );
        }

        return null;
    };

    const generateRunStep = (technology: SupportedTraditionalOIDCAppTechnologyTypes): ReactNode => {

        if (technology === SupportedTraditionalOIDCAppTechnologyTypes.TOMCAT_OIDC_AGENT) {
            return (
                <>
                    <Text>
                        Deploy the application downloaded in the previous step using <strong>Apache Tomcat</strong>.
                    </Text>
                    <Text>
                        Try out the application by accessing the <a
                        href="http://localhost:8080/oidc-sample-app/index.html"
                        target="_blank"
                        rel="noopener noreferrer"
                        className="link external"
                        >http://localhost:8080/oidc-sample-app/index.html</a>
                    </Text>
                </>
            );
        }

        if (technology === SupportedTraditionalOIDCAppTechnologyTypes.DOT_NET) {
            return (
                <>
                    <Text>
                        Once the installation is complete the <code className="inline-code">
                        Pickup Manager - OIDC v0.1.1</code> application wiil be launched automatically.
                        You can always re-launch the application by double clicking on the
                        <code className="inline-code">Pickup Manager - OIDC v0.1.1</code> application
                        available on your Desktop.
                    </Text>
                </>
            );
        }

        return null;
    };

    const sampleFlowSteps: VerticalStepperStepInterface[] = [
        {
            stepContent: generateSampleDownloadStep(technology),
            stepTitle: "Download"
        },
        {
            stepContent: generateConfigureStep(technology),
            stepTitle: "Configure"
        },
        {
            stepContent: generateRunStep(technology),
            stepTitle: "Run"
        }
    ];

    const renderPrerequisitesStep = (): ReactElement => {

        return (
            <div className="mt-3 mb-6">
                <Heading as="h3">Prerequisite</Heading>
                <Text>
                    You will need to have <strong>Docker</strong> installed on
                    your environment to try out the sample.
                </Text>
                <Text>To download <strong>Docker</strong>, navigate to the official <a
                        href="https://docs.docker.com/get-docker/"
                        target="_blank"
                        rel="noopener noreferrer"
                        className="link external"
                    >downloads</a> page.
                </Text>
            </div>
        );
    };

    return (
        <>
            { renderPrerequisitesStep() }
            <VerticalStepper
                alwaysOpen
                isSidePanelOpen
                stepContent={ sampleFlowSteps }
                isNextEnabled={ technology !== undefined }
            />
        </>
    );
};
