#!/usr/bin/env node

const _ = require('lodash');
const request = require('request');
const cheerio = require('cheerio');
const Table = require('cli-table3');

const TRILLIUM_WEBSITE_URL = 'http://www.trilliumbrewing.com';
const requestOpts = {
  headers: { 'User-Agent': 'request' },
};

const normalizeBackupBeerName = (name) => {
  const normalizedName = name
    .replace(/trillium/gi, '') // remove `trillium`
    .replace(/_|-/g, ' ') // replace hyphens and underscores with spaces
    .replace('.', '') // remove period
    .replace(/gif|png|jpg|jpeg/gi, ' ') // remove image file extensions
    .trim(); // remove leading whitespace

  return normalizedName;
};

const getBeerName = ($el) => {
  const name = $el.find('.summary-thumbnail-container').data('title');
  const backupName = $el.find('.summary-thumbnail-container img').attr('alt');

  if (name.length) {
    return name;
  }
  if (backupName.length) {
    return normalizeBackupBeerName(backupName);
  }
  return 'Unknown beer name';
};

const getBeerPrice = ($el) => {
  const description = $el.find('.summary-metadata--primary').text();
  const re = /(\$.*) (per|for) 4-pack/i;
  const hasCans = description.match(re);

  if (hasCans) {
    return hasCans[1];
  }
  return null;
};

const getBeerDescriptionUrl = ($el) => {
  const description = $el.find('.summary-thumbnail-container');
  const path = description.attr('href');
  const url = `${TRILLIUM_WEBSITE_URL}${path}`;
  return url;
};

const getBeerImageUrl = ($el) => {
  const image = $el.find('.summary-thumbnail-image');
  const imageUrl = image.data('src');
  return imageUrl;
};

const getBeerData = ($beerList) => {
  const beers = _.map($beerList, (beer) => {
    const beerData = {
      name: getBeerName($(beer)),
      price: getBeerPrice($(beer)),
      url: getBeerDescriptionUrl($(beer)),
      image: getBeerImageUrl($(beer)),
    };
    return beerData;
  });
  const onlyCannedBeers = beers.filter((beer) => beer.price !== null);
  return _.sortBy(onlyCannedBeers, 'name');
};

const renderAvailabilityTable = (locations) => {
  const table = new Table({
    head: ['Location', '', 'Name', '4-pack Price'],
  });

  // eslint-disable-next-line consistent-return
  locations.forEach(([locationLabel, html]) => {
    const data = getBeerData(html);

    if (!data.length) {
      return null;
    }
    const header = {
      rowSpan: data.length,
      content: locationLabel,
      vAlign: 'center',
    };

    data.forEach(({ name, price }, i) => {
      if (i === 0) {
        table.push([header, i + 1, name, price]);
      } else {
        table.push([i + 1, name, price]);
      }
    });
  });

  if (!table.length) {
    throw new Error('Something went wrong and no beers were discovered');
  }

  return console.log(table.toString());
};

const parseTrilliumWebsite = (error, response, body) => {
  if (error) {
    return console.error(error);
  }

  global.$ = cheerio.load(body);

  const $locations = $('.summary-item-list-container');
  const $fortPointBeerList = $('.summary-item', $locations[0]);
  const $cantonBeerList = $('.summary-item', $locations[1]);

  return renderAvailabilityTable([
    ['Fort Point', $fortPointBeerList],
    ['Canton', $cantonBeerList],
  ]);
};

request(`${TRILLIUM_WEBSITE_URL}/beers`, requestOpts, parseTrilliumWebsite);

@@ -49,23 +49,21 @@
 ;%0Aconst 
-request
+axios
  = requi
@@ -66,23 +66,21 @@
 equire('
-request
+axios
 ');%0Acons
@@ -218,27 +218,22 @@
 ;%0Aconst 
-requestOpts
+config
  = %7B%0A  h
@@ -257,23 +257,21 @@
 gent': '
-request
+axios
 ' %7D,%0A%7D;%0A
@@ -2812,90 +2812,110 @@
 e = 
-(error, response, body) =%3E %7B%0A  if (error) %7B%0A    return console.error(error);%0A  %7D%0A%0A
+async (url) =%3E %7B%0A  try %7B%0A    const response = await axios.get(url);%0A    const %7B data %7D = response;%0A%0A  
   gl
@@ -2940,16 +2940,18 @@
 oad(
-body
+data
 );%0A%0A
+  
   co
@@ -2994,32 +2994,34 @@
 st-container');%0A
+  
   const $fortPoi
@@ -3066,24 +3066,26 @@
 ions%5B0%5D);%0A  
+ 
+ 
 const $canto
@@ -3132,16 +3132,18 @@
 s%5B1%5D);%0A%0A
+  
   return
@@ -3173,16 +3173,18 @@
 e(%5B%0A    
+ 
+ 
 %5B'Fort P
@@ -3215,16 +3215,18 @@
 t%5D,%0A    
+  
 %5B'Canton
@@ -3252,23 +3252,95 @@
 ,%0A  
+ 
+ 
 %5D);%0A
-%7D;%0A%0Arequest
+  %7D catch (error) %7B%0A    return console.error(error);%0A  %7D%0A%7D;%0A%0AparseTrilliumWebsite
 (%60$%7B
@@ -3373,40 +3373,17 @@
 s%60, 
-requestOpts, parseTrilliumWebsite
+%7B%7D, config
 );%0A

update code to use axios