import React, { createContext, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { InfinityMintClient } from '../client';
import useClientContext from '../effects/useClientContext';
import { Dictionary } from 'infinitymint/dist/app/helpers';
import { Project } from '../core/project';
import Dashboard from '../Dashboard';
import storageController from '../core/storage';
import { InfinityMintClientConfig } from '../core/interfaces';
import WebEvents from '../webEvents';

export interface ClientContextType {
    controller: InfinityMintClient;
    loaded: boolean;
    error: Error;
    projects: Dictionary<Project>;
    project: Project;
    admin: boolean;
}

export const ClientContext = createContext({
    loaded: false,
    controller: null,
    error: null,
    projects: {},
    project: null,
    admin: false,
} as ClientContextType);

function ClientContextProvider({
    children,
    config,
}: {
    children: any;
    config: InfinityMintClientConfig;
}) {
    const { loaded, controller, error, projects, project, admin } =
        useClientContext({
            config,
        });

    const [showDashboard, setShowDashboard] = useState(
        storageController.getGlobalPreference('showDashboard')
    );

    const [showSetup, setShowSetup] = useState(
        storageController.getGlobalPreference('showSetup')
    );

    useEffect(() => {
        const toggleDashboard = () => {
            setShowDashboard(!showDashboard);
            storageController.setGlobalPreference(
                'showDashboard',
                !showDashboard
            );
        };
        WebEvents.off('toggleDashboard', toggleDashboard);
        WebEvents.on('toggleDashboard', toggleDashboard);
        return () => {
            WebEvents.off('toggleDashboard', toggleDashboard);
        };
    }, [showDashboard]);

    return (
        <ClientContext.Provider
            value={
                {
                    loaded,
                    controller,
                    error,
                    projects,
                    project,
                    admin,
                } as ClientContextType
            }
        >
            <>
                <style>
                    {`
                    .infinitymint-error {
                        position: fixed;
                        bottom: 0;
                        left: 0;
                        font-family: monospace;
                        padding: 10px;
                        width: 100%;
                        height: auto;
                        maxheight: 40%;
                        background-color: red;
                        color: white;
                        overflow-y: scroll;
                        opacity: 0.2;
                    }

                    .infinitymint-error:hover {
                        opacity: 1;
                    }
                    `}
                </style>
                {error ? (
                    <>
                        <div
                            className="infinitymint-error"
                            onClick={(e) => {
                                e.currentTarget.style.display = 'none';
                            }}
                        >
                            <h1>InfinityMint Error</h1>
                            <p>{error.message}</p>
                            <pre>{error.stack}</pre>
                        </div>
                    </>
                ) : null}
                {!error && showDashboard && loaded ? (
                    <Dashboard
                        onHide={() => {
                            setShowDashboard(false);
                            storageController.setGlobalPreference(
                                'showDashboard',
                                false
                            );
                            storageController.save();
                        }}
                    />
                ) : (
                    children
                )}
            </>
        </ClientContext.Provider>
    );
}

ClientContextProvider.propTypes = {
    children: PropTypes.any,
};

export default ClientContextProvider;
