import path from 'path';
import express from 'express';
import { createServer } from 'http';
import { Server } from '@mescius/js-collaboration';
import * as OT from '@mescius/js-collaboration-ot';
import { SqliteDb } from '@mescius/js-collaboration-ot-sqlite';
import { presenceFeature } from '@mescius/js-collaboration-presence';
import config from 'config';
import { konva_type, rich_text_type, spreadsheet_type } from './ot-types.mjs';
import { docRouter } from './routes/doc.mjs';
import { auth } from './middlewares/express-auth.mjs';
import { UserServices } from './services/user.mjs';
import { userRouter } from './routes/user.mjs';
import { DocServices } from './services/doc.mjs';
import { connectionAuth } from './middlewares/connection-auth.mjs';
import { submitOpAuth } from './middlewares/submit-op-auth.mjs';
import { submitExtraInfo } from './middlewares/submit-extra-info.mjs';
import { db, initTablesIfNotExists } from './db/config.mjs';

initTablesIfNotExists(db);

const port = config.get('port') || 8080;
const app = express();
const httpServer = createServer(app);
const collaborationServer = new Server({ httpServer });

OT.TypesManager.register(rich_text_type);
OT.TypesManager.register(konva_type);
OT.TypesManager.register(spreadsheet_type);

const userServices = new UserServices();

const documentServices = new OT.DocumentServices({ db: new SqliteDb(db) });

const docServices = new DocServices(documentServices);

app.use(express.static('public'));
app.use(express.json());

app.use('/api', auth(userServices, ['/login', '/signup', '/user/oauth/redirect']));
app.use('/api', docRouter(docServices));
app.use('/api', userRouter(userServices));

app.use('*', (req, res) => {
    res.setHeader('Content-Type', 'text/html').sendFile(path.join(process.cwd(), './public/index.html'));
});

collaborationServer.use('connect', connectionAuth(userServices, docServices));
collaborationServer.useFeature(OT.documentFeature(documentServices));
collaborationServer.useFeature(presenceFeature());

documentServices.use('submit', submitOpAuth());
documentServices.use('afterWrite', submitExtraInfo(docServices));

collaborationServer.on({
    connect: () => { console.log('connection'); },
    enterRoom: () => { console.log('enterRoom'); },
    message: ({ data, type }) => { if (type === 'ot-doc') { console.log('message', data); } },
    leaveRoom: () => { console.log('leaveRoom'); },
});

httpServer.listen(port, () => {
    console.log(`Server listening on port ${port}`);
    console.log(`http://localhost:${port}/`);
});
