const { jidNormalizedUser, proto, getContentType, areJidsSameUser } = require('@whiskeysockets/baileys')
const chalk = require('chalk')
const fs = require('fs')
const Crypto = require('crypto')
const axios = require('axios')
const moment = require('moment-timezone')
const { sizeFormatter } = require('human-readable')
const util = require('util')
const Jimp = require('jimp')

// --- FORMATTERS ---
exports.unixTimestampSeconds = (date = new Date()) => Math.floor(date.getTime() / 1000)

exports.tanggal = (numer) => {
    const myMonths = ["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"];
    const myDays = ['Minggu','Senin','Selasa','Rabu','Kamis','Jum’at','Sabtu']; 
    let tgl = new Date(numer);
    let day = tgl.getDate()
    let bulan = tgl.getMonth()
    let thisDay = myDays[tgl.getDay()];
    let year = tgl.getFullYear(); 
    let d = new Date
    let gmt = new Date(0).getTime() - new Date('1 January 1970').getTime()
    let weton = ['Pahing', 'Pon','Wage','Kliwon','Legi'][Math.floor(((d * 1) + gmt) / 84600000) % 5]
    return `${thisDay} ${weton}, ${day} ${myMonths[bulan]} ${year}`
}

exports.runtime = function(seconds) {
    seconds = Number(seconds);
    var d = Math.floor(seconds / (3600 * 24));
    var h = Math.floor(seconds % (3600 * 24) / 3600);
    var m = Math.floor(seconds % 3600 / 60);
    var s = Math.floor(seconds % 60);
    return `${d > 0 ? d + "d " : ""}${h > 0 ? h + "h " : ""}${m > 0 ? m + "m " : ""}${s}s`;
}

exports.formatSize = sizeFormatter({
    std: 'JEDEC',
    decimalPlaces: 2,
    keepTrailingZeroes: false,
    render: (literal, symbol) => `${literal} ${symbol}B`,
})

exports.getBuffer = async (url, options) => {
    try {
        const res = await axios({
            method: "get",
            url,
            headers: { 'DNT': 1, 'Upgrade-Insecure-Request': 1 },
            ...options,
            responseType: 'arraybuffer'
        })
        return res.data
    } catch (err) { return err }
}

// --- MEDIA HELPERS ---
exports.reSize = async (buffer, x, z) => {
    const buff = await Jimp.read(buffer)
    return await buff.resize(x, z).getBufferAsync(Jimp.MIME_JPEG)
}

exports.generateProfilePicture = async (buffer) => {
    const jimp = await Jimp.read(buffer)
    const min = jimp.getWidth()
    const max = jimp.getHeight()
    const cropped = jimp.crop(0, 0, min, max)
    return {
        img: await cropped.scaleToFit(720, 720).getBufferAsync(Jimp.MIME_JPEG),
        preview: await cropped.scaleToFit(720, 720).getBufferAsync(Jimp.MIME_JPEG)
    }
}

exports.sleep = async (ms) => {
    return new Promise(resolve => setTimeout(resolve, ms));
}

exports.smsg = (client, m, store) => {
    if (!m) return m
    let M = proto.WebMessageInfo

    if (client) {
        if (!client.sendText) {
            client.sendText = (jid, text, quoted = '', options) => client.sendMessage(jid, { text: text, ...options }, { quoted })
        }
    }

    if (m.key) {
        m.id = m.key.id
        m.chat = m.key.remoteJid
        m.fromMe = m.key.fromMe
        m.isGroup = m.chat.endsWith('@g.us')
        m.sender = client.decodeJid((m.fromMe && client.user.id) || m.participant || m.key.participant || m.chat)
    }

    if (m.message) {
        m.mtype = getContentType(m.message)
        m.msg = (m.mtype === 'viewOnceMessage' ? m.message[m.mtype].message[getContentType(m.message[m.mtype].message)] : m.message[m.mtype])
        
        m.body = m.message.conversation || m.msg?.caption || m.msg?.text || (m.mtype == 'listResponseMessage' && m.msg.singleSelectReply?.selectedRowId) || (m.mtype == 'buttonsResponseMessage' && m.msg.selectedButtonId) || (m.mtype == 'interactiveResponseMessage' && JSON.parse(m.msg.nativeFlowResponseMessage?.paramsJson || '{}').id) || ''
        m.text = m.body

        if (m.msg?.contextInfo?.quotedMessage) {
            let quoted = m.msg.contextInfo.quotedMessage
            let type = getContentType(quoted)
            m.quoted = quoted[type]

            if (typeof m.quoted === 'string') {
                m.quoted = { text: m.quoted }
            }

            m.quoted.mtype = type
            m.quoted.id = m.msg.contextInfo.stanzaId
            m.quoted.chat = m.msg.contextInfo.remoteJid || m.chat
            m.quoted.sender = client.decodeJid(m.msg.contextInfo.participant)
            m.quoted.fromMe = m.quoted.sender === client.user.id
            
            m.quoted.text = m.quoted.text || m.quoted.caption || m.quoted.conversation || m.quoted.contentText || m.quoted.selectedDisplayText || m.quoted.title || ''
        }
        
        m.reply = (text, chatId = m.chat, options = {}) => {
            if (Buffer.isBuffer(text)) return client.sendMessage(chatId, { document: text, mimetype: 'application/octet-stream', ...options }, { quoted: m })
            return client.sendMessage(chatId, { text: text, ...options }, { quoted: m })
        }
    }

    return m
}


let file = require.resolve(__filename)
fs.watchFile(file, () => {
    fs.unwatchFile(file)
    console.log(chalk.redBright(`Update ${__filename}`))
    delete require.cache[file]
    require(file)
})
