import { Button, Text, Skeleton, Loader } from '@bsf/force-ui';
import { __, sprintf } from '@wordpress/i18n';
import { RefreshCw } from 'lucide-react';
import { useState, useRef, useEffect } from '@wordpress/element';
import EmptyState from '@GlobalComponents/empty-state';
import { cn } from '@Functions/utils';
import { getMaxLengthForField } from '@Global/constants';

const SAVE_TEXT = __( 'Save', 'surerank' );
const EDIT_TEXT = __( 'Edit', 'surerank' );
const USE_THIS_TEXT = __( 'Use This', 'surerank' );
const FIXING_TEXT = __( 'Fixing…', 'surerank' );
const GENERATE_TEXT = __( 'Generate', 'surerank' );
const RETRY_TEXT = __( 'Retry', 'surerank' );
const GENERATING_TEXT = __( 'Generating…', 'surerank' );
const SHOW_MORE_TEXT = __( 'Regenerate', 'surerank' );

// Header text mapping for different field types
const HEADER_TEXT_MAP = {
	home_page_title: __(
		'Here are generated home page titles. Review and apply the one you like.',
		'surerank'
	),
	home_page_description: __(
		'Here are generated home page descriptions. Review and apply the one you like.',
		'surerank'
	),
	home_page_social_title: __(
		'Here are generated social titles for your home page. Review and apply the one you like.',
		'surerank'
	),
	home_page_social_description: __(
		'Here are generated social descriptions for your home page. Review and apply the one you like.',
		'surerank'
	),
	page_title: __(
		'Here are generated page titles. Review and apply the one you like.',
		'surerank'
	),
	page_description: __(
		'Here are generated page descriptions. Review and apply the one you like.',
		'surerank'
	),
	social_title: __(
		'Here are generated social titles. Review and apply the one you like.',
		'surerank'
	),
	social_description: __(
		'Here are generated social descriptions. Review and apply the one you like.',
		'surerank'
	),
	site_tag_line: __(
		'Here are generated site taglines. Review and apply the one you like.',
		'surerank'
	),
};

// Default header text for SEO checks
const DEFAULT_HEADER_TEXT = __(
	"Here are the fixes generated by SureRank AI based on your request. Review and apply the ones you'd like to use.",
	'surerank'
);

// Separate component for individual generated content items
const GeneratedContentItem = ( {
	item,
	onUseThis,
	globalFixing,
	fieldType,
} ) => {
	const maxLength = getMaxLengthForField( fieldType );
	const [ isFixing, setIsFixing ] = useState( false );
	const [ editedText, setEditedText ] = useState( item.text );
	const [ isEditing, setIsEditing ] = useState( false );
	const textareaRef = useRef( null );

	const handleUseThis = async ( content ) => {
		if ( isFixing || globalFixing ) {
			return;
		}

		setIsFixing( true );
		try {
			if ( typeof onUseThis === 'function' ) {
				await onUseThis( content );
			}
		} catch ( error ) {
			// Silently handle errors to prevent UI breaks
		} finally {
			setIsFixing( false );
		}
	};

	const handleTextChange = ( e ) => {
		setEditedText( e.target.value );
	};

	const handleEditClick = () => {
		if ( isEditing ) {
			// Save - just toggle off editing mode
			setIsEditing( false );
			if ( textareaRef?.current ) {
				textareaRef.current.blur();
				// Reset scroll position to top
				textareaRef.current.scrollTop = 0;
			}
		} else {
			// Edit - enable editing mode
			setIsEditing( true );
			// Focus the textarea after state update
			setTimeout( () => {
				if ( textareaRef?.current ) {
					textareaRef.current.focus();
					const length = textareaRef.current.value.length;
					textareaRef.current.setSelectionRange( length, length );
				}
			}, 0 );
		}
	};

	// Auto-adjust textarea height on mount and when text changes
	useEffect( () => {
		if ( textareaRef?.current ) {
			const textarea = textareaRef.current;
			// Reset height to auto to get proper scrollHeight calculation
			textarea.style.height = 'auto';
			const scrollHeight = textarea.scrollHeight;
			// Set new height with max of 120px
			const newHeight = Math.min( scrollHeight, 120 );
			textarea.style.height = newHeight + 'px';
		}
	}, [ editedText ] );

	const charCount = editedText.length;
	const editButtonText = isEditing ? SAVE_TEXT : EDIT_TEXT;

	// Hide character count for site tagline
	const showCharCount = fieldType !== 'site_tag_line';

	const buttonText = isFixing ? FIXING_TEXT : USE_THIS_TEXT;

	return (
		<div className="flex flex-col self-stretch gap-1.5 p-2 bg-white rounded-md shadow-sm">
			{ /* Text Content */ }
			<div className="flex flex-row items-start gap-2">
				<textarea
					ref={ textareaRef }
					value={ editedText }
					onChange={ handleTextChange }
					rows={ 1 }
					readOnly={ ! isEditing }
					className={ cn(
						'flex-1 bg-transparent border-none outline-none resize-none',
						'text-sm font-medium text-text-secondary',
						'py-[2px] px-[4px] rounded',
						'overflow-y-auto',
						'transition-[height] duration-150',
						'min-h-[20px] leading-[1.4]',
						isEditing ? 'cursor-text' : 'cursor-default'
					) }
					disabled={ isFixing || globalFixing }
					onInput={ ( e ) => {
						e.target.style.height = '0px';
						const scrollHeight = e.target.scrollHeight;
						e.target.style.height =
							Math.min( scrollHeight, 120 ) + 'px';
					} }
				/>
			</div>

			{ /* Action Buttons */ }
			<div
				className={ cn(
					'flex flex-row items-center self-stretch gap-2 p-1',
					showCharCount ? 'justify-between' : 'justify-end'
				) }
			>
				{ /* Character Count - Left Side */ }
				{ showCharCount && (
					<Text
						size={ 12 }
						weight={ 400 }
						color="tertiary"
						className="whitespace-nowrap"
					>
						{ sprintf(
							/* translators: 1: current character count, 2: maximum character count */
							__( '%1$d/%2$d', 'surerank' ),
							charCount,
							maxLength
						) }
					</Text>
				) }

				{ /* Right Side Buttons */ }
				<div className="flex flex-row items-center gap-2">
					{ /* Edit/Save Button */ }
					<Button
						variant="link"
						size="xs"
						tag="button"
						onClick={ handleEditClick }
						disabled={ isFixing || globalFixing }
					>
						{ editButtonText }
					</Button>

					{ /* Use This Button */ }
					<Button
						variant="link"
						size="xs"
						tag="button"
						onClick={ () => handleUseThis( editedText ) }
						disabled={ isFixing || globalFixing }
						icon={ isFixing && <Loader size="sm" /> }
					>
						{ buttonText }
					</Button>
				</div>
			</div>
		</div>
	);
};

