###
# Copyright (c) 2016, Santiago Gil
# Copyright (c) 2020, oddluck <oddluck@riseup.net>
#
#     This program is free software: you can redistribute it and/or modify
#     it under the terms of the GNU General Public License as published by
#     the Free Software Foundation, either version 3 of the License, or
#     (at your option) any later version.
#
#     This program is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#     GNU General Public License for more details.
#
#     You should have received a copy of the GNU General Public License
#     along with this program.  If not, see <http://www.gnu.org/licenses/>.
###

import supybot.utils as utils
from supybot.commands import *
import supybot.plugins as plugins
import supybot.ircutils as ircutils
import supybot.callbacks as callbacks
import json
import urllib.request
import pendulum
import requests

try:
    from supybot.i18n import PluginInternationalization

    _ = PluginInternationalization("NHL")
except ImportError:
    # Placeholder that allows to run the plugin on a bot
    # without the i18n module
    _ = lambda x: x


class NHL(callbacks.Plugin):
    """Get scores from NHL.com."""

    def __init__(self, irc):
        self.__parent = super(NHL, self)
        self.__parent.__init__(irc)

        self._SCOREBOARD_ENDPOINT = (
            "https://statsapi.web.nhl.com/api/v1/schedule?startDate={}&endDate={}"
            + "&expand=schedule.teams,schedule.linescore,schedule.broadcasts.all,schedule.ticket,schedule.game.content.media.epg"
            + "&leaderCategories=&site=en_nhl&teamId="
        )
        # https://statsapi.web.nhl.com/api/v1/schedule?startDate=2016-12-15&endDate=2016-12-15
        # &expand=schedule.teams,schedule.linescore,schedule.broadcasts,schedule.ticket,schedule.game.content.media.epg
        # &leaderCategories=&site=en_nhl&teamId=

        self._FUZZY_DAYS = [
            "yesterday",
            "tonight",
            "today",
            "tomorrow",
            "sun",
            "mon",
            "tue",
            "wed",
            "thu",
            "fri",
            "sat",
        ]

        # These two variables store the latest data acquired from the server
        # and its modification time. It's a one-element cache.
        # They are used to employ HTTP's 'If-Modified-Since' header and
        # avoid unnecessary downloads for today's information (which will be
        # requested all the time to update the scores).
        self._today_scores_cached_url = None
        self._today_scores_last_modified_time = None
        self._today_scores_last_modified_data = None

        self._TEAMS_BY_TRI = self._getTeams()

        # pendulum.set_formatter('alternative')

    def nhl(self, irc, msg, args, optional_team, optional_date):
        """[<team>] [<date>]
        Get games for a given date (YYYY-MM-DD). If none is specified, return games
        scheduled for today. Optionally add team abbreviation to filter
        for a specific team."""

        # Check to see if there's optional input and if there is check if it's
        # a date or a team, or both.
        tz = None
        if optional_team is None:
            team = "all"
            if optional_date:
                if "--tz" in optional_date:
                    tz = optional_date.split()[2]
                    optional_date = optional_date.split()[0]
            try:
                date = self._checkDateInput(optional_date)
                # print("1")
            except ValueError as e:
                irc.reply("ERROR: {0!s}".format(e))
                return
        else:
            if optional_team == "--tz":
                tz = optional_date
                team = "all"
                date = None
            else:
                date = self._checkDateInput(optional_team)
                # print("2")
                if date:  # and len(date) != 3:
                    team = "all"
                #                 elif date and len(date) == 3:
                #                     team = date
                #                     date = None
                else:
                    team = optional_team.upper()
                    try:
                        date = self._checkDateInput(optional_date)
                        # print("3")
                    except ValueError as e:
                        irc.reply("ERROR: {0!s}".format(e))
                        return

        if date is None:
            if not tz:
                tz = "US/Eastern"
            games = self._getTodayGames(team, tz)
            games_string = self._resultAsString(games)
            if not games_string:
                irc.reply("No games found for {}".format(team))
                return
            try:
                tdate = pendulum.from_format(games[0], "YYYY-MM-DD").strftime(
                    "%m/%d/%y"
                )
                games_string_date = ircutils.bold(tdate + ": ")
            except:
                games_string_date = ""
            # print(games[1]['clock'], games[1]['ended'])
            if len(games) == 2:
                if not games[1]["ended"]:
                    broadcasts = games[1]["broadcasts"]
                    games_string += " [{}]".format(broadcasts)
            # print(games)
            irc.reply(games_string_date + games_string)
        else:
            games = self._getGamesForDate(team, date)
            games_string = self._resultAsString(games)
            # print(games_string)
            if games_string == "":
                irc.reply("No games found for {}".format(team))
                return
            try:
                tdate = pendulum.from_format(games[0], "YYYY-MM-DD").strftime(
                    "%m/%d/%y"
                )
                games_string_date = ircutils.bold(tdate + ": ")
            except:
                games_string_date = ""
            if len(games) == 1:
                if not games[1]["ended"]:
                    try:
                        broadcasts = games[1]["broadcasts"]
                        games_string += " [{}]".format(broadcasts)
                    except:
                        pass
            # irc.reply(games_string)
            irc.reply(games_string_date + games_string)

    nhl = wrap(
        nhl, [optional("somethingWithoutSpaces"), optional("somethingWithoutSpaces")]
    )

    def _getTeams(self):

        url = "https://statsapi.web.nhl.com/api/v1/teams"
        try:
            data = requests.get(url)
            data = json.loads(data.content)
            data = data["teams"]
        except:
            return None

        teams = []
        for team in data:
            teams.append(team["abbreviation"])
        return teams

    def nhltv(self, irc, msg, args, optional_team, optional_date):
        """[<team>] [<date>]
        Get television broadcasts for a given date (YYYY-MM-DD). If none is specified, return broadcasts
        scheduled for today. Optionally add team abbreviation to filter
        for a specific team."""

        # Check to see if there's optional input and if there is check if it's
        # a date or a team, or both.
        if optional_team is None:
            team = "all"
            try:
                date = self._checkDateInput(optional_date)
            except ValueError as e:
                irc.reply("ERROR: {0!s}".format(e))
                return
        else:
            date = self._checkDateInput(optional_team)
            if date:
                team = "all"
            else:
                team = optional_team.upper()
                try:
                    date = self._checkDateInput(optional_date)
                except ValueError as e:
                    irc.reply("ERROR: {0!s}".format(e))
                    return

        if date is None:
            games = self._getTodayTV(team)
            games_string = self._resultTVAsString(games)
            try:
                tdate = pendulum.from_format(games[0], "YYYY-MM-DD").strftime(
                    "%m/%d/%y"
                )
                games_string_date = ircutils.bold(tdate + ": ")
            except:
                games_string_date = ""
            # print(games[0]['clock'], games[0]['ended'])
            if len(games) == 1:
                if not games[1]["ended"]:
                    broadcasts = games[1]["broadcasts"]
                    games_string += " [{}]".format(broadcasts)
            irc.reply(games_string_date + games_string)
        else:
            games = self._getTVForDate(team, date)
            if isinstance(games, str):
                irc.reply(games)
                return
            games_string = self._resultTVAsString(games)
            try:
                tdate = pendulum.from_format(games[0], "YYYY-MM-DD").strftime(
                    "%m/%d/%y"
                )
                games_string_date = ircutils.bold(tdate + ": ")
            except:
                games_string_date = ""
            if len(games) == 1:
                if not games[1]["ended"]:
                    try:
                        broadcasts = games[1]["broadcasts"]
                        games_string += " [{}]".format(broadcasts)
                    except:
                        pass
            # irc.reply(games_string)
            irc.reply(games_string_date + games_string)

        # if date is None:
        #    irc.reply(self._getTodayTV(team))
        # else:
        #    irc.reply(self._getTVForDate(team, date))

    nhltv = wrap(
        nhltv, [optional("somethingWithoutSpaces"), optional("somethingWithoutSpaces")]
    )

    def _getTodayGames(self, team, tz="US/Eastern"):
        games = self._getGames(team, self._getTodayDate(), tz)
        return games

    def _getGamesForDate(self, team, date):
        # print(date)
        games = self._getGames(team, date)
        return games

    def _getTodayTV(self, team):
        games = self._getGames(team, self._getTodayDate())
        return games

    def _getTVForDate(self, team, date):
        # print(date)
        games = self._getGames(team, date)
        return games

    ############################
    # Content-getting helpers
    ############################
    def _getGames(self, team, date, tz="US/Eastern"):
        """Given a date, populate the url with it and try to download its
        content. If successful, parse the JSON data and extract the relevant
        fields for each game. Returns a list of games."""
        url = self._getEndpointURL(date)

        # (If asking for today's results, enable the 'If-Mod.-Since' flag)
        use_cache = date == self._getTodayDate()
        # use_cache = False
        response = self._getURL(url, use_cache)
        if isinstance(response, str):
            return "ERROR: Something went wrong, check input"

        json = self._extractJSON(response)
        games = self._parseGames(json, team, tz)
        return games

    def _getEndpointURL(self, date):
        return self._SCOREBOARD_ENDPOINT.format(date, date)

    def _getURL(self, url, use_cache=False):
        """Use urllib to download the URL's content. The use_cache flag enables
        the use of the one-element cache, which will be reserved for today's
        games URL. (In the future we could implement a real cache with TTLs)."""
        user_agent = (
            "Mozilla/5.0                       (X11; Ubuntu; Linux x86_64; rv:45.0)    "
            "                   Gecko/20100101 Firefox/45.0"
        )
        header = {"User-Agent": user_agent}
        response = None

        # ('If-Modified-Since' to avoid unnecessary downloads.)
        if use_cache and self._haveCachedData(url):
            header["If-Modified-Since"] = self._today_scores_last_modified_time

        request = urllib.request.Request(url, headers=header)
        # print(url)

        try:
            response = urllib.request.urlopen(request)
        except urllib.error.HTTPError as error:
            if use_cache and error.code == 304:  # Cache hit
                self.log.info(
                    "{} - 304(Last-Modified: {})".format(
                        url, self._cachedDataLastModified()
                    )
                )
                return self._cachedData()
            else:
                self.log.error("HTTP Error ({}): {}".format(url, error.code))
                pass

        self.log.info("{} - 200".format(url))

        if not response:
            return "ERROR: Something went wrong, check input"

        if not use_cache:
            return response.read()

        # Updating the cached data:
        self._updateCache(url, response)
        return self._cachedData()

    def _extractJSON(self, body):
        return json.loads(body)

    def _parseGames(self, json, team, tz="US/Eastern"):
        """Extract all relevant fields from NHL.com's json
        and return a list of games."""
        games = []
        if json["totalGames"] == 0:
            return games
        games.append(json["dates"][0]["date"])
        for g in json["dates"][0]["games"]:
            # print(g)
            # Starting times are in UTC. By default, we will show Eastern times.
            # (In the future we could add a user option to select timezones.)
            tbd_check = self._ISODateToEasternTime(g["gameDate"])
            # print(tbd_check)
            if "3:00 AM" in tbd_check:
                starting_time = "TBD"
                # starting_time_TBD = True
            else:
                if "US/Eastern" not in tz:
                    starting_time = self._convertISODateToTime(g["gameDate"], tz)
                else:
                    starting_time = self._ISODateToEasternTime(g["gameDate"])
            broadcasts = []
            try:
                for item in g["broadcasts"]:
                    broadcasts.append(item["name"])
            except:
                pass
            # print(broadcasts)
            game_info = {
                "home_team": g["teams"]["home"]["team"]["abbreviation"],
                "away_team": g["teams"]["away"]["team"]["abbreviation"],
                "home_score": g["teams"]["home"]["score"],
                "away_score": g["teams"]["away"]["score"],
                "broadcasts": "{}".format(", ".join(item for item in broadcasts)),
                "starting_time": starting_time,
                "starting_time_TBD": g["status"]["startTimeTBD"],
                "pregame": (
                    True if "Pre-Game" in g["status"]["detailedState"] else False
                ),
                "period": g["linescore"]["currentPeriod"],
                "clock": g["linescore"].get("currentPeriodTimeRemaining"),
                "powerplay_h": g["linescore"]["teams"]["home"]["powerPlay"],
                "powerplay_a": g["linescore"]["teams"]["away"]["powerPlay"],
                "goaliePulled_h": g["linescore"]["teams"]["home"]["goaliePulled"],
                "goaliePulled_a": g["linescore"]["teams"]["away"]["goaliePulled"],
                "ended": (
                    g["status"]["statusCode"] == "7" or g["status"]["statusCode"] == "9"
                ),
                "ppd": (g["status"]["statusCode"] == "9"),
                "type": g["gameType"],
            }
            # print(game_info)
            if team == "all":
                games.append(game_info)
            else:
                if team in game_info["home_team"] or team in game_info["away_team"]:
                    games.append(game_info)
                else:
                    pass
        return games

    ############################
    # Today's games cache
    ############################
    def _cachedData(self):
        return self._today_scores_last_modified_data

    def _haveCachedData(self, url):
        return (self._today_scores_cached_url == url) and (
            self._today_scores_last_modified_time is not None
        )

    def _cachedDataLastModified(self):
        return self._today_scores_last_modified_time

    def _updateCache(self, url, response):
        self._today_scores_cached_url = url
        self._today_scores_last_modified_time = response.headers["last-modified"]
        self._today_scores_last_modified_data = response.read()

    ############################
    # Formatting helpers
    ############################
    def _resultAsString(self, games):
        if len(games) == 0:
            return "No games found"
        else:
            s = sorted(games[1:], key=lambda k: k["ended"])  # , reverse=True)
            # s = [self._gameToString(g) for g in games]
            b = []
            for g in s:
                b.append(self._gameToString(g))
            # print(b)
            # print(' | '.join(b))
            # games_strings = [self._gameToString(g) for g in games]
            return " | ".join(b)

    def _resultTVAsString(self, games):
        if len(games) == 0:
            return "No games found"
        else:
            s = sorted(games[1:], key=lambda k: k["ended"])  # , reverse=True)
            # s = [self._gameToString(g) for g in games]
            b = []
            for g in s:
                b.append(self._TVToString(g))
            # print(b)
            # print(' | '.join(b))
            # games_strings = [self._gameToString(g) for g in games]
            return " | ".join(b)

    def _TVToString(self, game):
        """Given a game, format the information into a string according to the
        context. For example:
        "MEM @ CLE 07:00 PM ET" (a game that has not started yet),
        "HOU 132 GSW 127 F OT2" (a game that ended and went to 2 overtimes),
        "POR 36 LAC 42 8:01 Q2" (a game in progress)."""
        away_team = game["away_team"]
        home_team = game["home_team"]
        if game["period"] == 0:  # The game hasn't started yet
            starting_time = (
                game["starting_time"] if not game["starting_time_TBD"] else "TBD"
            )
            starting_time = (
                ircutils.mircColor("PPD", "red") if game["ppd"] else starting_time
            )
            return "{} @ {} {} [{}]".format(
                away_team, home_team, starting_time, ircutils.bold(game["broadcasts"])
            )

        # The game started => It has points:
        away_score = game["away_score"]
        home_score = game["home_score"]

        away_string = "{} {}".format(away_team, away_score)
        home_string = "{} {}".format(home_team, home_score)

        # Highlighting 'powerPlay':
        if (
            game["powerplay_h"]
            and game["clock"].upper() != "END"
            and game["clock"].upper() != "FINAL"
            and not game["goaliePulled_h"]
        ):
            home_string = ircutils.mircColor(
                home_string, "orange"
            )  # 'black', 'yellow')
        if (
            game["powerplay_a"]
            and game["clock"].upper() != "END"
            and game["clock"].upper() != "FINAL"
            and not game["goaliePulled_a"]
        ):
            away_string = ircutils.mircColor(
                away_string, "orange"
            )  # 'black', 'yellow')

        # Highlighting an empty net (goalie pulled):
        if (
            game["goaliePulled_h"]
            and game["clock"].upper() != "END"
            and game["clock"].upper() != "FINAL"
            and game["clock"] != "00:00"
        ):
            home_string = ircutils.mircColor(home_string, "red")
        if (
            game["goaliePulled_a"]
            and game["clock"].upper() != "END"
            and game["clock"].upper() != "FINAL"
            and game["clock"] != "00:00"
        ):
            away_string = ircutils.mircColor(away_string, "red")

        # Bold for the winning team:
        if int(away_score) > int(home_score):
            away_string = ircutils.bold(away_string)
        elif int(home_score) > int(away_score):
            home_string = ircutils.bold(home_string)

        # print('got here ', game['broadcasts'])

        base_str = ""
        if not game["ended"]:
            base_str = " [{}]".format(game["broadcasts"])

        game_string = "{} {} {}{}".format(
            away_string,
            home_string,
            self._clockBoardToString(
                game["clock"],
                game["period"],
                game["ended"],
                game["pregame"],
                game["type"],
            ),
            base_str,
        )

        return game_string

    def _gameToString(self, game):
        """Given a game, format the information into a string according to the
        context. For example:
        "MEM @ CLE 07:00 PM ET" (a game that has not started yet),
        "HOU 132 GSW 127 F OT2" (a game that ended and went to 2 overtimes),
        "POR 36 LAC 42 8:01 Q2" (a game in progress)."""
        away_team = game["away_team"]
        home_team = game["home_team"]
        if game["period"] == 0:  # The game hasn't started yet
            starting_time = (
                game["starting_time"] if not game["starting_time_TBD"] else "TBD"
            )
            starting_time = (
                ircutils.mircColor("PPD", "red") if game["ppd"] else starting_time
            )
            return "{} @ {} {}".format(away_team, home_team, starting_time)

        # The game started => It has points:
        away_score = game["away_score"]
        home_score = game["home_score"]

        away_string = "{} {}".format(away_team, away_score)
        home_string = "{} {}".format(home_team, home_score)

        # Highlighting 'powerPlay':
        if (
            game["powerplay_h"]
            and game["clock"].upper() != "END"
            and game["clock"].upper() != "FINAL"
            and not game["goaliePulled_h"]
        ):
            home_string = ircutils.mircColor(
                home_string, "orange"
            )  # 'black', 'yellow')
        if (
            game["powerplay_a"]
            and game["clock"].upper() != "END"
            and game["clock"].upper() != "FINAL"
            and not game["goaliePulled_a"]
        ):
            away_string = ircutils.mircColor(
                away_string, "orange"
            )  # 'black', 'yellow')

        # Highlighting an empty net (goalie pulled):
        if (
            game["goaliePulled_h"]
            and game["clock"].upper() != "END"
            and game["clock"].upper() != "FINAL"
            and game["clock"] != "00:00"
        ):
            home_string = ircutils.mircColor(home_string, "red")
        if (
            game["goaliePulled_a"]
            and game["clock"].upper() != "END"
            and game["clock"].upper() != "FINAL"
            and game["clock"] != "00:00"
        ):
            away_string = ircutils.mircColor(away_string, "red")

        # Bold for the winning team:
        if int(away_score) > int(home_score):
            away_string = ircutils.bold(away_string)
        elif int(home_score) > int(away_score):
            home_string = ircutils.bold(home_string)

        game_string = "{} {} {}".format(
            away_string,
            home_string,
            self._clockBoardToString(
                game["clock"],
                game["period"],
                game["ended"],
                game["pregame"],
                game["type"],
            ),
        )

        return game_string

    def _clockBoardToString(self, clock, period, game_ended, pregame=None, gType=None):
        """Get a string with current period and, if the game is still
        in progress, the remaining time in it."""
        period_number = period
        # Game hasn't started => There is no clock yet.
        if period_number == 0:
            return ""

        # Halftime
        # if period:
        #    return ircutils.mircColor('Halftime', 'orange')

        period_string = self._periodToString(period_number, gType)

        # Game finished:
        if game_ended or clock.upper() == "FINAL":
            if period_number == 3:
                return ircutils.mircColor("F", "red")
            else:
                return ircutils.mircColor("F/{}".format(period_string), "red")

        # Game in progress:
        if clock.upper() == "END":
            return ircutils.mircColor("End {}".format(period_string), "light blue")
        else:
            # Period in progress, show clock:
            if pregame:
                return "{}".format(ircutils.mircColor("Pre-Game", "green"))
            return "{}{}".format(
                clock + " " if clock != "00:00" else "",
                ircutils.mircColor(period_string, "green"),
            )

    def _periodToString(self, period, gType):
        """Get a string describing the current period in the game.
        period is an integer counting periods from 1 (so 5 would be OT1).
        The output format is as follows: {Q1...Q4} (regulation);
        {OT, OT2, OT3...} (overtimes)."""
        if period <= 3:
            return "P{}".format(period)

        ot_number = period - 3
        if ot_number == 1:
            return "OT"
        # if regular/pre season game, we have shootouts
        if gType == "R" or gType == "PR":
            if ot_number > 1:
                return "SO"
        return "{}OT".format(ot_number)

    ############################
    # Date-manipulation helpers
    ############################
    def _getTodayDate(self):
        """Get the current date formatted as "YYYYMMDD".
        Because the API separates games by day of start, we will consider and
        return the date in the Pacific timezone.
        The objective is to avoid reading future games anticipatedly when the
        day rolls over at midnight, which would cause us to ignore games
        in progress that may have started on the previous day.
        Taking the west coast time guarantees that the day will advance only
        when the whole continental US is already on that day."""
        today = self._pacificTimeNow().date()
        today_iso = today.isoformat()
        return today_iso  # .replace('-', '')

    def _easternTimeNow(self):
        return pendulum.now("US/Eastern")

    def _pacificTimeNow(self):
        return pendulum.now("US/Pacific")

    def _convertISODateToTime(self, iso, target="US/Eastern"):
        """Convert the ISO date in UTC time that the API outputs into a
        time (target timezone) formatted with am/pm. Defaults to US/Eastern."""
        try:
            date = pendulum.parse(iso).in_tz("{}".format(target))
        except:
            try:
                target = self._checkTarget(target)
                date = pendulum.parse(iso).in_tz("{}".format(target))
            except:
                date = pendulum.parse(iso).in_tz("{}".format("US/Eastern"))
        time = date.format("h:mm A zz")
        return "{}".format(time)

    def _checkTarget(self, target):
        """check input among common tz"""
        target = target.upper()
        common = {
            "CT": "US/Central",
            "CDT": "US/Central",
            "CST": "US/Central",
            "MT": "US/Mountain",
            "MDT": "US/Mountain",
            "MST": "US/Mountain",
            "PT": "US/Pacific",
            "PDT": "US/Pacific",
            "PST": "US/Pacific",
            "ET": "US/Eastern",
            "EDT": "US/Eastern",
            "EST": "US/Eastern",
            "CENTRAL": "US/Central",
            "EASTERN": "US/Eastern",
            "PACIFIC": "US/Pacific",
            "MOUNTAIN": "US/Mountain",
        }
        if target in common:
            target = common[target]

        return target

    def _ISODateToEasternTime(self, iso):
        """Convert the ISO date in UTC time that the API outputs into an
        Eastern time formatted with am/pm. (The default human-readable format
        for the listing of games)."""
        date = pendulum.parse(iso).in_tz("{}".format("US/Eastern"))
        time = date.format("h:mm A zz")
        return "{}".format(time)  # Strip the seconds

    def _stripDateSeparators(self, date_string):
        return date_string.replace("-", "")

    def _EnglishDateToDate(self, date):
        """Convert a human-readable like 'yesterday' to a datetime object
        and return a 'YYYYMMDD' string."""
        if date == "lastweek":
            day_delta = -7
        elif date == "yesterday":
            day_delta = -1
        elif date == "today" or date == "tonight":
            day_delta = 0
        elif date == "tomorrow":
            day_delta = 1
        elif date == "nextweek":
            day_delta = 7
        elif date[:3] == "sun":
            date_string = (
                pendulum.now("US/Pacific").next(pendulum.SUNDAY).format("YYYY-MM-DD")
            )
            return date_string
        elif date[:3] == "mon":
            date_string = (
                pendulum.now("US/Pacific").next(pendulum.MONDAY).format("YYYY-MM-DD")
            )
            return date_string
        elif date[:3] == "tue":
            date_string = (
                pendulum.now("US/Pacific").next(pendulum.TUESDAY).format("YYYY-MM-DD")
            )
            return date_string
        elif date[:3] == "wed":
            date_string = (
                pendulum.now("US/Pacific").next(pendulum.WEDNESDAY).format("YYYY-MM-DD")
            )
            return date_string
        elif date[:3] == "thu":
            date_string = (
                pendulum.now("US/Pacific").next(pendulum.THURSDAY).format("YYYY-MM-DD")
            )
            return date_string
        elif date[:3] == "fri":
            date_string = (
                pendulum.now("US/Pacific").next(pendulum.FRIDAY).format("YYYY-MM-DD")
            )
            return date_string
        elif date[:3] == "sat":
            date_string = (
                pendulum.now("US/Pacific").next(pendulum.SATURDAY).format("YYYY-MM-DD")
            )
            return date_string
        # Calculate the day difference and return a string
        date_string = self._pacificTimeNow().add(days=day_delta).strftime("%Y-%m-%d")
        return date_string

    def _checkDateInput(self, date):
        """Verify that the given string is a valid date formatted as
        YYYY-MM-DD. Also, the API seems to go back until 2014-10-04, so we
        will check that the input is not a date earlier than that."""

        error_string = "Incorrect date format, should be YYYY-MM-DD"

        if date is None:
            return None

        if date in self._FUZZY_DAYS:
            date = self._EnglishDateToDate(date)
        elif date[:3].lower() in self._FUZZY_DAYS:
            date = self._EnglishDateToDate(date.lower())

        if date.isdigit():
            try:
                date = pendulum.from_format(date, "YYYYMMDD").strftime("%Y-%m-%d")
            except:
                raise ValueError("Incorrect date format, should be YYYY-MM-DD")
        elif date.replace("-", "").isdigit():
            try:
                parsed_date = pendulum.from_format(date, "YYYY-MM-DD")
            except:
                raise ValueError("Incorrect date format, should be YYYY-MM-DD")
        elif date.replace("/", "").isdigit():
            if len(date.split("/")) == 2:
                year = "/" + str(pendulum.datetime.now().year)
                date += year
            elif len(date.split("/")) == 3:
                if len(date.split("/")[2]) == 2:
                    date = "{}/{}/{}".format(
                        date.split("/")[0],
                        date.split("/")[1],
                        "20{}".format(date.split("/")[2]),
                    )
            else:
                raise ValueError("Incorrect date format, should be YYYY-MM-DD")
            try:
                date = pendulum.from_format(date, "MM/DD/YYYY").strftime("%Y-%m-%d")
            except:
                raise ValueError("Incorrect date format, should be YYYY-MM-DD")
        elif "-" not in date and date.isdigit() == False and len(date) > 3:
            if date.title() in [
                "Sunday",
                "Monday",
                "Tuesday",
                "Wednesday",
                "Thursday",
                "Friday",
                "Saturday",
            ]:
                return "Incorrect date format, should be YYYY-MM-DD"
            try:
                date = date.title()
                year = str(pendulum.datetime.now().year)
                date += year
                try:
                    date = pendulum.from_format(date, "DDMMMYYYY").strftime("%Y-%m-%d")
                except:
                    date = pendulum.from_format(date, "MMMDDYYYY").strftime("%Y-%m-%d")
            except:
                raise ValueError("Incorrect date format, should be YYYY-MM-DD")
                # return "Incorrect date format, should be YYYY-MM-DD"
        else:
            return None

        return date


Class = NHL

# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79:
