/**
 * JTZL_WebIRC_Chat - Main IRC Chat Component
 *
 * @package   JTZL_WebIRC_Chat
 * @copyright Copyright (c) 2025, JT. G.
 * @license   GPL-3.0+
 * @since     3.0.0
 */

import { useState, useEffect, useRef, useCallback } from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { ThemeToggle } from '../ui/theme-toggle';
import { EditableUsername } from '../ui/editable-username';
import { SidebarProvider, useSidebar } from '../ui/sidebar-provider';
import { useTheme } from '../providers/ThemeProvider';
import { AvatarUpload } from './AvatarUpload';
import { useAvatars } from '../../hooks/useAvatars';
import {
	ResponsiveProvider,
	useResponsive,
} from '../providers/ResponsiveProvider';
import { MessageList } from './MessageList';
import { MessageInput } from './MessageInput';
import type { MessageInputRef } from './MessageInput';
import { ChannelSidebar } from './ChannelSidebar';
import { ImageUpload } from './ImageUpload';
import { useMessageLog } from '../../hooks/useMessageLog';
import { useIRC } from '../../hooks/useIRC';
import { useAutoScroll } from '../../hooks/useAutoScroll';
import { getResponsiveWidthClasses } from '../../lib/responsive-utils';
import type { Config } from '../../types';

interface IRCChatProps {
	config: Config;
	className?: string;
}

/**
 * Main IRC Chat React component.
 * Integrates with existing WebSocket connection logic and IRC message handling.
 *
 * @since 3.0.0
 */
/**
 * Internal chat component that uses sidebar context.
 *
 * @since 3.0.0
 */
