import fs from 'fs';
import { MessageEvent } from "matrix-bot-sdk";
import { db } from "./db.js"
const configPath = './config.json';

const logError = (message) => {
    let time = new Date;
    console.error(`[${time.toLocaleString()}] [LOG] [E] ${message}`);
};

const logInfo = (message) => {
    let time = new Date;
    console.log(`[${time.toLocaleString()}] [LOG] [I] ${message}`);
};

const readConfig = () => {

    if (!fs.existsSync(configPath)) {

        fs.writeFileSync(configPath,
            `{
                "homeserverURL": "https://matrix.org/",
                "token": "Super secret token! Do not show to anyone! Even your mum! ;)",
                "maxAmountOfPhotoesPerUser": 5
            }`
        );

        logError('[LOG] [E] Config file was not found. I have created a template, please, edit it and restart a bot.');

        process.exit(-1);
    }

    return JSON.parse(fs.readFileSync(configPath));
};

const uploadMediaFromEvent = async (client, event) => {
    const message = new MessageEvent(event);
    const fileEvent = new MessageEvent(message.raw);
    const decrypted = await client.crypto.decryptMedia(fileEvent.content.file);
    const mxc = await client.uploadContent(decrypted);
    return mxc;
};

const uploadMediaAsMessage = async (roomId, type, mxc) => {
    await db.query("INSERT INTO media(owner, type, purpose, url) VALUES ($1, $2, 'm', $3)", [roomId, convertMsgType(type), mxc]);
};

const convertMsgType = (msgtype) => {
    switch (msgtype) {
        case "m.image":
            return "p";
        case "m.video":
            return "v";
        case "m.text":
            return "t";
        default:
            return msgtype;
    }
};


const getCityNameByID = async (id) => {
    return (await db.query(`SELECT name FROM cities WHERE ID = $1`, [id])).rows[0].name;
}

const getCountryNameByID = async (id) => {
    return (await db.query(`SELECT country FROM cities WHERE ID = $1`, [id])).rows[0].country;
}

const findCity = async (name) => {
    return (await db.query(`SELECT ID, name, lat, lng, country, levenshtein(name, $1) AS similarity
                               FROM cities
                               ORDER BY similarity ASC
                               LIMIT 5`, [name])
    ).rows;
}

const insertMessageIntoDB = async (roomId, recipient, type, content) => {
    let rowAmount = (await db.query("INSERT INTO messages (sender, recipient, type, content) VALUES ($1, $2, $3, $4) ON CONFLICT(sender, recipient) DO NOTHING RETURNING *", [roomId, recipient, convertMsgType(type), content])).rowCount;
    return rowAmount == 1;
};

const sequence = {
    "wait_start": "location",
    "location": "range",
    "range": "name",
    "name": "age",
    "age": "sex",
    "sex": "interest",
    "interest": "description",
    "description": "pictures",
    "pictures": "view_profiles"
};

const max_length = {
    "name": 32,
    "description": 512,
    "message": 128
}

export {
    readConfig,
    logError,
    logInfo,
    uploadMediaFromEvent,
    convertMsgType,
    sequence,
    max_length,
    getCityNameByID,
    getCountryNameByID,
    findCity,
    insertMessageIntoDB,
    uploadMediaAsMessage
};