/**
 * InviteMembersModal — the Matrix-native invite flow for a space.
 *
 * Fluxer's equivalent has shareable web invite links; since Brycord is a
 * Matrix client we show the Matrix primitives instead: the space's
 * canonical alias (or room ID fallback) as a copyable string people can
 * enter into their own client, plus a direct "Invite by Matrix ID" text
 * field that calls m.room.invite for a specific user.
 */
import { observer } from 'mobx-react-lite';
import { useEffect, useState } from 'react';
import { Copy, PaperPlaneTilt } from '@phosphor-icons/react';
import { Modal, Button } from '@brycord/ui';
import { MemberManager, MatrixClientManager } from '@brycord/matrix-client';
import ServerStore from '@app/stores/ServerStore';
import styles from './InviteMembersModal.module.css';

interface InviteMembersModalProps {
	isOpen: boolean;
	onClose: () => void;
	serverId: string;
}

// Quick sanity check for "@localpart:server.tld" — not exhaustive but
// enough to catch obvious typos before hitting the homeserver.
const MXID_REGEX = /^@[^:\s]+:[^:\s]+$/;

export const InviteMembersModal = observer(function InviteMembersModal({
	isOpen,
	onClose,
	serverId,
}: InviteMembersModalProps) {
	const server = ServerStore.getServer(serverId);
	const [mxid, setMxid] = useState('');
	const [inviting, setInviting] = useState(false);
	const [copied, setCopied] = useState(false);
	const [status, setStatus] = useState<{ type: 'success' | 'error'; message: string } | null>(null);

	// Resolve the room's canonical alias if the homeserver has one set;
	// otherwise fall back to the raw Matrix room ID. Both are valid
	// "addresses" that another Matrix user can paste into their client's
	// "Join a room" dialog to join the space.
	const [inviteAddress, setInviteAddress] = useState<string>(serverId);

	useEffect(() => {
		if (!isOpen) return;
		setStatus(null);
		setMxid('');
		setCopied(false);

		try {
			const client = MatrixClientManager.getInstance().getClient();
			const room = client.getRoom(serverId);
			const canonicalAlias = room?.getCanonicalAlias();
			setInviteAddress(canonicalAlias || serverId);
		} catch {
			setInviteAddress(serverId);
		}
	}, [isOpen, serverId]);

	const handleCopy = async () => {
		try {
			await navigator.clipboard.writeText(inviteAddress);
			setCopied(true);
			setTimeout(() => setCopied(false), 1500);
		} catch {
			// Silent fail — clipboard API can be blocked in some contexts.
		}
	};

	const handleInvite = async () => {
		const trimmed = mxid.trim();
		if (!MXID_REGEX.test(trimmed)) {
			setStatus({
				type: 'error',
				message: 'Enter a valid Matrix ID (e.g. @alice:matrix.org).',
			});
			return;
		}
		setInviting(true);
		setStatus(null);
		try {
			await MemberManager.getInstance().inviteMember(serverId, trimmed);
			setStatus({ type: 'success', message: `Invited ${trimmed}.` });
			setMxid('');
		} catch (err: any) {
			setStatus({
				type: 'error',
				message: err?.message || 'Failed to send invite.',
			});
		} finally {
			setInviting(false);
		}
	};

	return (
		<Modal.Root isOpen={isOpen} onClose={onClose} size="medium">
			<Modal.Header
				title={`Invite People to ${server?.name || 'Community'}`}
				onClose={onClose}
			/>
			<Modal.Content>
				<div className={styles.body}>
					<div className={styles.section}>
						<div className={styles.sectionLabel}>Invite by Matrix ID</div>
						<div className={styles.sectionDescription}>
							Send an invite directly to another Matrix user by their
							full address (e.g. <code>@alice:matrix.org</code>).
						</div>
						<div className={styles.inviteInputRow}>
							<input
								type="text"
								className={styles.inviteInput}
								placeholder="@alice:matrix.org"
								value={mxid}
								onChange={(e) => setMxid(e.target.value)}
								onKeyDown={(e) => {
									if (e.key === 'Enter') {
										e.preventDefault();
										handleInvite();
									}
								}}
								autoFocus
							/>
							<Button
								variant="primary"
								size="sm"
								loading={inviting}
								disabled={!mxid.trim()}
								icon={<PaperPlaneTilt size={16} />}
								onClick={handleInvite}
							>
								Send Invite
							</Button>
						</div>
						{status && (
							<p
								className={`${styles.status} ${
									status.type === 'success'
										? styles.statusSuccess
										: styles.statusError
								}`}
							>
								{status.message}
							</p>
						)}
					</div>

					<div className={styles.divider} />

					<div className={styles.section}>
						<div className={styles.sectionLabel}>
							Or share this community's address
						</div>
						<div className={styles.sectionDescription}>
							Anyone can join by entering this in their Matrix client's
							"Join a room" dialog (subject to the community's privacy
							settings).
						</div>
						<div className={styles.copyRow}>
							<input
								type="text"
								className={styles.copyInput}
								value={inviteAddress}
								readOnly
								onClick={(e) => e.currentTarget.select()}
							/>
							<Button
								variant="secondary"
								size="sm"
								icon={<Copy size={16} />}
								onClick={handleCopy}
							>
								{copied ? 'Copied!' : 'Copy'}
							</Button>
						</div>
					</div>
				</div>
			</Modal.Content>
			<Modal.Footer>
				<Button variant="primary" size="sm" onClick={onClose}>
					Done
				</Button>
			</Modal.Footer>
		</Modal.Root>
	);
});
