import $ from 'jquery';
import Component from '@glimmer/component';
import {
    IMAGE_EXTENSIONS,
    IMAGE_MIME_TYPES
} from 'ghost-admin/components/gh-image-uploader';
import {action} from '@ember/object';
import {run} from '@ember/runloop';
import {tracked} from '@glimmer/tracking';

export default class KoenigCardBeforeAfterComponent extends Component {
    @tracked imageWidth;
    files = null;
    selectingFile = false;
    imageMimeTypes = IMAGE_MIME_TYPES;
    imageExtensions = IMAGE_EXTENSIONS;

    get isPopulated() {
        return this.args.payload.beforeImage && this.args.payload.afterImage;
    }

    get overlayStyle() {
        return `width: ${this.args.payload.startingPosition}%`;
    }

    get toolbar() {
        let cardWidth = this.args.payload.cardWidth;

        return {
            items: [{
                title: 'Wide',
                icon: 'koenig/kg-img-wide',
                iconClass: cardWidth === 'wide' ? 'fill-green-l2' : 'fill-white',
                action: run.bind(this, this.setLayoutWide)
            }, {
                title: 'Full',
                icon: 'koenig/kg-img-full',
                iconClass: cardWidth === 'full' ? 'fill-green-l2' : 'fill-white',
                action: run.bind(this, this.setLayoutFull)
            }, {
                divider: true
            }]
        };
    }

    updateImageDimensions() {
        let beforeImage = this.args.payload.beforeImage;
        let afterImage = this.args.payload.afterImage;

        let smallestImageWidth = Math.min(
            beforeImage ? beforeImage.width : Infinity,
            afterImage ? afterImage.width : Infinity
        );

        try {
            this.imageWidth = Math.min(
                smallestImageWidth,
                parseInt(getComputedStyle(this.element).getPropertyValue('width'))
            );
        } catch (err) {
            this.imageWidth = Math.min(
                smallestImageWidth,
                0
            );
        }
    }

    constructor(owner, args) {
        super(owner, args);
        args.registerComponent(this);

        let placeholders = ['summer', 'mountains', 'ufo-attack'];
        this.placeholder = placeholders[Math.floor(Math.random() * placeholders.length)];
        if (!args.payload.cardWidth) {
            args.payload.cardWidth = 'wide';
        }
        if (!args.payload.startingPosition) {
            args.payload.startingPosition = 50;
        }
        if (!args.payload.caption) {
            args.payload.caption = null;
        }
    }

    _triggerFileDialog(event) {
        let target = event && event.target || this.element;

        // simulate click to open file dialog
        // using jQuery because IE11 doesn't support MouseEvent
        $(target)
            .closest('.__mobiledoc-card')
            .find('input[type="file"]')
            .trigger('click');
    }

    setupListeners() {
        this.updateImageDimensions();
        const handleResize = () => {
            this.updateImageDimensions();
        };
        window.addEventListener('resize', handleResize);
        this.willDestroy = () => {
            window.removeEventListener('resize', handleResize);
        };
    }

    @action
    preventDefault(e) {
        e.preventDefault();
    }

    @action
    stopPropagation(e) {
        e.stopPropagation();
    }

    @action
    removeFocus(e) {
        e.target.blur();
    }

    // required for snippet rects to be calculated - editor reaches in to component,
    // expecting a non-Glimmer component with a .element property
    @action
    registerElement(element) {
        this.element = element;
        this.setupListeners();
    }

    @action
    uploadStart(file) {
        return new Promise((resolve) => {
            let objectURL = URL.createObjectURL(file);
            let image = new Image();
            image.addEventListener('load', () => {
                let id = this.selectingFile;
                this.selectingFile = false;
                let metadata = {
                    id: id
                };
                resolve(metadata);
            });
            image.src = objectURL;
        });
    }

    @action
    uploadSuccess(file, metadata) {
        let image = new Image();
        image.addEventListener('load', () => {
            let imageData = {
                src: file.url,
                width: image.naturalWidth,
                height: image.naturalHeight
            };
            let prop = `${metadata.id}Image`;
            this.args.payload[prop] = imageData;
            this.updateImageDimensions();
        });
        image.src = file.url;
    }

    @action
    setLayoutWide() {
        this.args.payload.cardWidth = 'wide';
        run.scheduleOnce('afterRender', this, this.updateImageDimensions);
    }

    @action
    setLayoutFull() {
        this.args.payload.cardWidth = 'full';
        run.scheduleOnce('afterRender', this, this.updateImageDimensions);
    }

    @action
    setStartingPosition(event) {
        this.args.payload.startingPosition = Math.min(100, Math.max(0, parseInt(event.target.value)));
    }

    @action
    selectBeforeImage() {
        this.selectingFile = 'before';
        this._triggerFileDialog();
    }

    @action
    selectAfterImage() {
        this.selectingFile = 'after';
        this._triggerFileDialog();
    }

    @action
    uploadFailed() {
    }

    @action
    handleErrors() {
    }

    @action
    setCaption(caption) {
        this.args.payload.caption = caption;
    }

    @action
    leaveEditMode() {
        if (this.isEmpty) {
            // afterRender is required to avoid double modification of `isSelected`
            // TODO: see if there's a way to avoid afterRender
            run.scheduleOnce('afterRender', this, this.args.deleteCard);
        }
    }
}
