export interface TiptapNode {
    type: string;
    content?: TiptapNode[];
    text?: string;
    attrs?: {
        [key: string]: any;
    };
}

export default class Content {
    static convertTipTapRawToText(content: string): string {
        const text: string = this.convertTiptapToHTMLFromString(content);
        return this.htmlToText(text);
    }

    static htmlToText(html: string) {
        return html
            .replace(/<br\s*\/?>/gi, '\n') // Gérer les <br> d'abord
            .replace(/<\/?(p|h[1-6]|div)(\s+[^>]*)?>/gi, '\n') // Balises bloc
            .replace(/<\/?[^>]+(>|$)/g, '') // Supprimer toutes les balises restantes
            .replace(/(\n\s*){2,}/g, '\n\n') // Préserver les paragraphes
            .replace(/^\s+|\s+$|(?<=\s)\s+/g, '') // Nettoyer les espaces
            .trim();
    }

    static convertTiptapToHTMLFromString(jsonString: string): string {
        // Convert the JSON string to an object
        let jsonObject: TiptapNode;
        try {
            jsonObject = JSON.parse(jsonString);
        } catch (error) {
            console.error('Invalid JSON string:', error);
            return '';
        }

        // Use the existing conversion function
        return this.convertTiptapToHTML(jsonObject);
    }

    static convertTiptapToHTML(node: TiptapNode): string {
        let html = '';

        switch (node.type) {
            case 'doc':
                if (node.content) {
                    node.content.forEach(childNode => {
                        html += this.convertTiptapToHTML(childNode);
                    });
                }
                break;

            case 'paragraph':
                html += '<p>';
                if (node.content) {
                    node.content.forEach(childNode => {
                        html += this.convertTiptapToHTML(childNode);
                    });
                }
                html += '</p>';
                break;

            case 'text':
                let textContent = node.text || '';

                // Apply attributes like bold, italic, etc.
                if (node.attrs) {
                    if (node.attrs.bold) {
                        textContent = `<strong>${textContent}</strong>`;
                    }
                    if (node.attrs.italic) {
                        textContent = `<em>${textContent}</em>`;
                    }
                    if (node.attrs.underline) {
                        textContent = `<u>${textContent}</u>`;
                    }
                    if (node.attrs.strike) {
                        textContent = `<s>${textContent}</s>`;
                    }
                    if (node.attrs.link) {
                        textContent = `<a href="${node.attrs.link.href}">${textContent}</a>`;
                    }
                }

                html += textContent;
                break;

            case 'heading':
                const level = node.attrs?.level || 1;
                html += `<h${level}>`;
                if (node.content) {
                    node.content.forEach(childNode => {
                        html += this.convertTiptapToHTML(childNode);
                    });
                }
                html += `</h${level}>`;
                break;

            case 'bulletList':
                html += '<ul>';
                if (node.content) {
                    node.content.forEach(childNode => {
                        html += this.convertTiptapToHTML(childNode);
                    });
                }
                html += '</ul>';
                break;

            case 'orderedList':
                html += '<ol>';
                if (node.content) {
                    node.content.forEach(childNode => {
                        html += this.convertTiptapToHTML(childNode);
                    });
                }
                html += '</ol>';
                break;

            case 'listItem':
                html += '<li>';
                if (node.content) {
                    node.content.forEach(childNode => {
                        html += this.convertTiptapToHTML(childNode);
                    });
                }
                html += '</li>';
                break;

            case 'blockquote':
                html += '<blockquote>';
                if (node.content) {
                    node.content.forEach(childNode => {
                        html += this.convertTiptapToHTML(childNode);
                    });
                }
                html += '</blockquote>';
                break;

            case 'codeBlock':
                html += '<pre><code>';
                if (node.content) {
                    node.content.forEach(childNode => {
                        html += this.convertTiptapToHTML(childNode);
                    });
                }
                html += '</code></pre>';
                break;

            default:
                console.warn(`Unhandled node type: ${node.type}`);
                if (node.content) {
                    node.content.forEach(childNode => {
                        html += this.convertTiptapToHTML(childNode);
                    });
                }
                break;
        }

        return html;
    }
}
