'use client';

import './style.scss';
import '@/app/styles/community.scss';
import { useEffect, useRef } from 'react';
import BoardMeta from '@/types/forum/boardMeta';
import BoardManager from '@/types/forum/boardManager';
import { checkPermission } from '@/lib/utils/permission';

type Props = {
	boardMeta: BoardMeta;
	content: string;
	boardManagers?: BoardManager[];
}

export default function Content({ boardMeta, content, boardManagers }: Props)
{
	const articleRef = useRef<HTMLElement>(null);
	const allowTargetBlank = boardMeta.view.allowContentLinkTargetBlank;

	// $종목 태그 렌더 — 본문 텍스트의 `$005930(삼성전자)` 토큰을 /stock 링크 배지로 치환
	useEffect(() => {
		const el = articleRef.current;
		if (!el) {
			return;
		}

		const pattern = /\$(\d{6})(?!\d)(?:\(([^)]{0,20})\))?/g;

		const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, {
			acceptNode(node) {
				if (!node.nodeValue || !node.nodeValue.includes('$')) {
					return NodeFilter.FILTER_REJECT;
				}

				let parent = node.parentElement;
				while (parent && parent !== el) {
					if (parent.classList && parent.classList.contains('stock-tag')) {
						return NodeFilter.FILTER_REJECT;
					}
					parent = parent.parentElement;
				}

				return NodeFilter.FILTER_ACCEPT;
			}
		});

		const targets: Text[] = [];
		let cursor = walker.nextNode();
		while (cursor) {
			targets.push(cursor as Text);
			cursor = walker.nextNode();
		}

		for (const textNode of targets) {
			const text = textNode.nodeValue ?? '';
			pattern.lastIndex = 0;

			if (!pattern.test(text)) {
				continue;
			}

			pattern.lastIndex = 0;
			const frag = document.createDocumentFragment();
			let lastIndex = 0;
			let match: RegExpExecArray|null;

			while ((match = pattern.exec(text)) !== null) {
				const [full, code, name] = match;

				if (match.index > lastIndex) {
					frag.appendChild(document.createTextNode(text.slice(lastIndex, match.index)));
				}

				const anchor = document.createElement('a');
				anchor.href = `/stock/${code}`;
				anchor.className = 'stock-tag';

				const nameSpan = document.createElement('span');
				nameSpan.textContent = name ? name : code;
				anchor.appendChild(nameSpan);

				const codeSpan = document.createElement('span');
				codeSpan.className = 'stock-tag__code';
				codeSpan.textContent = code;
				anchor.appendChild(codeSpan);

				frag.appendChild(anchor);
				lastIndex = match.index + full.length;
			}

			if (lastIndex < text.length) {
				frag.appendChild(document.createTextNode(text.slice(lastIndex)));
			}

			textNode.parentNode?.replaceChild(frag, textNode);
		}
	}, [content]);

	useEffect(() => {
		const el = articleRef.current;
		if (!el) {
			return;
		}

		const handler = (e: MouseEvent) => {
			const target = e.target as HTMLElement;

			// 파일 다운로드
			const file = target.closest('section.file-embed') as HTMLElement;
			if (file && file.dataset.uuid) {
				// 파일 다운로드 권한 체크
				if (boardManagers) {
					const stored = localStorage.getItem('member');
					const member = stored ? JSON.parse(stored) : null;

					if (!checkPermission(boardMeta, boardManagers, member).canDownloadFile) {
						alert('파일을 다운로드할 수 있는 권한이 없습니다.');
						return;
					}
				}

				window.location.href = `/api/forum/post/file/${file.dataset.uuid}`;
			}

			// 링크 클릭
			const anchor = target.closest('a[data-uuid]') as HTMLAnchorElement;
			if (anchor && anchor.dataset.uuid) {
				e.preventDefault();
				window.open(`/api/forum/post/link/${anchor.dataset.uuid}`, allowTargetBlank ? '_blank' : '_self');
			}
		}

		el.addEventListener('click', handler);
		return () => {
			el.removeEventListener('click', handler);
		}
	}, [allowTargetBlank, boardMeta, boardManagers]);

	return (
		<article ref={articleRef} dangerouslySetInnerHTML={{ __html: content }} className='whitespace-normal break-words'></article>
	);
}
