require("dotenv").config();
const db = require('./db');

const twit = require("./twit");
var stream = twit.stream('statuses/filter', { track: '@ValerianWoman' });

// Global variables
const CONTENT_TYPES = {
  SONG:['song', 'cancion', 'canción'],
  QUOTE: ['quote', 'frase', 'cita']
}

const contentList = [];
for (let category in CONTENT_TYPES) {
  contentList.push(...CONTENT_TYPES[category]);
}
console.log(`Content List: ${contentList}`);
/////////////////////////

function tweetMessage(message) {
  return new Promise((resolve, reject) => {
    const tweet = { status: message };
    twit.post('statuses/update', tweet, (err, data) => {
      if (err) {
        return reject(err);
      } else {
        return resolve(data);
      }
    });

  })

}

////////////////////
async function tweetLyrics(tweetMsg) {

  const song = JSON.stringify(content.songs[1].url);
  const replyTo = tweetMsg.in_reply_to_screen_name;
  const text = tweetMsg.text;
  const from = tweetMsg.user.screen_name;

  console.log(`replyTo: ${replyTo}`);
  console.log(`from: ${from}`);
  console.log(`text: ${text}`);

  if (replyTo === 'ValerianWoman') {
    try {
      //const botReply = `@${from} ${lyric}`;
      const botReply = `@${from} ${song}`;
      await tweetMessage(botReply);
      console.log('Message tweeted successfuly!')
    } catch(err) {
      console.error(`Something went wrong: ${err}`);
    }
  }
}

/////////////////////////////
// Takes the tweets catched by the stream and deconstructs them
function deconstructTweet(tweetMsg) {
  // Deconstruct tweet
  const replyTo = tweetMsg.in_reply_to_screen_name;
  const messageText = tweetMsg.text;
  const from = tweetMsg.user.screen_name;

  return {
    replyTo,
    messageText,
    from
  }
}

/////////////////////////////
// Composes tweet using a deconstructed tweet and content to be sent
function composeTweet(tweetParts, content) {
  const { replyTo, messageText, from } = tweetParts;
  const botReply = `@${from} ${content}`;

  return botReply;
}

/////////////////////////////
// Creates a random number from a list of content
function getRandNum(array) {
  return Math.floor(Math.random() * array.length);
}

////////////////////////////
// Picks a random quote or song from the JSON file to be tweeted
function selectContent(value, content) {
  const songArray = CONTENT_TYPES.SONG;
  const quoteArray = CONTENT_TYPES.QUOTE;

  if (songArray.includes(value)) {
    console.log('It is a song.');
    const index = getRandNum(content.songs);
    console.log(`Index: ${index}`);
    const pick = JSON.stringify(content.songs[index].url);
    console.log(pick);
    return pick;
  } else {
    console.log('It is a quote.');
    const index = getRandNum(content.quotes);
    console.log(`Index: ${index}`);
    const pick = JSON.stringify(content.quotes[index].text);
    console.log(pick);
    return pick;
  }
}

//////////////////////////////////
// Does initial checks on the tweeted mention including:
// checking if it's a string, checking if it's a song or quote
function handleReply(tweetParts) {
  
  const request = tweetParts.messageText;
  console.log(`request: ${request}`);
  // Check if request is a string
  console.log(`Type of request: ${typeof request}`);
  if (typeof request !== 'string') return 'Not a string!';
  const contentType = request.toLowerCase().split(' ')[1];
  console.log(`contentType: ${contentType}`);

  if (contentList.includes(contentType)) {
    console.log(`Success!: ${contentType}`);
    return contentType;
  } else {
    console.log(`Error: Something went wrong.`);
    return false;
  }
}

/////////////////////
// Main program function
async function main() {
  // Load JSON database
  console.log('Loading content database...');

  try {
    const content = await db();
    
    stream.on('tweet', async function(tweet) {
      console.log('Handling stream...');
      // Deconstruct tweet into components
      const tweetParts = deconstructTweet(tweet);
      // Do some checks on tweet
      const response = handleReply(tweetParts);
      if (response === false) {
        // If the request is not a song or a quote, 
        // do nothing
        return null;
      }
      // Select content
      const pick = selectContent(response, content);
      // Compose tweet
      const tweetReady = composeTweet(tweetParts, pick);
      // Send tweet
      await tweetMessage(tweetReady);
      //await tweetLyrics(tweet);
    });
  } catch(err) {
    console.error(err);
  }

  // db()
  //   .then(data => {
  //     //console.log(data);
  //     const content = data;
  //     //console.log(content);
  //     stream.on('tweet', async function(tweet) {
  //       await tweetLyrics(tweet);
  //     });
  //   })
  //   .catch(err => err);

}

console.log('Starting Valerian bot...');
main();
