import React, { createRef } from "react";
import path from "path";
import { Link } from "react-router-dom";
import { DragSource, DropTarget } from "react-dnd";
import "./thing.scss";
import { Card, NgIf, Icon, EventEmitter, img_placeholder, Input } from "../../components/";
import { pathBuilder, basename, filetype, prompt, alert, leftPad, getMimeType, debounce, memory } from "../../helpers/";
import { Files } from "../../model/";
import { ShareComponent } from "./share";
import { TagComponent } from "./tag";
import { t } from "../../locales/";
const canDrop = (props, monitor) => {
    const file = monitor.getItem();
    if (props.file.type !== "directory") return false;
    else if (file.name === props.file.name) return false;
    else if (props.file.icon === "loading") return false;
    else if (props.selected === true) return false;
    return true;
};
const HOCDropTargetForFsFile = (Cmp) => {
    const nativeFileTarget = {
        canDrop,
        drop(props, monitor) {
            const path = pathBuilder(props.path, props.file.name, "directory");
            props.emit(
                "file.upload",
                path,
                monitor.getItem(),
            );
        },
    };
    return DropTarget(
        "__NATIVE_FILE__",
        nativeFileTarget,
        (connect, monitor) => ({
            connectDropNativeFile: connect.dropTarget(),
            nativeFileIsOver: monitor.isOver(),
            canDropNativeFile: monitor.canDrop(),
        }),
    )(Cmp);
};
const HOVDropTargetForVirtualFile = (Cmp) => {
    const fileTarget = {
        canDrop,
        drop(props, monitor, component) {
            const src = monitor.getItem();
            const dest = props.file;
            if (props.currentSelection.length === 0) {
                const from = pathBuilder(props.path, src.name, src.type);
                const to = pathBuilder(props.path, "./"+dest.name+"/"+src.name, src.type);
                return {
                    action: "rename",
                    args: [from, to, src.type],
                    ctx: "existingfile",
                };
            } else {
                return {
                    action: "rename.multiple",
                    args: props.currentSelection.map((selectionPath) => {
                        const from = selectionPath;
                        const to = pathBuilder(
                            props.path,
                            "./"+dest.name+"/"+basename(selectionPath),
                            filetype(selectionPath),
                        );
                        return [from, to];
                    }),
                };
            }
        },
    };
    return DropTarget(
        "file",
        fileTarget,
        (connect, monitor) => ({
            connectDropFile: connect.dropTarget(),
            fileIsOver: monitor.isOver(),
            canDropFile: monitor.canDrop(),
        }),
    )(Cmp);
};
const HOVDropSourceForVirtualFile = (Cmp) => {
    const fileSource = {
        beginDrag(props, monitor, component) {
            return {
                path: props.path,
                name: props.file.name,
                type: props.file.type,
            };
        },
        canDrag(props, monitor) {
            if (props.metadata.can_move === false) {
                return false;
            }
            if (props.file.icon === "loading") return false;
            else if (props.selected === false && props.currentSelection.length > 0) return false;
            return true;
        },
        endDrag(props, monitor, component) {
            if (monitor.didDrop() && component.state.icon !== "loading") {
                const result = monitor.getDropResult();
                if (result.action === "rename") {
                    props.emit.apply(component, ["file.rename"].concat(result.args));
                } else if (result.action === "rename.multiple") {
                    props.emit.call(component, "file.rename.multiple", result.args);
                } else {
                    throw new Error("unknown action");
                }
            }
        },
    };
    return DragSource(
        "file",
        fileSource,
        (connect, monitor) => ({
            connectDragSource: connect.dragSource(),
            isDragging: monitor.isDragging(),
        }),
    )(Cmp);
};
class ExistingThingComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            hover: null,
            filename: props.file.name,
            is_renaming: false,
            preview: null,
        };
    }
    shouldComponentUpdate(nextProps, nextState) {
        if (nextState.hover !== this.state.hover ||
            nextState.is_renaming !== this.state.is_renaming ||
            nextProps.view !== this.props.view ||
            this.state.preview !== nextState.preview ||
            this.props.fileIsOver !== nextProps.fileIsOver ||
            this.props.canDropFile !== nextProps.canDropFile ||
            this.props.nativeFileIsOver !== nextProps.nativeFileIsOver ||
            this.props.canDropNativeFile !== nextProps.canDropNativeFile ||
            this.props.selected !== nextProps.selected) return true;
        return false;
    }
    componentDidMount() {
        this.updateThumbnail(this.props);
    }
    UNSAFE_componentWillReceiveProps(props) {
        if (props.view !== this.props.view) {
            this.updateThumbnail(props);
        }
    }
    updateThumbnail(props) {
        if (props.view === "grid" && props.icon !== "loading") {
            const mimetype = getMimeType(props.file.path);
            if (window.CONFIG.thumbnailer.indexOf(mimetype) !== -1) {
                Files.url(props.file.path).then((url) => {
                    this.setState({ preview: url+"&thumbnail=true" });
                });
            }
        }
    }
    onRename(newFilename) {
        if (typeof newFilename === "string") {
            this.props.emit(
                "file.rename",
                pathBuilder(this.props.path, this.props.file.name, this.props.file.type),
                pathBuilder(this.props.path, newFilename, this.props.file.type),
                this.props.file.type,
            );
        }
        this.setState({ is_renaming: false });
    }
    onRenameRequest(force) {
        let new_state = !this.state.is_renaming;
        if (typeof force === "boolean") {
            new_state = force;
        }
        this.setState({ is_renaming: new_state });
    }
    onDeleteRequest(filename) {
        prompt.now(
            t("Confirm by typing") +" \""+this._confirm_delete_text()+"\"",
            (answer) => { // click on ok
                if (answer === this._confirm_delete_text()) {
                    this.setState({ icon: "loading" });
                    this.props.emit(
                        "file.delete",
                        pathBuilder(this.props.path, this.props.file.name, this.props.file.type),
                        this.props.file.type,
                    );
                    return Promise.resolve();
                } else {
                    return Promise.reject(t("Doesn't match"));
                }
            },
            () => {/* click on cancel */},
        );
    }
    onDeleteConfirm(answer) {
        if (answer === this._confirm_delete_text()) {
            this.setState({ icon: "loading", delete_request: false });
            this.props.emit(
                "file.delete",
                pathBuilder(this.props.path, this.props.file.name, this.props.file.type),
                this.props.file.type,
            );
        } else {
            this.setState({ delete_error: t("Doesn't match") });
        }
    }
    onDeleteCancel() {
        this.setState({ delete_request: false });
    }
    onTagRequest() {
        alert.now(