/**
 * Bridge Generator Component
 *
 * Generates and displays AI bridge sentences.
 * SECURITY: Uses strict whitelist-based HTML sanitization (server-side wp_kses + client-side DOM parser).
 *
 * @package Purrlink
 */

import { __ } from '@wordpress/i18n';
import { useState } from '@wordpress/element';
import { Button, Spinner, TextareaControl, Icon } from '@wordpress/components';
import { pencil, update, check, caution, info, tip } from '@wordpress/icons';

/**
 * Allowed HTML tags for bridge sentences.
 * Strictly limited to formatting and links only.
 */
const ALLOWED_TAGS = ['a', 'strong', 'em', 'b', 'i'];
const ALLOWED_ATTRS = ['href', 'title', 'target', 'rel'];

/**
 * Sanitize HTML content using a strict whitelist approach.
 * Client-side defense-in-depth complement to server-side wp_kses() sanitization.
 *
 * @param {string} html Raw HTML string from API.
 * @return {string} Sanitized HTML string.
 */
export const sanitizeHTML = (html) => {
	if (!html || typeof html !== 'string') {
		return '';
	}

	// Create a temporary DOM element for parsing
	const doc = new DOMParser().parseFromString(html, 'text/html');
	const walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ELEMENT);

	const nodesToRemove = [];

	// Walk through all elements and check against whitelist
	while (walker.nextNode()) {
		const node = walker.currentNode;
		const tagName = node.tagName.toLowerCase();

		if (!ALLOWED_TAGS.includes(tagName)) {
			nodesToRemove.push(node);
			continue;
		}

		// Remove disallowed attributes
		const attrs = Array.from(node.attributes);
		for (const attr of attrs) {
			if (!ALLOWED_ATTRS.includes(attr.name.toLowerCase())) {
				node.removeAttribute(attr.name);
			}
		}

		// Validate href to prevent javascript: URLs
		if (tagName === 'a') {
			const href = node.getAttribute('href');
			if (href && (href.startsWith('javascript:') || href.startsWith('data:'))) {
				node.removeAttribute('href');
			}
		}
	}

	// Remove disallowed nodes
	for (const node of nodesToRemove) {
		node.replaceWith(document.createTextNode(node.textContent));
	}

	return doc.body.innerHTML;
};

/**
 * Bridge Generator component.
 *
 * @param {Object}   props                    Component props.
 * @param {string}   props.bridge             Generated bridge sentence HTML.
 * @param {boolean}  props.isLoading          Loading state.
 * @param {string}   props.error              Error message.
 * @param {string}   props.notRelatedWarning  Warning when content not related.
 * @param {Object}   props.selectedPost       Selected target post.
 * @param {boolean}  props.hasSelectedText    Whether text is selected.
 * @param {Function} props.onGenerate         Generate callback.
 * @param {Function} props.onRegenerate       Regenerate callback.
 * @param {Function} props.onInsert           Insert callback (receives insertMode).
 * @return {JSX.Element} Bridge generator component.
 */
// Minimum characters for good context
const MIN_CHARS_WARNING = 20;
const MIN_CHARS_RECOMMENDED = 50;

