import React, { Fragment } from 'react';
import { RequestCluster } from '../../request-cluster';
import './screenshot-generator.scss';

const SS_URL = 'https://screenshot-service.internet-czas-dzialac.pl';

enum taskState {
    WAITING = 'waiting',
    RUNNING = 'running',
    FINISHED = 'finished',
}

type Screenshot = {
    url: string;
    thumb_url: string;
    domain: string;
    filename: string;
    found_headers: string[];
};

interface screenshotTask {
    domains: string[];
    elapsed_time_s: number;
    current_action: string;
    finished_time: number;
    id: string;
    images: Screenshot[];
    jobs_ahead: number;
    output: string;
    processing_took: number;
    request_time: number;
    started_time: number;
    status: taskState;
    url: string;
    waiting_took: number;
    zip_url: string;
    preview: string;
}

function createTaskEndpoint(visited_url: string, domains: string[]) {
    return `${SS_URL}/api/requests?url=${encodeURIComponent(visited_url)}${domains.reduce(
        (prev: string, curr: string) => prev + '&domains[]=' + curr,
        ''
    )}`;
}

function createTask(visited_url: string, domains: string[]) {
    return fetch(createTaskEndpoint(visited_url, domains), { method: 'POST' });
}

function pollTask(path: string): Promise<Response> {
    return fetch(path, { method: 'GET' });
}

