/**
 * BLOCK: unicard
 *
 * Registering a customizable block.
 */

//  Import CSS.
import "./editor.scss";
import "./style.scss";

// Import Icons.
import icons from "./icons/icons.js";

const { __ } = wp.i18n; // Import __() from wp.i18n
const { registerBlockType } = wp.blocks;
const {
	RichText,
	BlockControls,
	AlignmentToolbar,
	InspectorControls,
	ColorPalette,
	MediaUpload,
	MediaUploadCheck
} = wp.blockEditor;
const { Fragment } = wp.element;
const { Panel, PanelBody, PanelRow, Button, RadioControl } = wp.components;

const ALLOWED_MEDIA_TYPES = ["image"];

/**
 * Register: UniCard Block.
 *
 * Registers a new block provided a unique name and an object defining its
 * behavior. Once registered, the block is made editor as an option to any
 * editor interface where blocks are implemented.
 *
 * @link https://wordpress.org/gutenberg/handbook/block-api/
 * @param  {string}   name     Block name.
 * @param  {Object}   settings Block settings.
 * @return {?WPBlock}          The block, if it has been successfully
 *                             registered; otherwise `undefined`.
 */
registerBlockType("unicard/block-unicard", {
	title: __("UniCard", "unicard"),
	icon: { background: "#11acee", src: icons.unicard },
	category: "common",
	keywords: [__("unicard", "unicard"), __("custom card block", "unicard")],
	supports: {
		align: ["full", "wide"],
		anchor: true
	},
	attributes: {
		title: {
			type: "array",
			source: "children",
			selector: "h3"
		},
		content: {
			type: "array",
			source: "children",
			selector: "p"
		},
		contentStyle: {
			type: "object",
			default: {
				color: "black",
				textAlign: "left"
			}
		},
		backgroundStyle: {
			type: "object",
			default: {
				backgroundColor: "transparent"
			}
		},
		imageAlt: {
			attribute: "alt",
			selector: ".featured-image"
		},
		imageUrl: {
			attribute: "src",
			selector: ".featured-image"
		},
		imageId: {
			type: "number"
		},
		displayValue: {
			type: "string",
			default: "column"
		}
	},

	/**
	 * The edit function describes the structure of your block in the context of the editor.
	 * This represents what the editor will render when the block is used.
	 *
	 * The "edit" property must be a valid function.
	 *
	 * @link https://wordpress.org/gutenberg/handbook/block-api/block-edit-save/
	 *
	 * @param {Object} props Props.
	 * @returns {Mixed} JSX Component.
	 */
	edit: props => {
		let {
			attributes: {
				title,
				content,
				contentStyle,
				backgroundStyle,
				imageUrl,
				imageId,
				displayValue
			},
			setAttributes,
			className
		} = props;

		const onSelectImage = openEvent => {
			if (imageUrl) {
				return <img src={imageUrl} onClick={openEvent} className="image" />;
			} else {
				return (
					<div className="button-container">
						<Button
							className={
								!imageId
									? "editor-post-featured-image__toggle"
									: "editor-post-featured-image__preview"
							}
							onClick={openEvent}
						>
							{!imageId && __("Set featured image", "unicard")}
						</Button>
					</div>
				);
			}
		};

		const onRemoveImage = () => {
			setAttributes({
				imageUrl: null
			});
		};

		const onChangeTitle = newTitle => {
			setAttributes({
				title: newTitle
			});
		};

		const onChangeContent = newContent => {
			setAttributes({
				content: newContent
			});
		};

		const onChangeAlignment = newAlignment => {
			let alignmentValue = newAlignment === undefined ? "none" : newAlignment;
			setAttributes({
				contentStyle: {
					color: contentStyle.color,
					textAlign: alignmentValue
				}
			});
		};

		const onChangeTextColor = newColor => {
			let newColorValue = newColor === undefined ? "none" : newColor;
			setAttributes({
				contentStyle: {
					color: newColorValue,
					textAlign: contentStyle.textAlign
				}
			});
		};

		const onChangeBackgroundColor = newBgcolor => {
			let newBgcolorValue = newBgcolor === undefined ? "none" : newBgcolor;
			setAttributes({
				backgroundStyle: {
					backgroundColor: newBgcolorValue
				}
			});
		};

		const onChangeDisplay = newDisplay => {
			setAttributes({
				displayValue: newDisplay
			});
		};

		return [
			<BlockControls>
				<AlignmentToolbar
					value={contentStyle.textAlign}
					onChange={onChangeAlignment}
				/>
			</BlockControls>,

			<Fragment>
				<InspectorControls>
					<Panel className={className}>
						<PanelBody
							title={__("Color Settings", "unicard")}
							initialOpen={true}
						>
							<PanelRow>{__("Choose a text color.", "unicard")}</PanelRow>
							<ColorPalette
								value={contentStyle.color}
								onChange={onChangeTextColor}
							/>
							<PanelRow>{__("Choose a background color.", "unicard")}</PanelRow>
							<ColorPalette
								value={backgroundStyle.backgroundColor}
								onChange={onChangeBackgroundColor}
							/>
						</PanelBody>
						<PanelBody
							title={__("Display Settings", "unicard")}
							initialOpen={false}
						>
							<RadioControl
								label={__("Choose Card Layout", "unicard")}
								selected={displayValue}
								options={[
									{ label: "Column", value: "column" },
									{ label: "Column Reverse", value: "column-reverse" },
									{ label: "Row", value: "row" },
									{ label: "Row Reverse", value: "row-reverse" }
								]}
								onChange={onChangeDisplay}
							/>
						</PanelBody>
					</Panel>
				</InspectorControls>
			</Fragment>,

			<div className="unicard-title">
				<h2>{__("UniCard Block", "unicard")}</h2>
			</div>,
			<div
				className={[className, displayValue].join(" ")}
				style={backgroundStyle}
			>
				<div className="card-image">
					<MediaUploadCheck>
						<MediaUpload
							onSelect={media => {
								setAttributes({ imageAlt: media.alt, imageUrl: media.url });
							}}
							allowedTypes={ALLOWED_MEDIA_TYPES}
							type="image"
							value={imageId}
							render={({ open }) => onSelectImage(open)}
						/>
					</MediaUploadCheck>
					{!!imageUrl && (
						<MediaUploadCheck>
							<div className="button-container">
								<Button
									className="button"
									onClick={onRemoveImage}
									isLink
									isDestructive
								>
									{__("Remove", "unicard")}
								</Button>
							</div>
						</MediaUploadCheck>
					)}
				</div>
				<div className="card-content">
					<div className="card-title">
						<RichText
							className="heading"
							tagName="h3"
							style={contentStyle}
							onChange={onChangeTitle}
							placeholder={__("Your card title", "unicard")}
							keepPlaceholderOnFocus={true}
							value={title}
						/>
					</div>
					<div className="card-description">
						<RichText
							tagName="p"
							style={contentStyle}
							onChange={onChangeContent}
							placeholder={__("Your card content", "unicard")}
							keepPlaceholderOnFocus={true}
							value={content}
						/>
					</div>
				</div>
			</div>
		];
	},
	save: props => {
		const background = props.attributes.backgroundStyle;
		const display = props.attributes.displayValue;
		const layout = props.option;
		const style = props.attributes.contentStyle;
		const title = props.attributes.title;
		const content = props.attributes.content;
		const url = props.attributes.imageUrl;
		const alt = props.attributes.imageAlt;

		const cardImage = (imgSrc, imgAlt) => {
			if (!imgSrc) return null;

			if (imgAlt) {
				return (
					<div className="card-image">
						<img className="featured-image" src={imgSrc} alt={imgAlt} />
					</div>
				);
			}

			// No alt set, so let's hide it from screen readers
			return (
				<div className="card-image">
					<img
						className="featured-image"
						src={imgSrc}
						alt=""
						aria-hidden="true"
					/>
				</div>
			);
		};

		const cardTitle = () => {
			if (!title) return null;

			if (title) {
				return (
					<div className="card-title">
						<RichText.Content style={style} tagName="h3" value={title} />
					</div>
				);
			}
		};

		const cardContent = () => {
			if (!content) return null;

			if (content) {
				return (
					<div className="card-description">
						<RichText.Content style={style} tagName="p" value={content} />
					</div>
				);
			}
		};

		return (
			<div className={["card", display].join(" ")} style={background}>
				{cardImage(url, alt)}

				<div className="card-content" style={layout}>
					{title.length > 0 && cardTitle()}
					{content.length > 0 && cardContent()}
				</div>
			</div>
		);
	}
});
