import {TiptapAttrValue, TiptapLinkAttrs, TiptapNode} from "@/lib/types/chapter";

function isTiptapLinkAttrs(value: TiptapAttrValue): value is TiptapLinkAttrs {
    return typeof value === 'object' && value !== null && 'href' in value;
}

export function getPageCount(text: string): number {
    const charactersPerLine: number = 90;
    const linesPerPage: number = 40;
    
    const lines: string[] = text.split('\n');
    let totalLines: number = 0;
    
    lines.forEach((line: string) => {
        const lineLength: number = line.length;
        const estimatedLines: number = Math.ceil(lineLength / charactersPerLine);
        totalLines += estimatedLines;
    });
    
    return Math.ceil(totalLines / linesPerPage);
}

export function convertTiptapToHTML(node: TiptapNode): string {
    let html: string = '';
    
    switch (node.type) {
        case 'doc':
            if (node.content) {
                node.content.forEach((childNode: TiptapNode) => {
                    html += convertTiptapToHTML(childNode);
                });
            }
            break;
        
        case 'paragraph':
            html += '<p>';
            if (node.content) {
                node.content.forEach((childNode: TiptapNode) => {
                    html += convertTiptapToHTML(childNode);
                });
            }
            html += '</p>';
            break;
        
        case 'text':
            let textContent: string = node.text || '';
            
            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 && isTiptapLinkAttrs(node.attrs.link)) {
                    textContent = `<a href="${node.attrs.link.href}">${textContent}</a>`;
                }
            }
            
            html += textContent;
            break;
        
        case 'heading':
            const level: number = typeof node.attrs?.level === 'number' ? node.attrs.level : 1;
            html += `<h${level}>`;
            if (node.content) {
                node.content.forEach((childNode: TiptapNode) => {
                    html += convertTiptapToHTML(childNode);
                });
            }
            html += `</h${level}>`;
            break;
        
        case 'bulletList':
            html += '<ul>';
            if (node.content) {
                node.content.forEach((childNode: TiptapNode) => {
                    html += convertTiptapToHTML(childNode);
                });
            }
            html += '</ul>';
            break;
        
        case 'orderedList':
            html += '<ol>';
            if (node.content) {
                node.content.forEach((childNode: TiptapNode) => {
                    html += convertTiptapToHTML(childNode);
                });
            }
            html += '</ol>';
            break;
        
        case 'listItem':
            html += '<li>';
            if (node.content) {
                node.content.forEach((childNode: TiptapNode) => {
                    html += convertTiptapToHTML(childNode);
                });
            }
            html += '</li>';
            break;
        
        case 'blockquote':
            html += '<blockquote>';
            if (node.content) {
                node.content.forEach((childNode: TiptapNode) => {
                    html += convertTiptapToHTML(childNode);
                });
            }
            html += '</blockquote>';
            break;
        
        case 'codeBlock':
            html += '<pre><code>';
            if (node.content) {
                node.content.forEach((childNode: TiptapNode) => {
                    html += convertTiptapToHTML(childNode);
                });
            }
            html += '</code></pre>';
            break;
        
        default:
            if (node.content) {
                node.content.forEach((childNode: TiptapNode) => {
                    html += convertTiptapToHTML(childNode);
                });
            }
            break;
    }
    
    return html;
}