export default function ScreenshotGenerator({
    visited_url,
    clusters,
    setReportWindowMode,
    setRequestPath,
    downloadFiles,
    user_role,
}: {
    visited_url: string;
    clusters: Record<string, RequestCluster>;
    setReportWindowMode: Function;
    setRequestPath: Function;
    downloadFiles: Function;
    user_role: string;
}) {
    const [mode, setMode] = React.useState<string>('idle');
    const [images, setImages] = React.useState<Screenshot[]>([]);
    const [taskId, setTaskId] = React.useState<string | null>(null);
    const [output, setOutput] = React.useState<any>({});
    const [currentAction, setCurrentAction] = React.useState<string>('');
    const [preview, setPreview] = React.useState<string>('');
    const [lastPreview, setLastPreview] = React.useState<string>('');

    async function subscribeTask(path: string): Promise<screenshotTask> {
        let response = { status: taskState.WAITING };
        let last_preview = '';
        while (response.status === taskState.WAITING || response.status === taskState.RUNNING) {
            await new Promise((resolve) => setTimeout(resolve, 1000));
            response = await (await pollTask(path)).json();
            setImages((response as screenshotTask)?.images);
            setCurrentAction((response as screenshotTask)?.current_action);
            setLastPreview(last_preview);
            setPreview((response as screenshotTask)?.preview);
            last_preview = (response as screenshotTask)?.preview;
            document.querySelector('.images')?.scrollTo({
                top: document.querySelector('.images')?.scrollHeight,
                behavior: 'smooth',
            });
        }

        if (response.status === taskState.FINISHED) {
            setMode('finished');
        }
        return response as screenshotTask;
    }

    return (
        <div className="generator-container">
            {mode === 'idle' ? (
                <Fragment>
                    <h1>Przygotowanie zrzutów ekranów</h1>
                    <div className="container">
                        <h2>Notka informacyjna</h2>
                        <img
                            src="/assets/doctor_welcome.png"
                            style={{
                                width: '100%',
                                maxWidth: '360px',
                                float: 'right',
                                position: 'relative',
                                top: '-10px',
                            }}
                        />
                        <Fragment>
                            <p>
                                W celu udokumentowania procesów przetwarzania danych, jakie wykryła
                                nasza wtyczka na tej stronie, warto wykonać zrzuty ekranu, na
                                których widać przeglądarkę z otwartymi narzędziami deweloperskimi,
                                ukazując wybrane elementy ruchu sieciowego generowanego przez
                                stronę.
                            </p>
                            <p>Jeżeli chcesz, wtyczka Rentgen może wygenerować je za Ciebie.</p>
                            <p>
                                Uwaga: aby to zrobić, adres aktualnie odwiedzonej podstrony
                                analizowanej witryny będzie wysłany na nasz serwer, aby na nim
                                odwiedzić tę podstronę i wykonać zrzuty ekranu.
                            </p>
                            <p>
                                Serwer, na którym jest wykonywana analiza należy do inicjatywy{' '}
                                <a href="https://www.internet-czas-dzialac.pl/contact/">
                                    <i>Internet. Czas działać!</i>
                                </a>
                                . Zebrane dane nie są wysyłane do żadnych podmiotów trzecich i są
                                usuwane z serwera po 24 godzinach. Wysłanie na serwer informacji o
                                adresie przeglądanej strony jest konieczne, aby wykonać te zrzuty
                                ekranu w sposób automatyczny. Jeżeli nie chcesz korzystać z opcji
                                automatycznej, zachęcamy do wykonania zrzutów ekranu samodzielnie.
                            </p>
                        </Fragment>
                    </div>

                    <div className="buttons-container">
                        <button
                            className="sv_prev_btn"
                            onClick={() => {
                                setReportWindowMode('preview');
                                setRequestPath(null);
                            }}
                        >
                            Pomiń
                        </button>
                        <button
                            className="sv_next_btn"
                            onClick={async () => {
                                setMode('in_progress');
                                const task = await createTask(
                                    visited_url,
                                    Object.values(clusters)
                                        .filter((cluster) => cluster.hasMarks())
                                        .map((cluster) => cluster.id)
                                );
                                const urlArr = task.url.split('/');
                                setTaskId(urlArr[urlArr.length - 1]);
                                const response = await subscribeTask(task.url);
                                setImages(response.images);
                                setLastPreview(preview);
                                setPreview(response.preview);
                                setOutput(response);
                                setRequestPath(response.zip_url);
                            }}
                        >
                            Wygeneruj
                        </button>
                    </div>
                </Fragment>
            ) : null}

            {mode === 'in_progress' || mode === 'finished' ? (
                <Fragment>
                    <h1>Przygotowanie zrzutów ekranów</h1>
                    <div className="container">
                        {mode === 'in_progress' ? (
                            <Fragment>
                                <h2>To może chwilkę zająć...</h2>
                                <p>
                                    Nasz serwer właśnie odwiedza wskazaną przez Ciebie stronę
                                    i przygotowuje zrzuty ekranów narzędzi deweloperskich.
                                </p>
                                <div>{currentAction}</div>
                            </Fragment>
                        ) : null}
                        {mode === 'finished' ? (
                            <Fragment>
                                <h2>Gotowe!</h2>
                                <p>Zrzuty ekranów narzędzi deweloperskich są gotowe do pobrania.</p>
                            </Fragment>
                        ) : null}

                        <div className="images">
                            {mode === 'in_progress' ? (
                                <div
                                    className="browser"
                                    style={{
                                        backgroundImage: `url(${SS_URL}${preview})${
                                            lastPreview ? `, url(${SS_URL}${lastPreview})` : ''
                                        }`,
                                    }}
                                >
                                    <div className="browser__header browser__header--in_progress">
                                        <div className="browser__header--address-bar"></div>
                                        <div className="browser__header--controls">· · ·</div>
                                    </div>
                                    <div className="browser__content"></div>
                                </div>
                            ) : null}
                            {images.map((screenshot) => {
                                return (
                                    <div
                                        key={`${taskId}_${screenshot.url}`}
                                        className="browser browser--filled"
                                        style={{
                                            backgroundImage: `url(${SS_URL}${screenshot.thumb_url})`,
                                        }}
                                    >
                                        <div className="browser__header">
                                            <div className="browser__header--address-bar">
                                                🕸 {screenshot.domain}
                                            </div>
                                            <div className="browser__header--controls">· · ·</div>
                                        </div>
                                        <div className="browser__content"></div>
                                    </div>
                                );
                            })}
                        </div>
                    </div>
                    <div className="buttons-container">
                        {mode === 'finished' ? (
                            <Fragment>
                                <button
                                    className="sv_next_btn"
                                    onClick={() => {
                                        downloadFiles(`${SS_URL}${output.zip_url}`);
                                        setReportWindowMode('preview');
                                    }}
                                >
                                    Pobierz zrzuty ekranów i przejdź dalej
                                </button>
                            </Fragment>
                        ) : null}
                    </div>
                </Fragment>
            ) : null}
        </div>
    );
}
