/* global rmlOpts */

import React from "react";
import { blocks, components, editor, element, i18n } from "wp";

const BLOCK_ID = "real-media-library/gallery";
const { registerBlockType } = blocks;
const {
    G,
    SVG,
    Path,
    ServerSideRender: ServerSideRenderWpLower6Dot2,
    PanelBody,
    RangeControl,
    ToggleControl,
    SelectControl,
    TreeSelect,
    Notice,
    Spinner,
    Button,
    withNotices,
} = components;
const { Component, Fragment } = element;
const { InspectorControls, ServerSideRender: ServerSideRenderWpGreaterEqual6Dot2 } = editor;
const { __ } = i18n;

const ServerSideRender = ServerSideRenderWpLower6Dot2 || ServerSideRenderWpGreaterEqual6Dot2;

const linkOptions = [
    { value: "attachment", label: __("Attachment Page") },
    { value: "media", label: __("Media File") },
    { value: "none", label: __("None") },
];

/**
 * Control to select a folder. You do not have to fill the items, it is
 * automatically filled and retrieved from the server.
 */
class SelectFolderControl extends Component {
    constructor() {
        super(...arguments);

        this.state = {
            $busy: true,
            tree: [],
        };
    }

    /**
     * Load the RML tree.
     */
    async componentDidMount() {
        const { tree } = await window.rml.request({
            location: {
                path: "/tree",
            },
        });
        tree.unshift({
            id: -1,
            name: rmlOpts.others.lang.unorganized,
        });
        tree.unshift({
            id: undefined,
            name: "-",
        });
        this.setState({ tree, $busy: false });
    }

    render() {
        const { ...rest } = this.props;
        const { $busy, tree } = this.state;
        return !$busy ? <TreeSelect label={rmlOpts.others.lang.folder} {...rest} tree={tree} /> : <Spinner />;
    }
}

/**
 * Gallery edit view with inspector controls like the normal gallery block.
 */
class GalleryEdit extends Component {
    constructor() {
        super(...arguments);

        this.state = {
            refresh: new Date().getTime(),
        };
    }

    setFid = (fid) => this.props.setAttributes({ fid: +fid });
    setLinkTo = (linkTo) => this.props.setAttributes({ linkTo });
    setColumnsNumber = (columns) => this.props.setAttributes({ columns });
    toggleImageCrop = () => this.props.setAttributes({ imageCrop: !this.props.attributes.imageCrop });
    toggleCaptions = () => this.props.setAttributes({ captions: !this.props.attributes.captions });
    handleReload = () => this.props.setAttributes({ lastEditReload: new Date().getTime() });

    render = () => {
        // Collect data
        const { attributes } = this.props;
        const { fid, columns = 3, imageCrop, captions, linkTo } = attributes;

        return (
            <Fragment>
                <InspectorControls>
                    <PanelBody title={__("Gallery Settings")}>
                        <SelectFolderControl value={fid} onChange={this.setFid} />
                        <RangeControl
                            label={__("Columns")}
                            value={columns}
                            onChange={this.setColumnsNumber}
                            min="1"
                            max="8"
                        />
                        <ToggleControl
                            label={__("Crop Images")}
                            checked={!!imageCrop}
                            onChange={this.toggleImageCrop}
                        />
                        <ToggleControl label={__("Caption")} checked={!!captions} onChange={this.toggleCaptions} />
                        <SelectControl
                            label={__("Link To")}
                            value={linkTo}
                            onChange={this.setLinkTo}
                            options={linkOptions}
                        />
                        <Button isPrimary onClick={this.handleReload}>
                            {rmlOpts.others.lang.reloadContent}
                        </Button>
                    </PanelBody>
                </InspectorControls>
                <ServerSideRender block={BLOCK_ID} attributes={attributes} />
                {!fid && (
                    <Notice status="error" isDismissible={false}>
                        <p>{rmlOpts.others.lang.gutenBergBlockSelect}</p>
                    </Notice>
                )}
            </Fragment>
        );
    };
}

/**
 * @see https://github.com/WordPress/gutenberg/blob/master/packages/block-library/src/gallery/index.js
 */
registerBlockType(BLOCK_ID, {
    title: "Real Media Library Gallery",
    description: "Display folder images in a rich gallery.",
    icon: (
        <SVG viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
            <Path fill="none" d="M0 0h24v24H0V0z" />
            <G>
                <Path d="M20 4v12H8V4h12m0-2H8L6 4v12l2 2h12l2-2V4l-2-2z" />
                <Path d="M12 12l1 2 3-3 3 4H9z" />
                <Path d="M2 6v14l2 2h14v-2H4V6H2z" />
            </G>
        </SVG>
    ),
    category: "common",
    supports: {
        align: true,
    },
    attributes: {
        fid: {
            type: "number",
            default: 0,
        },
        columns: {
            type: "number",
            default: 3,
        },
        imageCrop: {
            type: "boolean",
            default: true,
        },
        captions: {
            type: "boolean",
            default: true,
        },
        linkTo: {
            type: "string",
            default: "none",
        },
        lastEditReload: {
            type: "number",
            default: 0,
        },
    },
    edit: withNotices(GalleryEdit),
    save() {
        // Rendering in PHP, see general\Gutenberg
        return null;
    },
});