function IRCChatInternal({ config, className }: IRCChatProps) {
	const { open: sidebarOpen, toggleSidebar } = useSidebar();
	const { config: responsiveConfig } = useResponsive();

	// Input state
	const [inputValue, setInputValue] = useState('');

	// Message log hook
	const {
		messages,
		addMessage,
		addMessageWithId,
		updateMessage,
		formatTimestamp,
	} = useMessageLog();

	// IRC state management hook (now internally uses command and message processors)
	const { state: ircState, actions: ircActions } = useIRC(
		config,
		addMessage,
		addMessageWithId,
		updateMessage
	);

	// Refs
	const logRef = useRef<HTMLDivElement>(null);
	const messageInputRef = useRef<MessageInputRef>(null);
	const scrollContainerRef = useRef<HTMLDivElement>(null);

	// Auto-scroll hook for mobile devices
	const { actions: autoScrollActions } = useAutoScroll({
		enabled: true,
		threshold: 100,
		animationDuration: 300,
		respectReducedMotion: true,
		preserveInputFocus: true,
	});

	const { actualTheme } = useTheme();

	// Avatar management hook
	const {
		currentUserAvatar,
		getUserAvatar,
		updateCurrentUserAvatar,
		fetchUserAvatars,
	} = useAvatars();

	// Fetch avatars when users list changes.
	useEffect(() => {
		if (ircState.users.length > 0) {
			const usernames = ircState.users.map((user) => user.nick);
			fetchUserAvatars(usernames);
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [ircState.users]);

	// Set up scroll container reference when component mounts
	useEffect(() => {
		if (scrollContainerRef.current) {
			autoScrollActions.setScrollContainer(scrollContainerRef.current);
		}
	}, [autoScrollActions]);

	// Handle new messages with auto-scroll (mobile only)
	useEffect(() => {
		autoScrollActions.handleNewMessage();
	}, [messages, autoScrollActions]);

	/**
	 * Handle message submission for sending messages and commands.
	 *
	 * @since 3.0.0
	 */
	const handleMessageSubmit = useCallback(
		(message: string): void => {
			// Preserve input focus before sending message (mobile only)
			if (messageInputRef.current) {
				autoScrollActions.preserveFocus(messageInputRef);
			}

			ircActions.handleUserInput(message);
			setInputValue('');
		},
		[ircActions, autoScrollActions]
	);

	/**
	 * Handle successful image uploads.
	 * Creates a single message with all images in grid format.
	 *
	 * @since 3.1.0
	 */
	const handleImagesUploaded = useCallback(
		(imageUrls: string[], caption?: string): void => {
			if (imageUrls.length === 0) {
				return;
			}

			// Extract filenames from URLs to keep the IRC message short.
			const filenames = imageUrls.map((url) => {
				// Handle query string URLs (e.g., /?chat_webirc_image=filename.png).
				const urlObj = new URL(url, window.location.origin);
				const filenameFromQuery =
					urlObj.searchParams.get('chat_webirc_image') ||
					urlObj.searchParams.get('chat_webirc_avatar');

				if (filenameFromQuery) {
					return filenameFromQuery;
				}

				// Fallback to path-based extraction for other URL formats.
				return url.split('/').pop() || '';
			});

			// Create image message format: [IMG:filename1,filename2,filename3,filename4] optional caption
			// All images will be displayed together in a grid layout.
			let imageMessage = `[IMG:${filenames.join(',')}]`;
			if (caption) {
				imageMessage += ` ${caption}`;
			}

			// Send the image message through IRC.
			ircActions.handleUserInput(imageMessage);
		},
		[ircActions]
	);

	/**
	 * Handle image upload errors.
	 *
	 * @since 3.1.0
	 */
	const handleUploadError = useCallback(
		(error: string): void => {
			addMessage(`Image upload failed: ${error}`, 'error');
		},
		[addMessage]
	);

	/**
	 * Handle avatar change.
	 *
	 * @since 3.1.0
	 */
	const handleAvatarChange = useCallback(
		(avatarUrl: string): void => {
			updateCurrentUserAvatar(avatarUrl, ircState.currentNick);
			addMessage('Avatar updated successfully', 'notice');
		},
		[updateCurrentUserAvatar, addMessage, ircState.currentNick]
	);

	/**
	 * Handle avatar upload error.
	 *
	 * @since 3.1.0
	 */
	const handleAvatarUploadError = useCallback(
		(error: string): void => {
			addMessage(`Avatar upload failed: ${error}`, 'error');
		},
		[addMessage]
	);

	/**
	 * Handle connection button click - disconnect if connected, reconnect if disconnected.
	 *
	 * @since 3.0.0
	 */
	const handleConnectionToggle = useCallback((): void => {
		if (ircState.isConnected) {
			ircActions.disconnect();
		} else {
			ircActions.reconnect();
		}
	}, [ircState.isConnected, ircActions]);

	/**
	 * Handle channel selection from sidebar.
	 *
	 * @since 3.0.0
	 */
	const handleChannelSelect = useCallback(
		(channelName: string): void => {
			ircActions.selectChannel(channelName);
		},
		[ircActions]
	);

	/**
	 * Handle user selection for private messages.
	 * Pre-fills the message input with /msg command.
	 *
	 * @since 3.0.0
	 */
	const handleUserSelect = useCallback((username: string): void => {
		// Pre-fill the message input with /msg command
		setInputValue(`/msg ${username} `);

		// Focus the input so user can start typing immediately
		setTimeout(() => {
			messageInputRef.current?.focus();
		}, 0);
	}, []);

	/**
	 * Get button text based on connection status.
	 *
	 * @since 3.0.0
	 *
	 * @return string - Button text
	 */
	const getButtonText = (): string => {
		if (ircState.connectionStatus === 'connecting') {
			return 'Connecting...';
		}
		if (ircState.isConnected) {
			return 'Disconnect';
		}
		return 'Reconnect';
	};

	// Log initial debug information
	useEffect(() => {
		if (config.debugLogs) {
			addMessage(
				`[DEBUG] IRC Chat initialized with config: ${JSON.stringify({
					server: config.server,
					channel: config.channel,
					theme: actualTheme,
				})}`,
				'notice'
			);
		}
	}, [config, actualTheme, addMessage]);

	// Get responsive width classes based on configuration
	const responsiveWidthClasses = getResponsiveWidthClasses(responsiveConfig);

	return (
		<div
			className={`chat-webirc-container flex h-full ${responsiveWidthClasses} bg-background border-2 border-border rounded-xl overflow-hidden ${className || ''}`}
		>
			{/* Sidebar with proper v0 app styling */}
			<div
				className={`bg-sidebar border-r border-sidebar-border transition-all duration-300 rounded-l-xl ${
					sidebarOpen ? 'w-48' : 'w-0'
				}`}
			>
				<div
					className={`flex flex-col h-full ${!sidebarOpen && 'hidden'}`}
				>
					<ChannelSidebar
						channels={ircState.channels}
						users={ircState.users}
						currentChannel={ircState.currentChannel}
						isConnected={ircState.isConnected}
						connectionStatus={ircState.connectionStatus}
						onChannelSelect={handleChannelSelect}
						onUserSelect={handleUserSelect}
						serverAddress={config.server}
						className="h-full"
					/>
				</div>
			</div>

			<div className="flex-1 flex flex-col min-w-0 overflow-hidden rounded-r-xl">
				{/* Header matching v0 app structure */}
				<div className="bg-card border-b border-border p-3 h-[60px] flex items-center justify-between">
					<div className="flex items-center gap-2">
						<button
							onClick={toggleSidebar}
							className="inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 h-8 w-8 p-0 hover:bg-accent hover:text-accent-foreground"
							aria-label={
								sidebarOpen ? 'Hide sidebar' : 'Show sidebar'
							}
						>
							{sidebarOpen ? (
								<ChevronLeft className="h-4 w-4" />
							) : (
								<ChevronRight className="h-4 w-4" />
							)}
						</button>
						<span className="text-sm font-medium text-primary">
							Channel:
						</span>
						<h2 className="font-semibold text-card-foreground">
							{ircState.currentChannel}
						</h2>
					</div>
					<div className="flex items-center gap-2">
						{config.ui.allowThemeSwitch && <ThemeToggle />}
						<button
							className={`text-xs px-3 py-1.5 rounded text-sm font-medium transition-colors ${
								ircState.isConnected
									? 'border border-input bg-background hover:bg-accent hover:text-accent-foreground'
									: 'bg-primary text-primary-foreground hover:bg-primary/90'
							}`}
							type="button"
							onClick={handleConnectionToggle}
							disabled={
								ircState.connectionStatus === 'connecting'
							}
						>
							{getButtonText()}
						</button>
					</div>
				</div>

				{/* Message area with proper ScrollArea - flex-1 with min-h-0 ensures it takes available space without overflowing */}
				<div className="flex-1 min-h-0 overflow-hidden">
					<div className="h-full max-w-none md:max-w-[800px] md:mx-auto">
						<MessageList
							ref={logRef}
							scrollContainerRef={scrollContainerRef}
							messages={messages}
							formatTimestamp={formatTimestamp}
							currentNick={ircState.currentNick}
							getUserAvatar={getUserAvatar}
							className="h-full pl-1 pr-2 md:px-5 py-4"
						/>
					</div>
				</div>

				{/* Input area matching v0 app structure */}
				<div className="flex-shrink-0 border-t border-border p-3 min-w-0 space-y-2">
					<MessageInput
						ref={messageInputRef}
						value={inputValue}
						onChange={setInputValue}
						onSubmit={handleMessageSubmit}
						disabled={!ircState.isConnected}
						users={ircState.users}
						placeholder="Type a message or /help... (/ for commands, @ for users)"
						imageUploadButton={
							<ImageUpload
								onImagesUploaded={handleImagesUploaded}
								onUploadError={handleUploadError}
								disabled={!ircState.isConnected}
							/>
						}
					/>
					<div className="flex items-center gap-2 text-sm text-muted-foreground">
						{ircState.isConnected ? (
							<>
								<span>Connected as</span>
								<div className="flex items-center gap-2">
									<AvatarUpload
										currentAvatar={currentUserAvatar}
										onAvatarChange={handleAvatarChange}
										onUploadError={handleAvatarUploadError}
										size="sm"
										fallbackInitials={ircState.currentNick
											.slice(0, 2)
											.toUpperCase()}
									/>
									<EditableUsername
										currentNick={ircState.currentNick}
										onNickChange={ircActions.changeNick}
										isConnected={ircState.isConnected}
										userPersistence={config.userPersistence}
									/>
								</div>
							</>
						) : (
							<span>
								Disconnected - Connect to start chatting
							</span>
						)}
					</div>
				</div>
			</div>
		</div>
	);
}

/**
 * Main IRC Chat React component with sidebar and responsive providers.
 *
 * @since 3.0.0
 */
export function IRCChat({ config, className }: IRCChatProps) {
	const sidebarDefaultOpen = !config.ui.sidebarDefaultCollapsed;

	return (
		<ResponsiveProvider config={{ enabled: true }}>
			<SidebarProvider defaultOpen={sidebarDefaultOpen}>
				<IRCChatInternal config={config} className={className} />
			</SidebarProvider>
		</ResponsiveProvider>
	);
}
