/* eslint-disable @typescript-eslint/no-explicit-any */
import * as OT from '@mescius/js-collaboration-ot-client';
import { Presence } from "@mescius/js-collaboration-presence-client";
import Quill from 'quill';
import 'quill/dist/quill.snow.css';
import { IDoc } from '../../request/doc';

import { useEffect, useRef, useState } from 'react';
import { rich_text_type } from '../../ot-types';
import { IUser } from '../../request/user';
import { connect } from '../../request/req';
import {CustomHeader, PageType} from "../Header";

OT.TypesManager.register(rich_text_type);

interface IPresence {
    user: IUser;
}

export default function SharedQuill(props: { doc: IDoc, user: IUser, readonly: boolean }) {
    const ref = useRef<HTMLDivElement>(null);
    const { doc, user } = props;

    useEffect(() => {
        const conn = connect(doc.id);
        const sharedDoc = new OT.SharedDoc(conn);
        const presence = new Presence<IPresence>(conn);
        const div = ref.current as HTMLDivElement;
    
        const quill = new Quill(div, { theme: 'snow', readOnly: props.readonly });

        bind(quill, sharedDoc);

        return () => {
            conn.close();
            sharedDoc.destroy();
            presence.destroy();

            div.previousSibling?.remove();
            div.innerHTML = '';
        }
    }, [doc.id, user])

    return (
        <CustomHeader type={PageType.Open} doc={doc}>
            <div style={{ width: '100%', height: '100%', background: 'white', display: 'flex', flexDirection: 'column' }}>
                <div ref={ref}></div>
            </div>
        </CustomHeader>
    )
}

async function bind(quill: Quill, doc: OT.SharedDoc) {
    await doc.subscribe();
    quill.setContents(doc.data as any);
    quill.on('text-change', function (delta: unknown, _oldDelta: unknown, source: string) {
        console.log('text-change');
        if (source !== 'user') return;
        doc.submitOp(delta, { source: doc.connection.id });
    });
    doc.on('op', function (op, source) {
        if (source === doc.connection.id) return;
        quill.updateContents(op as any);
    });

    doc.on('error', (err) => console.error(err))
}
