/**
 * MobileEmojisTab — full-screen Fluxer-style mobile variant of
 * EmojisTab. Layout:
 *
 *   ┌────────── Upload Emoji ──────────┐  ← brand-primary CTA
 *   Add up to 50 custom emoji…           helper text
 *   UPLOAD REQUIREMENTS                   section label
 *   ┌─────── card ──────────────┐
 *   │ • File type: PNG, GIF, …  │
 *   │ • Recommended size: 256KB │
 *   │ • Recommended dimensions… │
 *   │ • Naming: 2+ chars, …     │
 *   └────────────────────────────┘
 *   EMOJI — N SLOTS AVAILABLE             section label
 *   ┌────────── card ────────────┐
 *   │ [img] :hazmat:           ⋯ │
 *   │ [img] :blank:            ⋯ │
 *   │ ...                       │
 *   └────────────────────────────┘
 *
 * The uploader column from the Fluxer reference is intentionally
 * dropped — MSC2545's `images` dict only stores `{shortcode → mxc}`
 * with no record of who added each entry, so there's nothing to
 * surface. Tapping the trash icon prompts a confirm and removes.
 *
 * The whole tab is gated behind `EmojiPackManager.canManageEmojis`
 * (native power-level check) — same gate as desktop. Non-admins
 * see a friendly fallback explaining how to get access.
 */
import { observer } from 'mobx-react-lite';
import { useMemo, useRef, useState } from 'react';
import { Trash, UploadSimple } from '@phosphor-icons/react';
import {
	EmojiPackManager,
	MAX_EMOJIS_PER_PACK,
	type CustomEmoji,
} from '@brycord/matrix-client';
import EmojiPackStore from '@app/stores/EmojiPackStore';
import { CustomEmojiImage } from '../channel/CustomEmojiImage';
import styles from './MobileEmojisTab.module.css';

interface MobileEmojisTabProps {
	serverId: string;
}

const SHORTCODE_REGEX = /^[a-z0-9_]{2,30}$/;
const MAX_FILE_BYTES = 256 * 1024;

