import React from 'react';
import {withContextConsumer} from "@formanta/react";
import {cancelPromise} from "../../../component/cancelPromise";
import {withApiControl} from "../../../component/ApiControl";
import {withPusher, Pushing} from "../../../component/Pusher/Pusher";
import {ApiFileSend} from "../../../lib/ApiFileSend";

const StoreUploadContext = React.createContext({});

class StoreUploadProviderBase extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            parallel_uploads: 3,
            uploadFiles: this.uploadFiles
        };
    }

    uploaderFactory = (file, target, updateProgress, i) => new Promise((resolve, reject) => {
        (new ApiFileSend('files/add-one' + (target ? '/' + encodeURIComponent(target) : ''), true))
            .onProgress((e) => {
                updateProgress(file.id, (e.loaded * 100.0 / e.total) || 100);
            })
            .onFinish((e, xhr) => {
                if(xhr.readyState === 4 && xhr.status === 200) {
                    updateProgress(file.id, 'success');
                } else if(xhr.readyState === 4 && xhr.status !== 200) {
                    updateProgress(file.id, 'error');
                }
                resolve();
            })
            .exec({
                data: {
                    title: 'tldnsnele,m', caption: 'capti blabbel dei nbcew skn ejnje njdhd dmmdm'
                },
                file: file.file
            });
    });

    uploadBatch = (files, target, updateProgress, start = 0) => {
        const ret = [];
        let i = start;
        while(i < (start + this.state.parallel_uploads) && i < files.length) {
            if(files[i]) {
                ret.push(this.uploaderFactory(files[i], target, updateProgress, i));
            }
            i++;
        }
        return ret;
    };

    uploadAll = (files, target, updateProgress, i = 0) => {
        const current = this.uploadBatch(files, target, updateProgress, i);
        return Promise.all(current)
            .then(
                () => {
                    if(i < files.length) {
                        return this.uploadAll(files, target, updateProgress, i + this.state.parallel_uploads)
                    }
                    return;
                }
            );
    };

    uploadFiles = (files, target, updateProgress) => {
        const {cancelPromise, execPushing, handleApiFail} = this.props;

        cancelPromise(execPushing(
            new Pushing(
                'fileUploader',
                'fileUploader',
                (resolve, reject) => {
                    //this.setState({saving: this.createUpdatedSaving('docTree', 'progress')});
                    const file_arr = [];
                    Object.keys(files).forEach(id => {
                        if('init' === files[id].progress) {
                            file_arr.push(files[id]);
                        }
                    });
                    this.uploadAll(file_arr, target, updateProgress).then(() => {
                        resolve();
                    }).catch(
                        () => {
                            reject();
                        }
                    )
                }
            )
        ))
            .then((data) => {

            })
            .catch((err) => {
                handleApiFail(err, 'File Upload', false);

                if(!err.cancelled) {
                }
            });
    };

    render() {
        return (
            <StoreUploadContext.Provider value={this.state}>
                {this.props.children}
            </StoreUploadContext.Provider>
        );
    }
}

const StoreUploadProvider = cancelPromise(withPusher(withApiControl(StoreUploadProviderBase)));

const storeUpload = withContextConsumer(StoreUploadContext.Consumer);

export {StoreUploadProvider, storeUpload};