import Axios from 'axios';
import React from 'react';
import Message from '../../../../Components/Transcripts/Message';
import _ from 'lodash';

const emojiRegex = /(<a?:.+:\D+>)/g;
const userRegex = /(<@!?\d+>)/g;
const channelRegex = /(<#\d+>)/g;

async function parseText(text) {
    const dict = {
        "emojis": {},
        "users": {},
        "channels": {}
    }
    const emojis = text.match(emojiRegex);
    if (emojis) {
        for (let i = 0; i < emojis.length; i++) {
            const emoji = emojis[i];
            const emojiID = emoji.replaceAll(/\D/g, '');
            const emojiURL = `https://cdn.discord.com/emojis/${emojiID}`;
            dict["emojis"][emoji] = emojiURL;
        }
    }
    const users = text.match(userRegex);
    if (users) {
        for (let i = 0; i < users.length; i++) {
            const user = users[i];
            const userID = user.replaceAll(/\D/g, '');
            const username = (await Axios.get(`http://${process.env.NUCLEUS_CALLBACK}/users/${userID}`)).data;
            dict["users"][user.replaceAll(/<@|>/g, '')] = username;
        }
    }
    const channels = text.match(channelRegex);
    if (channels) {
        for (let i = 0; i < channels.length; i++) {
            const channel = channels[i];
            const channelID = channel.replaceAll(/\D/g, '');
            const channelName = (await Axios.get(`http://${process.env.NUCLEUS_CALLBACK}/channels/${channelID}`)).data;
            dict["channels"][channel] = channelName;
        }
    }
    // console.log("parseText", dict)
    return dict
}

async function parse(json) {
    let dict = {
        "emojis": {},
        "users": {},
        "channels": {}
    }

    await _.forEach(json, async (message, index) => {
        let thisMessage = {}
        if(message.content) {
            let parsed = await parseText(message.content)
            // console.log(parsed)
            _.assign(thisMessage, parsed)
        }
        if(message.embeds) {
            _.forEach(message.embeds, async (embed, _index) => {
                // console.log(embed)
                if(embed.description) {
                    let parsed = await parseText(embed.description)
                    _.assign(thisMessage, parsed)
                }
                if(embed.title) {
                    let parsed = await parseText(embed.title)
                    _.assign(thisMessage, parsed)
                }
                if(embed.fields) {
                    _.forEach(embed.fields, async (field, _index) => {
                        if(field.name) {
                            let parsed = await parseText(field.name)
                            _.assign(thisMessage, parsed)
                        }
                        if(field.value) {
                            let parsed = await parseText(field.value)
                            _.assign(thisMessage, parsed)
                        }
                    })
                }
            })
        }
        // console.log(thisMessage)
        _.assign(dict, thisMessage)
        // console.log(index, dict)
    })

    // console.log("dict", dict)
    return dict;
}

function Index(props) {
    return <div style={{overflowY: "scroll", overflowX: "hidden"}}>
        <div style={{
            width: "100vw",
            height: "40px",
            backgroundColor: "#F27878",
            display: "flex",
            justifyContent: "left",
            alignItems: "center",
            paddingLeft: "25px",
            color: "white",
            fontSize: "1.5em",
        }}>Transcript for: {props.data.for.username}#{props.data.for.discriminator} | In #{<a href={`https://discord.com/channels/${props.data.guild}/${props.data.channel}`}>{props.channelName}</a>} | Type: {props.data.type}</div>
        <div style={{
            width: "100vw",
            backgroundColor: "var(--theme-ui-colors-background)", //Can we change this to be not black please. it's too contrast heavy
            margintop: "-50px",
            padding: "25px",
            paddingTop: "10px",
            transition: "all 0.3s ease-in-out"
        }}>
        {
            props.data.messages.map((message, index) => {
                return <Message key={index.toString()} message={message} />
            })
        }
        </div>
    </div>
}

export default Index;
export async function getServerSideProps(ctx) {
    if(!ctx.params.code) {
        return {
            redirect: {
                destination: '/nucleus/transcript/about',
                permanent: true
            }
        }
    }
    return {
        redirect: {
            destination: `/nucleus/transcript/${ctx.params.code}/human?key=${ctx.query.key}`,
            permanent: true
        }
    }
    // let code;
    // try {
    //     code = (await Axios.get(`http://${process.env.NUCLEUS_CALLBACK}/transcript/${ctx.params.code}?key=${ctx.query.key`))
    // } catch (e) {
    //     return {
    //         redirect: {
    //             destination: '/nucleus/transcript/invalid',
    //             permanent: true
    //         }
    //     }
    // }
    // const linkedData = await parse(code.data.messages)

    // const channelName = (await Axios.get(`http://${process.env.NUCLEUS_CALLBACK}/channels/${code.data.channel}`)).data;

    // return {
    //     props: {
    //         data: code.data,
    //         linkedData,
    //         channelName
    //     }
    // }
}