const BridgeGenerator = ({
	bridge,
	isLoading,
	error,
	notRelatedWarning,
	selectedPost,
	selectedText,
	onGenerate,
	onRegenerate,
	onForceGenerate,
	onInsert,
	onBridgeChange,
}) => {
	const textLength = selectedText?.length || 0;
	const hasSelectedText = textLength > 0;
	const isTooShort = textLength > 0 && textLength < MIN_CHARS_WARNING;
	const couldBeMore = textLength >= MIN_CHARS_WARNING && textLength < MIN_CHARS_RECOMMENDED;
	// Loading state
	if (isLoading) {
		return (
			<div className="purrlink-bridge__loading">
				<Spinner />
				<span>{__('Generating bridge sentence...', 'purrlink')}</span>
			</div>
		);
	}

	// Error state
	if (error) {
		return (
			<div className="purrlink-bridge__error">
				<p>{error}</p>
				<Button
					className="purrlink-button purrlink-button--secondary"
					onClick={onRegenerate}
				>
					{__('Retry', 'purrlink')}
				</Button>
			</div>
		);
	}

	// Not related warning state
	if (notRelatedWarning) {
		return (
			<div className="purrlink-bridge">
				<div className="purrlink-notice purrlink-notice--warning">
					<strong>{__('Content Not Related', 'purrlink')}</strong>
					<p>{notRelatedWarning}</p>
				</div>
				<div className="purrlink-bridge__target">
					<p>
						<strong>{__('Target:', 'purrlink')}</strong> {selectedPost?.title}
					</p>
				</div>
				<p className="purrlink-bridge__hint">
					{__('Try selecting a different target article that relates to your selected text.', 'purrlink')}
				</p>
				<Button
					className="purrlink-button purrlink-button--primary"
					onClick={onForceGenerate}
				>
					{__('Generate Anyway', 'purrlink')}
				</Button>
			</div>
		);
	}

	// No bridge yet - show generate button
	if (!bridge) {
		return (
			<div className="purrlink-bridge">
				{/* No text selected */}
				{!hasSelectedText && (
					<div className="purrlink-notice purrlink-notice--info">
						<div className="purrlink-notice__header">
							<Icon icon={info} size={18} />
							<strong>{__('Select text to get started', 'purrlink')}</strong>
						</div>
						<p>{__('Highlight 1-2 sentences in your post where you want to add the link.', 'purrlink')}</p>
					</div>
				)}

				{/* Text too short warning */}
				{isTooShort && (
					<div className="purrlink-notice purrlink-notice--warning">
						<div className="purrlink-notice__header">
							<Icon icon={caution} size={18} />
							<strong>{__('Text too short', 'purrlink')}</strong>
						</div>
						<p>{__('Select at least 1 sentence for better context. The AI needs enough text to create a natural bridge.', 'purrlink')}</p>
						<span className="purrlink-notice__count">
							{textLength} / {MIN_CHARS_WARNING} {__('characters', 'purrlink')}
						</span>
					</div>
				)}

				{/* Could select more tip */}
				{couldBeMore && (
					<div className="purrlink-notice purrlink-notice--tip">
						<div className="purrlink-notice__header">
							<Icon icon={tip} size={18} />
							<strong>{__('Tip', 'purrlink')}</strong>
						</div>
						<p>{__('Selecting more text gives better context for a more natural bridge sentence.', 'purrlink')}</p>
					</div>
				)}

				{/* Good selection indicator */}
				{textLength >= MIN_CHARS_RECOMMENDED && (
					<div className="purrlink-notice purrlink-notice--success">
						<div className="purrlink-notice__header">
							<Icon icon={check} size={18} />
							<strong>{__('Good selection!', 'purrlink')}</strong>
						</div>
						<p>{__('You have enough context for a great bridge sentence.', 'purrlink')}</p>
					</div>
				)}

				<div className="purrlink-bridge__target">
					<p>
						<strong>{__('Target:', 'purrlink')}</strong> {selectedPost?.title}
					</p>
				</div>

				<Button
					className="purrlink-button purrlink-button--primary"
					onClick={() => onGenerate(false)}
					disabled={!hasSelectedText || isTooShort}
				>
					{__('Generate Bridge Sentence', 'purrlink')}
				</Button>

				{isTooShort && (
					<p className="purrlink-bridge__hint">
						{__('Select more text to enable generation', 'purrlink')}
					</p>
				)}
			</div>
		);
	}

	// State for edit mode
	const [isEditing, setIsEditing] = useState(false);

	// Sanitize the bridge HTML before rendering
	const sanitizedBridge = sanitizeHTML(bridge);

	// Strip HTML for editing (plain text)
	const plainTextBridge = bridge.replace(/<[^>]*>/g, '');

	// Show bridge preview with insert options
	return (
		<div className="purrlink-bridge">
			{isEditing ? (
				<div className="purrlink-bridge__editor">
					<TextareaControl
						value={bridge}
						onChange={onBridgeChange}
						rows={4}
						className="purrlink-bridge__textarea"
						help={__('You can edit the HTML directly. Use <a href="URL"><strong>Title</strong></a> for links.', 'purrlink')}
					/>
					<Button
						className="purrlink-button purrlink-button--text"
						onClick={() => setIsEditing(false)}
					>
						{__('Done Editing', 'purrlink')}
					</Button>
				</div>
			) : (
				<div className="purrlink-bridge__preview-wrapper">
					<div
						className="purrlink-bridge__preview"
						// eslint-disable-next-line react/no-danger -- Sanitized with whitelist above
						dangerouslySetInnerHTML={{ __html: sanitizedBridge }}
					/>
					<Button
						className="purrlink-button purrlink-button--text purrlink-bridge__edit-btn"
						onClick={() => setIsEditing(true)}
					>
						<Icon icon={pencil} size={14} />
						{__('Edit', 'purrlink')}
					</Button>
				</div>
			)}

			<div className="purrlink-bridge__actions">
				<Button
					className="purrlink-button purrlink-button--primary"
					onClick={() => onInsert('after')}
				>
					{__('Insert as New Paragraph', 'purrlink')}
				</Button>
				<Button
					className="purrlink-button purrlink-button--secondary"
					onClick={() => onInsert('inline')}
				>
					{__('Append to Paragraph', 'purrlink')}
				</Button>
			</div>

			<Button
				className="purrlink-button purrlink-button--text"
				onClick={onRegenerate}
			>
				<Icon icon={update} size={16} />
				{__('Regenerate', 'purrlink')}
			</Button>
		</div>
	);
};

export default BridgeGenerator;
