'use client';

import { useEffect, useRef } from 'react';
import { Rnd } from 'react-rnd';
import Quill from 'quill';
import 'quill/dist/quill.snow.css';
import '@/styles/quill.scss';
import ReactDOM from 'react-dom/client';
import FileUploader from './FileUploader';
import FileBlot from './FileBlot';

const BlockEmbed = Quill.import('blots/block/embed');

// --------- FileUploader ---------
class ResizableImageBlot extends BlockEmbed {
	static blotName = 'resizableImage';
	static tagName = 'div';
	static className = 'resizable-image-container';
  
	static create(value) {
	  // value: { url: string, width?: number, height?: number }
	  const node = super.create();
	  // 저장할 이미지 정보
	  node.setAttribute('data-url', value.url);
	  node.setAttribute('data-width', value.width || 200);
	  node.setAttribute('data-height', value.height || 200);
	  // React 컴포넌트를 렌더링할 컨테이너 생성
	  const container = document.createElement('div');
	  container.classList.add('resizable-image-inner');
	  node.appendChild(container);
	  return node;
	}
  
	static value(node) {
	  // 블롯의 값을 Delta로 저장할 때 사용
	  return {
		url: node.getAttribute('data-url'),
		width: node.getAttribute('data-width'),
		height: node.getAttribute('data-height')
	  };
	}

	renderReactComponent() {
		const node = this.domNode as HTMLElement;
		const container = node.querySelector('.resizable-image-inner');
		const initialWidth = parseInt(node.getAttribute('data-width') || '200', 10);
		const initialHeight = parseInt(node.getAttribute('data-height') || '200', 10);
		const url = node.getAttribute('data-url') || '';
	
		// React 18 이상에서는 createRoot 사용
		const root = ReactDOM.createRoot(container!);
		root.render(
		  <Rnd
			default={{
			  width: initialWidth,
			  height: initialHeight,
			}}
			bounds="parent"
			enableResizing={{
			  top: true,
			  right: true,
			  bottom: true,
			  left: true,
			  topRight: true,
			  bottomRight: true,
			  bottomLeft: true,
			  topLeft: true,
			}}
			onResizeStop={(e, direction, ref, delta, position) => {
			  // 리사이즈 완료 후 새로운 크기를 data-속성에 저장
			  node.setAttribute('data-width', String(ref.offsetWidth));
			  node.setAttribute('data-height', String(ref.offsetHeight));
			}}
		  >
			<img
			  src={url}
			  alt=""
			  style={{ width: '100%', height: '100%', objectFit: 'contain' }}
			/>
		  </Rnd>
		);
	  }
}

Quill.register(ResizableImageBlot);
Quill.register('modules/fileUploader', FileUploader);
Quill.register(FileBlot);

// --------- Quill Editor ---------

// 글씨 크기 설정
const FontSizeStyle = Quill.import('attributors/style/size') as any;
FontSizeStyle.whitelist = ['11px', '13px', '15px', '16px', '19px', '24px', '28px', '30px', '34px', '38px'];
Quill.register(FontSizeStyle, true);

interface QuillEditorProps {
    content: string|null|'';
    onChange: (content: string) => void;
}

export default function Editor({ content, onChange }: QuillEditorProps) {
    const editorRef = useRef<HTMLDivElement | null>(null);
    const quillInstanceRef = useRef<Quill | null>(null);

    useEffect(() => {
        if (editorRef.current && !quillInstanceRef.current) {
			const icons = Quill.import('ui/icons') as Record<string, string>;

			// 파일 아이콘 생성
			icons['file'] = '<svg viewBox="0 -0.5 17 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="si-glyph si-glyph-file-upload" fill="#000000"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <title>1126</title> <defs> </defs> <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <g transform="translate(1.000000, 1.000000)" fill="#434343"> <path d="M14,8.047 L14,12.047 L2,12.047 L2,8.047 L0,8.047 L0,15 L15.969,15 L15.969,8.047 L14,8.047 Z" class="si-glyph-fill"> </path> <path d="M7.997,0 L5,3.963 L7.016,3.984 L7.016,8.969 L8.953,8.969 L8.953,3.984 L10.953,3.984 L7.997,0 Z" class="si-glyph-fill"> </path> </g> </g> </g></svg>';

            quillInstanceRef.current = new Quill(editorRef.current, {
                theme: 'snow',
                modules: {
                    toolbar: {
						container: [
							[{ font: [] }, { size: ['11px', '13px', '15px', '16px', '19px', '24px', '28px', '30px', '34px', '38px']}],
							['bold', 'italic', 'underline', 'strike', { color: [] }, { background: [] }],
							[{ align: [] }, { list: 'ordered' }, { list: 'bullet' }],
							['blockquote', 'code-block', 'clean'],
							['link', 'image', 'video', 'file']
						],
						handlers: {
							file: () => {
                                const uploader = quillInstanceRef.current?.getModule('fileUploader') as FileUploader;
								uploader?.selectFile();
							}
						},
					},
                    clipboard: {
                        matchVisual: false,
                    },
				
                    fileUploader: {}
                }
            });

			quillInstanceRef.current.root.innerHTML = content || '';

			// 에디터 내용 변경 시
            quillInstanceRef.current.on('text-change', () => {
                onChange(quillInstanceRef.current!.root.innerHTML);
            });

			// 첨부파일 클릭 시 활성화 제거
			quillInstanceRef.current.on('selection-change', () => {
				const uploader = quillInstanceRef.current?.getModule('fileUploader') as FileUploader;
				if (uploader) {
					uploader.clearActiveCards();
				}
			});

			// FileCardBlot에 quillInstanceRef.current를 주입
			FileBlot.setQuillInstance(quillInstanceRef.current);
			const quillRoot = quillInstanceRef.current.root;
			// drop 위치 처리
			quillRoot.addEventListener('dragover', (e) => {
				e.preventDefault();
			});
	
			quillRoot.addEventListener('drop', (e) => {
				e.preventDefault();
				const data = e.dataTransfer?.getData('text/plain');
				if (!data) return;
	
				const file = JSON.parse(data);
	
				// 현재 커서 위치 찾기
				const selection = quillInstanceRef.current!.getSelection();
				const index = selection ? selection.index : quillInstanceRef.current!.getLength();
	
				// 기존 dragging 된 요소 삭제
				const draggingNode = quillRoot.querySelector('.file-card.dragging');
				draggingNode?.remove();
	
				// 새로운 위치에 삽입
				quillInstanceRef.current!.insertEmbed(index, 'fileCard', file, Quill.sources.USER);
				quillInstanceRef.current!.setSelection(index + 1);
			});
        }
    }, []);

	useEffect(() => {
		if (quillInstanceRef.current) {
			const currentHTML = quillInstanceRef.current.root.innerHTML;
			if (currentHTML !== (content || '')) {
				quillInstanceRef.current.root.innerHTML = content || '';
			}
		}
	}, [content]);

    return (
        <div className="w-full">
            <div ref={editorRef} />
        </div>
    );
}