const GenerateContent = ( {
	onUseThis,
	onRegenerate,
	contents = [],
	generating = false,
	fixing = false,
	error = null,
	fieldType = null,
	headerText: customHeaderText = null,
} ) => {
	// Get header text based on field type, or use custom text, or default
	const headerText =
		customHeaderText || HEADER_TEXT_MAP[ fieldType ] || DEFAULT_HEADER_TEXT;

	const handleRegenerate = () => {
		if ( generating ) {
			return;
		}
		if ( typeof onRegenerate !== 'function' ) {
			return;
		}
		onRegenerate();
	};

	const hasAnyContent = contents && contents?.length > 0;
	const hasError = error !== null; // Error handling moved to parent component

	// Determine button text based on state
	const getButtonText = () => {
		if ( hasAnyContent ) {
			return SHOW_MORE_TEXT;
		}
		if ( generating ) {
			return GENERATING_TEXT;
		}
		if ( ! hasAnyContent && hasError ) {
			return RETRY_TEXT;
		}
		return GENERATE_TEXT;
	};

	// Determine empty state message
	const getEmptyStateMessage = () => {
		if ( ! hasAnyContent ) {
			return sprintf(
				/* translators: %s: "Retry" button text */
				__(
					'No content generated. Click %s to retry creating AI-powered content suggestions.',
					'surerank'
				),
				`"${ getButtonText() }"`
			);
		}
		return __(
			'No content generated yet. Click "Generate" to create AI-powered content suggestions.',
			'surerank'
		);
	};

	// Determine main content to render
	let mainContent;

	if ( generating ) {
		// Loading skeleton for content items
		const skeletonItems = Array.from( { length: 5 } ).map( ( _, index ) => (
			<div
				key={ index }
				className="flex flex-row self-stretch gap-1 p-2 bg-white rounded-md shadow-sm"
			>
				{ /* Text Content Skeleton */ }
				<div className="flex flex-row items-center gap-1 p-1 flex-1">
					<div className="flex flex-row justify-stretch items-stretch gap-2 flex-1">
						<div className="flex-1 space-y-2">
							<Skeleton
								variant="rectangular"
								className="w-full h-4"
							/>
							<Skeleton
								variant="rectangular"
								className="w-3/4 h-4"
							/>
						</div>
					</div>
				</div>

				{ /* Button Skeleton */ }
				<div className="flex flex-row items-center gap-2">
					<Skeleton
						variant="rectangular"
						className="w-16 h-8 rounded"
					/>
				</div>
			</div>
		) );

		mainContent = skeletonItems;
	} else if ( hasAnyContent ) {
		// Generated content items using the separate component
		const contentItems = contents.map( ( item ) => (
			<GeneratedContentItem
				key={ item.id }
				item={ item }
				onUseThis={ onUseThis }
				globalFixing={ fixing }
				fieldType={ fieldType }
			/>
		) );

		mainContent = contentItems;
	} else {
		// Empty state
		mainContent = (
			<div className="flex flex-col self-stretch gap-2">
				<EmptyState
					message={ getEmptyStateMessage() }
					className="m-2 text-center"
				/>
			</div>
		);
	}

	return (
		<div className="flex flex-col self-stretch gap-3">
			{ /* Header Text */ }
			<Text
				size={ 14 }
				weight={ 400 }
				color="primary"
				className="self-stretch"
			>
				{ headerText }
			</Text>

			{ /* Content Wrapper */ }
			<div className="flex flex-col items-end self-stretch gap-2 p-2 bg-background-secondary rounded-lg">
				{ /* Main Content Area */ }
				{ mainContent }

				{ /* Single Action Button */ }
				<div className="flex flex-row items-center gap-2 p-1">
					<Button
						variant="ghost"
						size="xs"
						onClick={ handleRegenerate }
						disabled={ generating }
						icon={
							<RefreshCw
								className={ cn(
									'w-4 h-4',
									generating && 'animate-spin'
								) }
							/>
						}
						iconPosition="left"
						className="px-1"
					>
						{ getButtonText() }
					</Button>
				</div>
			</div>
		</div>
	);
};

export default GenerateContent;
