import { IBrowserModal } from '../../interfaces/components/file-input/IBrowserModal';
import { IFilesBrowserCommands } from '../../interfaces/commands/IFilesBrowserCommands';
import { IItem } from '../../interfaces/components/file-input/IItem';
import { IFileInputBus } from '../../interfaces/bus/IFileInputBus';
import { TFilesBrowserIcon, TFileType } from '../../types/TFilesBrowserIcon';

export class BrowserModal implements IBrowserModal {

    protected html: string = `
        <div class="fb-modal modal fade">
            <div class="modal-dialog modal-xl" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="exampleModalLabel">Выберите файл</h5>
                        <button type="button" class="js-close-btn close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
                    <div class="modal-body js-body">
                        <div class="files-container js-files-container"></div>
                    </div>
                    <div class="modal-footer">
                        <input type="file" id="fb-file-input" class="fb-file-input js-file-input" />
                        <label for="fb-file-input" class="btn btn-primary js-file-input-label">Загрузить файл</label>
                        <button type="button" class="btn btn-primary js-create-dir-button">Создать папку</button>
                    </div>
                </div>
            </div>
        </div>
    `;

    protected _template: HTMLElement;

    protected body: HTMLElement;

    protected jsContainer: HTMLElement;

    protected closeBtn: HTMLElement;

    protected createDirButton: HTMLElement;

    protected fileInput: HTMLElement;

    protected filesBrowserCommands: IFilesBrowserCommands;

    protected icons: IItem[] = [];

    protected resolve: any;

    protected reject: any;

    protected bus: IFileInputBus;

    protected currentPath: string = '';

    protected createItem: () => IItem;

    public setItemCreator(creator: () => IItem) {
        this.createItem = creator;
    }

    public setFileInputBus(bus: IFileInputBus) {
        this.bus = bus;
    }

    public setCurrentPath(path: string) {
        let segments = path.split('/');
        let stack = [];
        for (let i in segments) {
            if (segments[i] == '' && +i > 0) {
                continue;
            }
            if (segments[i] == '..') {
                // Ignore this segment, remove last segment from stack
                stack.pop();
                continue;
            }
            if (segments[i] == '.') {
                // Ignore this segment
                continue;
            }
            stack.push(segments[i]);
        }
        this.currentPath = stack.join('/');
    }

    public constructor() {
        let div = document.createElement('div');
        div.innerHTML = this.html.trim();
        this._template = <HTMLElement>div.firstChild;
        this.body = this._template.querySelector('.js-body');
        this.jsContainer = this._template.querySelector('.js-files-container');
        this.createDirButton = this._template.querySelector('.js-create-dir-button');
        this.fileInput = this._template.querySelector('.js-file-input');
        this.closeBtn = this._template.querySelector('.js-close-btn');
    }

    public get template(): HTMLElement {
        return this._template;
    }

    public setFilesBrowserCommands(commands: IFilesBrowserCommands) {
        this.filesBrowserCommands = commands;
    }

    public show(): Promise<string> {
        return new Promise<string>((resolve: any, reject: any) => {
            this.resolve = resolve;
            this.reject = reject;
            this.filesBrowserCommands.getDir('')
                .then((resp: any) => {
                    this.jsContainer.innerHTML = '';
                    this.icons = [];
                    for (let data of resp) {
                        if (data.name == '.') {
                            continue;
                        }
                        this.newItem(data);
                    }
                });
            this._template.classList.add('show');
            this._template.style.display = 'block';
        });
    }

    public hide() {
        this._template.classList.remove('show');
        this._template.style.display = 'none';
        this.bus.hideItemContextMenu();
    }

    public eventsListen() {
        this._template.onclick = (e: Event) => {
            this.bus.hideItemContextMenu();
        };
        this.closeBtn.onclick = () => {
            this.hide();
        }
        this.createDirButton.onclick = (e: Event) => {
            let dirName = '';
            this.bus.execItemModal()
                .then((name: string) => {
                    dirName = name;
                    return this.filesBrowserCommands.createDir(this.currentPath + '/' + name);
                })
                .then((resp: any) => {
                    if (resp.success) {
                        this.bus.createdDir(this.currentPath, dirName);
                    }
                });
        };
        this.fileInput.onchange = (e: Event) => {
            e.preventDefault();
            if ((<any>event.target).files.length >= 1) {
                let file = (<any>event.target).files[0];
                this.filesBrowserCommands.uploadFile(this.currentPath + '/' + file.name, file)
                    .then((resp: any) => {
                        if (resp.success && resp.type == TFileType.file) {
                            this.bus.uploadedFile(this.currentPath, resp.fileName);
                        }
                        if (resp.success && resp.type == TFileType.img) {
                            this.bus.uploadedImg(this.currentPath, resp.fileName);
                        }
                    });
            }
        };
    }

    public update(icons: TFilesBrowserIcon[]) {
        this.jsContainer.innerHTML = '';
        this.icons = [];
        for (let data of icons) {
            if (data.name == '.') {
                continue;
            }
            this.newItem(data);
        }
    }

    public deleteFile(path: string) {
        for (let i in this.icons) {
            if (this.icons[i].getData().path + '/' + this.icons[i].getData().name == path) {
                this.icons[i].template.remove();
                this.icons.splice(+i, 1);
                break;
            }
        }
    }

    public renameFile(path: string, newName: string) {
        for (let i in this.icons) {
            if (this.icons[i].getData().path + '/' + this.icons[i].getData().name == path) {
                this.icons[i].rename(newName);
                break;
            }
        }
    }

    public newItem(data: TFilesBrowserIcon) {
        let item = this.createItem();
        item.setOnSelectedFile((fileName: string) => {
            this.resolve(fileName);
            this.hide();
        });
        item.load(data);
        this.jsContainer.append(item.template);
        item.eventsListen();
        this.icons.push(item);
    }

}