export const MobileEmojisTab = observer(function MobileEmojisTab({
	serverId,
}: MobileEmojisTabProps) {
	const [pendingFile, setPendingFile] = useState<File | null>(null);
	const [pendingPreviewUrl, setPendingPreviewUrl] = useState<string | null>(
		null,
	);
	const [shortcode, setShortcode] = useState('');
	const [uploading, setUploading] = useState(false);
	const [deletingShortcode, setDeletingShortcode] = useState<string | null>(
		null,
	);
	const [status, setStatus] = useState<
		{ type: 'success' | 'error'; message: string } | null
	>(null);
	const fileInputRef = useRef<HTMLInputElement>(null);

	const canManage = useMemo(() => {
		try {
			return EmojiPackManager.getInstance().canManageEmojis(serverId);
		} catch {
			return false;
		}
	}, [serverId]);

	const pack = EmojiPackStore.getPack(serverId);
	const emojis: CustomEmoji[] = pack?.emojis ?? [];
	const slotsRemaining = MAX_EMOJIS_PER_PACK - emojis.length;
	const isFull = slotsRemaining <= 0;

	if (!canManage) {
		return (
			<div className={styles.gate}>
				<h2 className={styles.gateTitle}>Emojis</h2>
				<p className={styles.gateBody}>
					You need permission to manage emojis in this server. Ask an
					admin to grant you a role with a higher power level.
				</p>
			</div>
		);
	}

	const handleFilePick = (e: React.ChangeEvent<HTMLInputElement>) => {
		const file = e.target.files?.[0];
		// Reset input so the same file can be picked again after clearing.
		if (fileInputRef.current) fileInputRef.current.value = '';
		if (!file) return;
		setStatus(null);

		if (!file.type.startsWith('image/')) {
			setStatus({
				type: 'error',
				message: 'Emoji must be a PNG, GIF, WebP, or JPEG image.',
			});
			return;
		}
		if (file.size > MAX_FILE_BYTES) {
			setStatus({
				type: 'error',
				message: 'File is too large. Maximum is 256 KB.',
			});
			return;
		}

		if (pendingPreviewUrl) URL.revokeObjectURL(pendingPreviewUrl);
		setPendingFile(file);
		setPendingPreviewUrl(URL.createObjectURL(file));

		// Auto-suggest a shortcode from the filename, same heuristic
		// the desktop tab uses.
		if (!shortcode) {
			const base = file.name.replace(/\.[^.]+$/, '').toLowerCase();
			const cleaned = base.replace(/[^a-z0-9_]/g, '_').slice(0, 30);
			if (cleaned.length >= 2) setShortcode(cleaned);
		}
	};

	const handleUpload = async () => {
		if (!pendingFile || uploading) return;
		const trimmed = shortcode.trim();
		if (!SHORTCODE_REGEX.test(trimmed)) {
			setStatus({
				type: 'error',
				message:
					'Shortcode must be 2–30 chars (lowercase letters, digits, underscores).',
			});
			return;
		}
		if (emojis.some((e) => e.shortcode === trimmed)) {
			setStatus({
				type: 'error',
				message: `An emoji named "${trimmed}" already exists.`,
			});
			return;
		}

		setUploading(true);
		setStatus(null);
		try {
			await EmojiPackManager.getInstance().addEmoji(serverId, trimmed, pendingFile);
			if (pendingPreviewUrl) URL.revokeObjectURL(pendingPreviewUrl);
			setPendingFile(null);
			setPendingPreviewUrl(null);
			setShortcode('');
			setStatus({ type: 'success', message: `Added :${trimmed}:` });
		} catch (err: any) {
			setStatus({
				type: 'error',
				message: err?.message || 'Failed to upload emoji.',
			});
		} finally {
			setUploading(false);
		}
	};

	const handleClearPending = () => {
		if (pendingPreviewUrl) URL.revokeObjectURL(pendingPreviewUrl);
		setPendingFile(null);
		setPendingPreviewUrl(null);
		setShortcode('');
	};

	const handleDelete = async (emoji: CustomEmoji) => {
		if (deletingShortcode) return;
		if (!window.confirm(`Remove :${emoji.shortcode}: from this server?`)) return;
		setDeletingShortcode(emoji.shortcode);
		setStatus(null);
		try {
			await EmojiPackManager.getInstance().removeEmoji(serverId, emoji.shortcode);
			setStatus({ type: 'success', message: `Removed :${emoji.shortcode}:` });
		} catch (err: any) {
			setStatus({
				type: 'error',
				message: err?.message || 'Failed to remove emoji.',
			});
		} finally {
			setDeletingShortcode(null);
		}
	};

	return (
		<div className={styles.root}>
			<button
				type="button"
				className={styles.uploadButton}
				onClick={() => fileInputRef.current?.click()}
				disabled={isFull || uploading}
			>
				<UploadSimple size={18} weight="bold" />
				Upload Emoji
			</button>
			<input
				ref={fileInputRef}
				type="file"
				accept="image/png,image/gif,image/webp,image/jpeg"
				onChange={handleFilePick}
				style={{ display: 'none' }}
			/>

			<p className={styles.helperText}>
				Add up to {MAX_EMOJIS_PER_PACK} custom emoji that anyone can use
				in this server. Animated GIF and WebP emoji play automatically.
			</p>

			<div className={styles.sectionLabel}>Upload Requirements</div>
			<div className={styles.requirementsCard}>
				<ul className={styles.requirementsList}>
					<li>
						<strong>File type:</strong> PNG, GIF, WebP, JPEG
					</li>
					<li>
						<strong>Maximum file size:</strong> 256 KB
					</li>
					<li>
						<strong>Recommended dimensions:</strong> 128×128
					</li>
					<li>
						<strong>Naming:</strong> Emoji names must be at least 2
						characters long and can only contain lowercase letters,
						digits, and underscores.
					</li>
				</ul>
			</div>

			{/* Inline upload form — only visible after a file has been
			    picked. Lets the user name and confirm the upload, or
			    cancel out without leaving the tab. */}
			{pendingFile && (
				<div className={styles.uploadForm}>
					<div className={styles.uploadFormRow}>
						<div className={styles.uploadPreview}>
							{pendingPreviewUrl && (
								<img
									src={pendingPreviewUrl}
									alt="pending emoji"
									className={styles.uploadPreviewImage}
									draggable={false}
								/>
							)}
						</div>
						<input
							type="text"
							className={styles.shortcodeInput}
							placeholder="shortcode"
							value={shortcode}
							onChange={(e) =>
								setShortcode(
									e.target.value.toLowerCase().replace(/[^a-z0-9_]/g, ''),
								)
							}
							maxLength={30}
						/>
					</div>
					<div className={styles.uploadFormActions}>
						<button
							type="button"
							className={`${styles.formButton} ${styles.formButtonSecondary}`}
							onClick={handleClearPending}
							disabled={uploading}
						>
							Cancel
						</button>
						<button
							type="button"
							className={`${styles.formButton} ${styles.formButtonPrimary}`}
							onClick={handleUpload}
							disabled={uploading || !SHORTCODE_REGEX.test(shortcode)}
						>
							{uploading ? 'Uploading…' : 'Add Emoji'}
						</button>
					</div>
				</div>
			)}

			{status && (
				<div
					className={`${styles.status} ${
						status.type === 'error' ? styles.statusError : styles.statusSuccess
					}`}
				>
					{status.message}
				</div>
			)}

			<div className={styles.sectionLabel}>
				Emoji — {Math.max(0, slotsRemaining)} Slots Available
			</div>

			{emojis.length === 0 ? (
				<div className={styles.empty}>
					No custom emojis yet. Tap "Upload Emoji" to add one.
				</div>
			) : (
				<div className={styles.emojiCard}>
					{emojis.map((emoji) => (
						<div key={emoji.mxcUrl} className={styles.emojiRow}>
							<div className={styles.emojiThumb}>
								<CustomEmojiImage
									mxc={emoji.mxcUrl}
									alt={`:${emoji.shortcode}:`}
									title={`:${emoji.shortcode}:`}
									className={styles.emojiThumbImage}
									draggable={false}
								/>
							</div>
							<span className={styles.emojiName}>:{emoji.shortcode}:</span>
							<button
								type="button"
								className={styles.deleteButton}
								onClick={() => handleDelete(emoji)}
								disabled={deletingShortcode === emoji.shortcode}
								aria-label={`Remove :${emoji.shortcode}:`}
							>
								<Trash size={18} weight="fill" />
							</button>
						</div>
					))}
				</div>
			)}
		</div>
	);
});
