/**
 * Use this file for JavaScript code that you want to run in the front-end
 * on posts/pages that contain this block.
 *
 * When this file is defined as the value of the `viewScript` property
 * in `block.json` it will be enqueued on the front end of the site.
 *
 * Example:
 *
 * ```js
 * {
 *   "viewScript": "file:./view.js"
 * }
 * ```
 *
 * If you're not making any changes to this file because your project doesn't need any
 * JavaScript running in the front-end, then you should delete this file and remove
 * the `viewScript` property from `block.json`.
 *
 * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/#view-script
 */

import { animate } from "https://cdn.jsdelivr.net/npm/motion@11.18.2/+esm";

const DocumentationModule = {
	config: {
		selectors: {
			block: '.wp-block-documentation',
			toggleButton: '.documentation-nav-toggle',
			mobileNav: '.documentation-nav-mobile',
			tocLinks: '.toc-content a',
			sections: '.documentation-content h1, .documentation-content h2, .documentation-content h3, .documentation-content h4, .documentation-content h5, .documentation-content h6',
			contentArea: '.documentation-content',
			tocContent: '.toc-content',
			mobileNavLinks: '.nav-item',
			nav: '.documentation-nav',
			navMobile: '.documentation-nav-mobile',
			navToggle: '.documentation-nav-toggle',
			navSection: '.nav-section',
			sectionHeader: '.section-header',
			sectionContent: '.section-content',
			navItem: '.nav-item',
			content: '.documentation-content',
			chevronIcon: '.chevron-icon',
			navItems: '.nav-item'
		},
		scroll: {
			offset: 60, // Reduced offset for better visibility
			behavior: 'smooth', // Default scroll behavior
			block: 'start'     // Align to the top of the container
		},
		animation: {
			duration: 0.3,
			ease: [0.4, 0, 0.2, 1]
		}
	},

	state: {
		blocks: []
	},

	init() {
		// Wait for DOM to be fully loaded
		setTimeout(() => {
			const blocks = document.querySelectorAll(this.config.selectors.block);
			if (!blocks.length) return;
			this.setupNav();

			blocks.forEach(block => {
				this.initializeBlock(block);
				this.setupAccordion(block);
			});
		}, 100);
	},

	initializeBlock(block) {
		const elements = this.getBlockElements(block);
		if (!elements) return;
		this.setupMobileNavigation(block, elements);
		this.setupSectionIds(elements.sections);
		this.setupTocLinks(block, elements);
		
		// Set up scroll event listeners
		window.addEventListener('scroll', () => this.updateActiveSectionOnScroll(block, elements));
		
		if (elements.contentArea) {
			elements.contentArea.addEventListener('scroll', () => this.updateActiveSectionOnScroll(block, elements));
		}
	},

	getBlockElements(block) {
		const elements = {
			toggleButton: block.querySelector(this.config.selectors.toggleButton),
			mobileNav: block.querySelector(this.config.selectors.mobileNav),
			tocLinks: block.querySelectorAll(this.config.selectors.tocLinks),
			sections: block.querySelectorAll(this.config.selectors.sections),
			contentArea: block.querySelector(this.config.selectors.contentArea),
			tocContent: block.querySelector(this.config.selectors.tocContent)
		};

		// Check if critical elements exist
		if (!elements.contentArea || !elements.sections.length) {
			return null;
		}

		return elements;
	},

	setupMobileNavigation(block, elements) {
		const { toggleButton, mobileNav } = elements;
		if (!toggleButton || !mobileNav) return;

		toggleButton.addEventListener('click', () => {
			toggleButton.classList.toggle('active');
			mobileNav.classList.toggle('active');
		});

		const mobileNavLinks = mobileNav.querySelectorAll(this.config.selectors.mobileNavLinks);
		mobileNavLinks.forEach(link => {
			link.addEventListener('click', () => {
				toggleButton.classList.remove('active');
				mobileNav.classList.remove('active');
			});
		});

		document.addEventListener('click', (e) => {
			if (!mobileNav.contains(e.target) && !toggleButton.contains(e.target)) {
				toggleButton.classList.remove('active');
				mobileNav.classList.remove('active');
			}
		});
	},

	setupSectionIds(sections) {
		if (!sections) return;
		sections.forEach(section => {
			if (!section.id) {
				section.id = this.generateSectionId(section.textContent);
			}
			
			// Add scroll-margin-top to improve visibility when scrolled to
			section.style.scrollMarginTop = `${this.config.scroll.offset}px`;
		});
	},

	generateSectionId(text) {
		return text.toLowerCase().trim()
			.replace(/\s+/g, '-')
			.replace(/[^\w-]/g, '')
			.replace(/-+$/, '');
	},

	setupTocLinks(block, elements) {
		const { tocLinks } = elements;
		if (!tocLinks || tocLinks.length === 0) return;

		tocLinks.forEach(link => {
			link.addEventListener('click', (e) => {
				e.preventDefault();
				const targetId = link.getAttribute('href').substring(1);
				const targetSection = document.getElementById(targetId);
				
				if (targetSection) {
					// Scroll to the target section
					this.scrollToElement(targetSection);
					
					// Update active link in the TOC
					this.updateActiveTocLink(link, elements.tocLinks);
				}
			});
		});
	},

	scrollToElement(element) {
		if (!element) return;
		
		// Simple and reliable approach using scrollIntoView
		element.scrollIntoView({
			behavior: this.config.scroll.behavior,
			block: this.config.scroll.block
		});
		
		// Focus the element for accessibility
		element.setAttribute('tabindex', '-1');
		element.focus({ preventScroll: true });
	},

	updateActiveTocLink(activeLink, allLinks) {
		if (!allLinks) return;
		
		// Remove active class from all links
		Array.from(allLinks).forEach(link => {
			link.classList.remove('active');
		});
		
		// Add active class to the current link
		if (activeLink) {
			activeLink.classList.add('active');
		}
	},

	updateActiveSectionOnScroll(block, elements) {
		const { sections, tocLinks } = elements;
		if (!sections || !tocLinks) return;
		
		let activeSection = null;
		const viewportMiddle = window.innerHeight / 2;
		
		// Find the section closest to the middle of the viewport
		for (let i = 0; i < sections.length; i++) {
			const section = sections[i];
			const rect = section.getBoundingClientRect();
			
			// If the section is in the viewport
			if (rect.top < viewportMiddle && rect.bottom > 0) {
				activeSection = section;
				break;
			}
			
			// If we've gone past the viewport middle, use the previous section
			if (rect.top > viewportMiddle && i > 0) {
				activeSection = sections[i - 1];
				break;
			}
		}
		
		// If no section was found but there are sections, use the last one
		if (!activeSection && sections.length > 0) {
			activeSection = sections[sections.length - 1];
		}
		
		// Update the active TOC link
		if (activeSection) {
			const activeLink = Array.from(tocLinks).find(
				link => link.getAttribute('href') === `#${activeSection.id}`
			);
			
			if (activeLink) {
				this.updateActiveTocLink(activeLink, tocLinks);
				this.scrollActiveLinkIntoView(activeLink, elements.tocContent);
			}
		}
	},

	scrollActiveLinkIntoView(activeLink, tocContent) {
		if (!activeLink || !tocContent) return;
		
		const linkRect = activeLink.getBoundingClientRect();
		const containerRect = tocContent.getBoundingClientRect();
		
		// If the link is outside the visible area of the TOC content
		if (linkRect.bottom > containerRect.bottom || linkRect.top < containerRect.top) {
			activeLink.scrollIntoView({
				behavior: 'smooth',
				block: 'nearest'
			});
		}
	},

	setupNav() {
		const documentationSections = document.querySelector('.documentation-sections');
		if (!documentationSections) return;
		
		const sections = documentationSections.querySelectorAll('.nav-section');
		if (!sections.length) return;
		
		sections.forEach(section => {
			const header = section.querySelector(this.config.selectors.sectionHeader);
			const content = section.querySelector(this.config.selectors.sectionContent);
			if (!header || !content) return;
			
			const nav = content.querySelector('nav');
			if (!nav) return;
			
			// Initial state
			content.style.height = '0px';
			nav.style.opacity = '0';
			nav.style.transform = 'translateY(-10px)';
			
			header.addEventListener('click', async () => {
				const isOpen = section.classList.contains('open');
				
				// Close other sections
				sections.forEach(otherSection => {
					if (otherSection !== section && otherSection.classList.contains('open')) {
						const otherContent = otherSection.querySelector(this.config.selectors.sectionContent);
						const otherNav = otherContent?.querySelector('nav');
						
						if (!otherContent || !otherNav) return;
						
						otherSection.classList.remove('open');
						
						animate(otherContent, { height: 0 }, {
							duration: this.config.animation.duration,
							ease: this.config.animation.ease
						});
						
						animate(otherNav, {
							opacity: 0,
							transform: 'translateY(-10px)'
						}, {
							duration: this.config.animation.duration,
							ease: this.config.animation.ease
						});
					}
				});
				
				// Toggle current section
				if (!isOpen) {
					section.classList.add('open');
					
					// Get natural height
					content.style.height = 'auto';
					const height = content.offsetHeight;
					content.style.height = '0px';
					
					// Animate opening
					await animate(content, { height }, {
						duration: this.config.animation.duration,
						ease: this.config.animation.ease
					});
					
					animate(nav, {
						opacity: 1,
						transform: 'translateY(0)'
					}, {
						duration: this.config.animation.duration,
						ease: this.config.animation.ease
					});
					
					content.style.height = 'auto';
				} else {
					section.classList.remove('open');
					
					await animate(content, { height: 0 }, {
						duration: this.config.animation.duration,
						ease: this.config.animation.ease
					});
					
					animate(nav, {
						opacity: 0,
						transform: 'translateY(-10px)'
					}, {
						duration: this.config.animation.duration,
						ease: this.config.animation.ease
					});
				}
			});
		});
	},

	setupAccordion(block) {
		const sections = block.querySelectorAll(this.config.selectors.navSection);
		if (!sections.length) return;

		sections.forEach(section => {
			const header = section.querySelector(this.config.selectors.sectionHeader);
			const content = section.querySelector(this.config.selectors.sectionContent);
			const chevron = header?.querySelector(this.config.selectors.chevronIcon);
			const nav = content?.querySelector(this.config.selectors.nav);
			
			if (!header || !content || !nav) return;

			// État initial
			content.style.height = '0px';
			nav.style.opacity = '0';
			nav.style.transform = 'translateY(-10px)';

			header.addEventListener('click', async () => {
				const isOpen = section.classList.contains('open');

				// Ferme les autres sections
				sections.forEach(otherSection => {
					if (otherSection !== section && otherSection.classList.contains('open')) {
						const otherContent = otherSection.querySelector(this.config.selectors.sectionContent);
						const otherNav = otherContent?.querySelector(this.config.selectors.nav);
						const otherChevron = otherSection.querySelector(this.config.selectors.chevronIcon);
						
						otherSection.classList.remove('open');
						
						if (otherContent && otherNav) {
							animate(otherContent, { height: 0 }, {
								duration: this.config.animation.duration,
								ease: this.config.animation.ease
							});

							animate(otherNav, {
								opacity: 0,
								transform: 'translateY(-10px)'
							}, {
								duration: this.config.animation.duration,
								ease: this.config.animation.ease
							});
						}

						if (otherChevron) {
							animate(otherChevron, { 
								rotate: 0 
							}, {
								duration: this.config.animation.duration,
								ease: this.config.animation.ease
							});
						}
					}
				});

				// Toggle la section courante
				section.classList.toggle('open');
				
				if (!isOpen) {
					// Mesure la hauteur naturelle
					content.style.height = 'auto';
					const height = content.offsetHeight;
					content.style.height = '0px';
					
					// Anime l'ouverture
					await animate(content, { height }, {
						duration: this.config.animation.duration,
						ease: this.config.animation.ease
					});

					animate(nav, {
						opacity: 1,
						transform: 'translateY(0)'
					}, {
						duration: this.config.animation.duration,
						ease: this.config.animation.ease
					});

					if (chevron) {
						animate(chevron, { 
							rotate: 180 
						}, {
							duration: this.config.animation.duration,
							ease: this.config.animation.ease
						});
					}

					// Permet le redimensionnement naturel après l'animation
					content.style.height = 'auto';
				} else {
					await animate(content, { height: 0 }, {
						duration: this.config.animation.duration,
						ease: this.config.animation.ease
					});

					animate(nav, {
						opacity: 0,
						transform: 'translateY(-10px)'
					}, {
						duration: this.config.animation.duration,
						ease: this.config.animation.ease
					});

					if (chevron) {
						animate(chevron, { 
							rotate: 0 
						}, {
							duration: this.config.animation.duration,
							ease: this.config.animation.ease
						});
					}
				}
			});
		});
	}
};

// Initialisation robuste
function initDocumentation() {
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => DocumentationModule.init());
  } else {
    DocumentationModule.init();
  }
}

initDocumentation();
