const logger = require('log4js').getLogger('Weather 🔧');
const fecha = require('fecha');

const { get } = require('lodash');

logger.level = 'debug';

function getTodaysForcast(hourlyData) {
  const data = get(hourlyData, 'data', []);

  const output = [];
  const now = new Date().getTime();
  const nowToHour = now - (now % 3600000);
  const tomorrow = nowToHour + (60 * 1000 * 60 * 24);

  for (const item of data) {
    const time = item.time * 1000;
    if (!(time < nowToHour || time > tomorrow)) {
      // logger.debug(item);
      const newItem = { 'time': fecha.format(time, 'h A'), 'icon': item.icon, 'temp': item.temperature, 'precip': item.precipProbability };
      output.push(newItem);
    }
  }

  return output;
}

function getDailyForcast(dailyData) {
  const data = get(dailyData, 'data', []);

  const output = [];

  const h24 = (60 * 1000 * 60 * 24);
  const now = new Date().getTime();

  const startOD = now - (now % h24);
  const endOD = startOD + h24 - 1;

  for (const item of data) {
    const time = item.time * 1000;
    if (!(time < endOD)) {
      // logger.debug(item);
      const newItem = {
        'time': fecha.format(time, 'dddd'),
        'icon': item.icon,
        'tempHigh': item.temperatureHigh,
        'tempLow': item.temperatureLow,
        'precip': item.precipProbability,
        'precipType': item.precipType
      };
      output.push(newItem);
    }
  }

  return output;
}

function toCompass(degrees) {
  return ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE', 'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW', 'N'][Math.round(degrees / 11.25 / 2)];
}


function moonCalc(moonPhase) {
  let output = '';
  if (moonPhase === 0.0)
    output = 'New moon';
  else if (moonPhase >= 0.1 && moonPhase < 0.25)
    output = 'waxing crescent';
  else if (moonPhase === 0.25)
    output = 'First Quarter';
  else if (moonPhase > 0.25 && moonPhase < 0.5)
    output = 'waxing gibbous';
  else if (moonPhase === 0.5)
    output = 'Full moon';
  else if (moonPhase > 0.5 && moonPhase < 0.75)
    output = 'Waning gibbous';
  else if (moonPhase === 0.5)
    output = 'Third quarter';
  else if (moonPhase > 0.75)
    output = 'Waning crescent';

  return output;
  // a value of 0 corresponds to a new moon, 0.25 to a first quarter moon, 0.5 to a full moon, and 0.75 to a last quarter moon. (The ranges
  // in between these represent waxing crescent, waxing gibbous, waning gibbous, and waning crescent moons, respectively.)
}
function getDetails(dailyData) {
  const data = get(dailyData, 'data', []);

  const today = data[0];

  const output = {};

  output.summary = dailyData.summary;
  output.icon = dailyData.icon;
  output.humidity = today.humidity;
  output.visibility = today.visibility;
  output.uvIndex = today.uvIndex;
  output.sunriseTime = fecha.format(today.sunriseTime * 1000, 'shortTime');
  output.sunsetTime = fecha.format(today.sunsetTime * 1000, 'shortTime');
  output.moonphase = moonCalc(today.moonPhase);
  output.moonPhaseVal = today.moonPhase;
  output.windSpeed = today.windSpeed;
  output.pressure = today.pressure;

  return output;
}

function reduceWeather(body = '') {
  if (body === '') return {};
  const obj = {};
  const { currently, daily, hourly } = body;
  const today = daily.data[0];

  const outCurrent = {};

  outCurrent.icon = get(currently, 'icon');
  outCurrent.temperature = get(currently, 'temperature');
  outCurrent.summary = get(currently, 'summary');
  outCurrent.precip = get(currently, 'precipProbability');
  outCurrent.precipType = get(currently, 'precipType');
  outCurrent.tempMax = get(today, 'temperatureMax');
  outCurrent.tempMin = get(today, 'temperatureMin');
  outCurrent.windBearing = get(today, 'windBearing');
  outCurrent.windBearingRead = toCompass(get(today, 'windBearing'));

  const forcastToday = getTodaysForcast(hourly);
  const dailyForecast = getDailyForcast(daily);
  const details = getDetails(daily);

  obj.currently = outCurrent;
  obj.forcastToday = forcastToday;
  obj.dailyForecast = dailyForecast;
  obj.details = details;
  obj.time = get(currently, 'time');

  return obj;
}

module.exports = { reduceWeather };

//
/*
moonPhase optional, only on daily
The fractional part of the lunation number during the given day: a value of 0 corresponds to a new moon, 0.25 to a first quarter moon, 0.5 to a full moon, and 0.75 to a last quarter moon. (The ranges in between these represent waxing crescent, waxing gibbous, waning gibbous, and waning crescent moons, respectively.)

 */
