/////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////
// Convert a date token to local
// date range to UTC for server
// dataListView consumption
//
export default {
  ///////////////////////////////
  // token to date range
  //
  tokenToDates: function(token) {
    if (token == null || token.length == 0) {
      throw new Error(
        "relative-date-filter-calculator: date token is null or empty"
      );
    }

    //return object contains the two dates that encompass the time period
    //the token represents to the local browser time zone but in UTC
    //and iso8601 format

    //NOTE: it's valid for one of the two ret values might be undefined as it's valid to have a single date for
    //Past or Future
    const ret = { after: undefined, before: undefined };
    const dtNow = window.$gz.DateTime.local();
    const dtToday = window.$gz.DateTime.local(
      dtNow.year,
      dtNow.month,
      dtNow.day
    );
    let dtAfter = null;
    let dtBefore = null;

    switch (token) {
      case "*yesterday*":
        //Between Day before yesterday at midnight and yesterday at midnight
        ret.after = dtToday
          .plus({ days: -1, seconds: -1 })
          .toUTC()
          .toString();
        ret.before = dtToday.toUTC().toString();
        break;

      case "*today*":
        //Between yesterday at midnight and tommorow at midnight
        ret.after = dtToday
          .plus({ seconds: -1 })
          .toUTC()
          .toString();
        ret.before = dtToday
          .plus({ days: 1 })
          .toUTC()
          .toString();
        break;

      case "*tomorrow*":
        //Between Tonight at midnight and day after tommorow at midnight
        ret.after = dtToday
          .plus({ days: 1, seconds: -1 })
          .toUTC()
          .toString();
        ret.before = dtToday
          .plus({ days: 2 })
          .toUTC()
          .toString();
        break;

      case "*lastweek*":
        //Between two Sundays ago at midnight and last sunday at midnight

        //go back a week
        dtAfter = dtToday.plus({ days: -7 });
        //go backwards to Sunday (In Luxon Monday is 1, Sunday is 7)
        while (dtAfter.weekday != 7) {
          dtAfter = dtAfter.plus({ days: -1 });
        }
        //go to very start of eighth dayahead
        dtBefore = dtAfter.plus({ days: 8 });
        //remove a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });
        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*thisweek*":
        //Between Sunday at midnight and Next sunday at midnight

        //Start with today
        dtAfter = dtToday;
        //SET dtAfter to Monday start of this week
        //go backwards to monday (In Luxon Monday is 1, Sunday is 7)
        while (dtAfter.weekday != 1) {
          dtAfter = dtAfter.plus({ days: -1 });
        }
        //Now go back to sunday last second
        dtAfter = dtAfter.plus({ seconds: -1 });

        //Start with today
        dtBefore = dtToday;

        //SET dtBefore to next monday
        //is it monday now?
        if (dtBefore.weekday == 1) {
          //Monday today? then go to next monday
          dtBefore = dtBefore.plus({ days: 7 });
        } else {
          //Find next monday...
          while (dtBefore.weekday != 1) {
            dtBefore = dtBefore.plus({ days: 1 });
          }
        }
        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*nextweek*":
        //Between Next Sunday at midnight and Next Next sunday at midnight

        //Start with today
        dtAfter = dtToday;
        //If today is monday skip over it first, we're looking for *next* monday, not this one
        if (dtAfter.weekday == 1) {
          dtAfter = dtAfter.plus({ days: 1 });
        }

        //go forwards to next monday 12:00am (In Luxon Monday is 1, Sunday is 7)
        while (dtAfter.weekday != 1) {
          dtAfter = dtAfter.plus({ days: 1 });
        }
        //Now go back to sunday last second
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set dtBefore 7 days ahead of dtAfter
        //(sb BEFORE two mondays from now at zero hour so need to add a second due to prior removal of a second to make sunday)
        dtBefore = dtAfter.plus({ days: 7, seconds: 1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*lastmonth*":
        //start with the first day of this month
        dtAfter = window.$gz.DateTime.local(dtNow.year, dtNow.month, 1);
        //subtract a Month
        dtAfter = dtAfter.plus({ months: -1 });
        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });
        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*thismonth*":
        //start with the first day of this month
        dtAfter = window.$gz.DateTime.local(dtNow.year, dtNow.month, 1);
        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });
        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*nextmonth*":
        //start with the first day of this month
        dtAfter = window.$gz.DateTime.local(dtNow.year, dtNow.month, 1);

        //add a month
        dtAfter = dtAfter.plus({ months: 1 });

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*14daywindow*":
        //Start with today
        dtAfter = dtToday;

        //subtract 7 days
        dtAfter = dtAfter.plus({ days: -7 });

        //Add 15 days to dtAfter to get end date
        dtBefore = dtAfter.plus({ days: 15 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*past*":
        //Any time before Now
        //set return values from calculated values
        ret.after = undefined;
        ret.before = dtNow.toUTC().toString();
        break;

      case "*future*":
        //Any time after Now
        //set return values from calculated values
        ret.after = dtNow.toUTC().toString();
        ret.before = undefined;
        break;

      case "*lastyear*":
        //"last year" means prior calendar year from start of january to end of december
        //start with the first day of this year
        dtAfter = window.$gz.DateTime.local(dtNow.year);

        //subtract a year
        dtAfter = dtAfter.plus({ years: -1 });

        //Before zero hour january 1st this year
        dtBefore = window.$gz.DateTime.local(dtNow.year);

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*thisyear*":
        //From zero hour january 1 this year (minus a second) to zero hour jan 1 next year
        //start with the first day of this year
        dtAfter = window.$gz.DateTime.local(dtNow.year);

        //Before zero hour january 1st next year
        dtBefore = window.$gz.DateTime.local(dtNow.year);
        dtBefore = dtBefore.plus({ years: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*last3months*":
        //From Now minus 3 months
        dtAfter = dtToday.plus({ months: -3 });

        //Before now
        dtBefore = dtNow;

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*last6months*":
        //From Now minus 6 months
        dtAfter = dtToday.plus({ months: -6 });

        //Before now
        dtBefore = dtNow;

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*pastyear*": //within the prior 365 days before today
        //From Now minus 365 days
        dtAfter = dtToday.plus({ days: -365 });

        //Before now
        dtBefore = dtNow;

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*past90days*":
        //From Now minus 90 days
        dtAfter = dtNow.plus({ days: -90 });

        //Before now
        dtBefore = dtNow;

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*past30days*":
        //From Now minus 30 days
        dtAfter = dtNow.plus({ days: -30 });

        //Before now
        dtBefore = dtNow;

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*past7days*":
        //From Now minus 7 days
        dtAfter = dtNow.plus({ days: -7 });

        //Before now
        dtBefore = dtNow;

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*past24hours*":
        //From Now minus 24 hours
        dtAfter = dtNow.plus({ hours: -24 });

        //Before now
        dtBefore = dtNow;

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*past6hours*":
        //From Now minus 6 hours
        dtAfter = dtNow.plus({ hours: -6 });

        //Before now
        dtBefore = dtNow;

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;
      ///////////////////////////////////////////////////////////////////////////
      case "*january*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 1, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*february*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 2, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*march*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 3, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*april*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 4, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*may*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 5, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*june*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 6, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*july*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 7, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*august*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 8, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*september*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 9, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*october*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 10, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*november*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 11, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*december*":
        //This year specific month (month is 1 based)
        dtAfter = window.$gz.DateTime.local(dtNow.year, 12, 1);

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*lastyearlastmonth*":
        //start with the first day of this month
        dtAfter = window.$gz.DateTime.local(dtNow.year, dtNow.month, 1);
        //subtract a Year and a Month
        dtAfter = dtAfter.plus({ years: -1, months: -1 });
        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });
        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*lastyearthismonth*":
        //start with the first day of this month
        dtAfter = window.$gz.DateTime.local(dtNow.year, dtNow.month, 1);
        //subtract a Year
        dtAfter = dtAfter.plus({ years: -1 });
        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });
        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      case "*lastyearnextmonth*":
        //start with the first day of this month
        dtAfter = window.$gz.DateTime.local(dtNow.year, dtNow.month, 1);

        //subtract a year, add a month
        dtAfter = dtAfter.plus({ years: -1, months: 1 });

        //Add one month to dtAfter to get end date
        dtBefore = dtAfter.plus({ months: 1 });

        //move after back a second for boundary
        dtAfter = dtAfter.plus({ seconds: -1 });

        //set return values from calculated values
        ret.after = dtAfter.toUTC().toString();
        ret.before = dtBefore.toUTC().toString();
        break;

      default:
        throw new Error(
          "relative-date-time-filter-calculater: Date token [" +
            token +
            "] was not recognized"
        );
      //--------------------------
    }

    return ret;
  }
};
