import React, { useContext, useEffect, useState } from 'react';
import Loading from './Loading';
import { Alert, Col, Row } from 'react-bootstrap';
import { fetchImport } from '../../core/imports';
import {
    InfinityMintProjectAsset,
    InfinityMintProjectPath,
} from 'infinitymint/dist/app/interfaces';
import { Project } from '../../core/project';
import { ClientContext } from '../../contexts/clientProvider';
import { cutLongString, log } from '../../utils/helpers';

let currentExecution = false;
const awaitCurrentExecution = () => {
    let interval;
    return new Promise((resolve, reject) => {
        interval = setInterval(() => {
            if (!currentExecution) {
                clearInterval(interval);
                resolve(true);
            }
        }, 100);
    });
};

export default function PathImage({
    path,
    project = null,
    waitForOthers = true,
    maxHeight = 256,
}: {
    path: InfinityMintProjectPath | InfinityMintProjectAsset;
    project?: Project;
    waitForOthers?: boolean;
    maxHeight?: number;
    forceHeight?: boolean;
}) {
    const [loaded, setLoaded] = useState(false);
    const [rendered, setRendered] = useState(false);
    const [base64Encoded, setBase64Encoded] = useState(null);
    const client = useContext(ClientContext);

    useEffect(() => {
        setLoaded(false);
    }, []);

    useEffect(() => {
        if (!path || !client.loaded) return;
        let currentProject = project || client.project;

        const main = async () => {
            setLoaded(false);

            if (currentExecution && waitForOthers) {
                log('Waiting for other fetch to finish...');
                await awaitCurrentExecution();
            }

            if (waitForOthers) currentExecution = true;
            let blob = await fetchImport(
                currentProject.deployedProject,
                path.export,
                null,
                false,
                client.controller.apiAccess
            );

            let ext =
                currentProject.deployedProject.bundles.imports[
                    currentProject.deployedProject.imports[path.export.key]
                ].extension.substring(1);

            let encoding = 'image/' + ext;
            if (ext === 'svg') encoding = 'image/svg+xml';
            setBase64Encoded(
                `data:${encoding};base64,` +
                    Buffer.from(await blob.arrayBuffer()).toString('base64')
            );
            setLoaded(true);

            if (waitForOthers) currentExecution = false;
        };
        main();
    }, [path, project, client, waitForOthers]);

    return (
        <div className="d-grid">
            {!loaded ? (
                <Row className="d-grid">
                    <Col lg={12} className="d-grid m-0">
                        <Alert
                            variant="secondary"
                            className="text-center d-grid"
                            style={{
                                maxHeight: maxHeight + 'px',
                            }}
                        >
                            <span
                                className="spinning d-block"
                                style={{
                                    fontSize: '2.25vw',
                                }}
                            >
                                🚀
                            </span>
                            <p className="fs-4">
                                Loading
                                <br />
                                <span
                                    className="badge bg-secondary"
                                    style={{
                                        fontSize: '0.4rem',
                                        wordBreak: 'break-all',
                                    }}
                                >
                                    {cutLongString(
                                        path.export.key.split('@')?.[1] ||
                                            path.export.key,
                                        30
                                    )}
                                </span>
                            </p>
                        </Alert>
                    </Col>
                </Row>
            ) : (
                <Row>
                    <Col className="d-grid">
                        {!rendered ? (
                            <div className="d-flex justify-content-center">
                                <Loading />
                            </div>
                        ) : (
                            <></>
                        )}

                        <img
                            src={base64Encoded}
                            alt={'path ' + path.pathId}
                            className="img img-fluid d-grid mx-auto"
                            style={{
                                maxHeight: maxHeight + 'px',
                                maxWidth: '100%',
                                display: 'none',
                            }}
                            loading="lazy"
                            onLoadStartCapture={() => {
                                console.log('test');
                            }}
                            onLoad={(e) => {
                                setRendered(true);
                                e.currentTarget.style.display = 'block';
                            }}
                        />
                    </Col>
                </Row>
            )}
        </div>
    );
}
