import styled from "styled-components";

import { useContext, useEffect, useState } from "preact/hooks";

import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";

import {
	IntermediateContext,
	useIntermediate,
} from "../../../context/intermediate/Intermediate";
import { AppContext } from "../../../context/revoltjs/RevoltClient";
import { MessageObject } from "../../../context/revoltjs/util";

import AutoComplete, {
	useAutoComplete,
} from "../../../components/common/AutoComplete";

const EditorBase = styled.div`
	display: flex;
	flex-direction: column;

	textarea {
		resize: none;
		padding: 12px;
		font-size: 0.875rem;
		border-radius: 3px;
		white-space: pre-wrap;
		background: var(--secondary-header);
	}

	.caption {
		padding: 2px;
		font-size: 11px;
		color: var(--tertiary-foreground);

		a {
			cursor: pointer;
			&:hover {
				text-decoration: underline;
			}
		}
	}
`;

interface Props {
	message: MessageObject;
	finish: () => void;
}

export default function MessageEditor({ message, finish }: Props) {
	const [content, setContent] = useState((message.content as string) ?? "");
	const { focusTaken } = useContext(IntermediateContext);
	const { openScreen } = useIntermediate();
	const client = useContext(AppContext);

	async function save() {
		finish();

		if (content.length === 0) {
			openScreen({
				id: "special_prompt",
				// @ts-expect-error
				type: "delete_message",
				// @ts-expect-error
				target: message,
			});
		} else if (content !== message.content) {
			await client.channels.editMessage(message.channel, message._id, {
				content,
			});
		}
	}

	// ? Stop editing when pressing ESC.
	useEffect(() => {
		function keyUp(e: KeyboardEvent) {
			if (e.key === "Escape" && !focusTaken) {
				finish();
			}
		}

		document.body.addEventListener("keyup", keyUp);
		return () => document.body.removeEventListener("keyup", keyUp);
	}, [focusTaken]);

	const {
		onChange,
		onKeyUp,
		onKeyDown,
		onFocus,
		onBlur,
		...autoCompleteProps
	} = useAutoComplete((v) => setContent(v ?? ""), {
		users: { type: "all" },
	});

	return (
		<EditorBase>
			<AutoComplete detached {...autoCompleteProps} />
			<TextAreaAutoSize
				forceFocus
				maxRows={3}
				padding={12}
				value={content}
				maxLength={2000}
				onChange={(ev) => {
					onChange(ev);
					setContent(ev.currentTarget.value);
				}}
				onKeyDown={(e) => {
					if (onKeyDown(e)) return;

					if (
						!e.shiftKey &&
						e.key === "Enter" &&
						!isTouchscreenDevice
					) {
						e.preventDefault();
						save();
					}
				}}
				onKeyUp={onKeyUp}
				onFocus={onFocus}
				onBlur={onBlur}
			/>
			<span className="caption">
				escape to <a onClick={finish}>cancel</a> &middot; enter to{" "}
				<a onClick={save}>save</a>
			</span>
		</EditorBase>
	);
}
