<!-- eslint-disable indent -->
<template>
  <div class="schedule-view">

    <div class="centerDiv">
      <div class="row">
        <h1>Season {{ seasonNumber }} Schedule</h1>
      </div>

      <div class="row">
        <div class="col-sm-7">
          <div class="row">
            <h2 id="week-num">Week {{ selectedWeekNumber }}</h2>
          </div>
          <!-- Matchups -->
          <div class="row">
            <div v-for="(matchup, index) in gamesGroupedByMatchup" :key="index" class="col-sm-auto">
              <div class="table-responsive-sm" style="text-align: center">
                <table class="table table-sm table-striped">
                  <thead class="thead-dark">
                    <tr>
                      <th style="width: 3rem">Away</th>
                      <th style="width: 5rem">Score</th>
                      <th style="width: 3rem">Home</th>
                    </tr>
                  </thead>
                  <tbody id="matchup-1">
                    <tr v-for="game in matchup" :key="game.id">
                      <td>
                        <RouterLink
                          :to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: game.away_team.abbrev } }"
                          :style="{ 'font-weight': game.away_score > game.home_score ? 'bold' : 'normal' }">
                          {{ game.away_team.abbrev }}
                        </RouterLink>
                      </td>
                      <td>
                        <RouterLink v-if="game.away_score || game.home_score"
                          :to="{ name: 'games', params: { seasonNumber: seasonNumber, weekNumber: selectedWeekNumber, gameNumber: game.game_num, team1Abbreviation: game.away_team.abbrev, team2Abbreviation: game.home_team.abbrev } }">
                          {{ `${game.away_score}-${game.home_score}` }}
                        </RouterLink>
                        <template v-else>@</template>
                      </td>
                      <td>
                        <RouterLink
                          :to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: game.home_team.abbrev } }"
                          :style="{ 'font-weight': game.home_score > game.away_score ? 'bold' : 'normal' }">
                          {{ game.home_team.abbrev }}
                        </RouterLink>
                      </td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </div>
          </div>
          <!-- Week Buttons -->
          <div class="row">
            <div class="col-sm">
              <button v-if="selectedWeekNumber > 1" class="btn btn-outline-primary m-1"
                @click="$router.push({ name: 'schedule', params: { seasonNumber: seasonNumber, weekNumber: selectedWeekNumber - 1 } })">
                &lt;&lt; Week {{ selectedWeekNumber - 1 }}
              </button>
              <button class="btn btn-primary m-1">
                Week {{ selectedWeekNumber }}
              </button>
              <!-- TODO might want to do regular season week + post season week amount here -->
              <button v-if="selectedWeekNumber < 21" class="btn btn-outline-primary m-1"
                @click="$router.push({ name: 'schedule', params: { seasonNumber: seasonNumber, weekNumber: selectedWeekNumber + 1 } })">
                Week {{ selectedWeekNumber + 1 }} &gt;&gt;
              </button>
            </div>
          </div>
        </div>
        <div class="col-sm-5">
          <div class="row">
            <div>
              <h2>Season Schedule</h2>
            </div>
          </div>
          <div class="row">
            <div class="table-responsive-xl">
              <table class="table table-sm table-striped">
                <thead class="thead-dark">
                  <tr>
                    <th>Week</th>
                    <th>Start Date</th>
                    <th>End Date</th>
                    <th>Notes</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="week in scheduleWeeks" :key="week.weekNumber">
                    <td>
                      <RouterLink
                        :to="{ name: 'schedule', params: { seasonNumber: seasonNumber, weekNumber: week.weekNumber } }">
                        Week {{ week.weekNumber }}
                      </RouterLink>
                    </td>
                    <td>{{ week.weekStart }}</td>
                    <td>{{ week.weekEnd }}</td>
                    <td>{{ week.weekSpecialInfo }}</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import type { Game } from '@/services/apiResponseTypes'
import { type LeagueInfo, fetchCurrentLeagueInfo } from '@/services/currentService'
import { CHRISTMAS, CURRENT_SEASON, SEASON_START_DATE, THANKSGIVING } from '@/services/utilities'
import { fetchGamesBySeasonAndWeek } from '@/services/gameService'
import dayjs from 'dayjs'
import customParseFormat from 'dayjs/plugin/customParseFormat'
dayjs.extend(customParseFormat)

interface ScheduleWeekRow {
  weekNumber: number
  weekStart: string
  weekEnd: string
  weekSpecialInfo: string
}

export default {
  name: 'ScheduleView',
  data() {
    return {
      currentWeekNumber: 0,
      weekGames: [] as Game[]
    }
  },
  props: {
    seasonNumber: { type: Number, default: CURRENT_SEASON },
    weekNumber: { type: Number, required: false }
  },
  created() {
    this.fetchCurrentWeekNumber()
    this.fetchData()
  },
  computed: {
    selectedWeekNumber(): number {
      if (this.weekNumber || this.weekNumber === 0) return this.weekNumber
      return this.currentWeekNumber
    },
    gamesGroupedByMatchup(): Game[][] {
      if (!this.weekGames.length) return []

      const groupedGames = this.weekGames.reduce((storage, game) => {
        const key = [game.home_team.abbrev, game.away_team.abbrev].sort().join('-')
        if (storage[key]) {
          storage[key].push(game)
        } else {
          storage[key] = [game]
        }
        return storage
      }, {} as { [key: string]: Game[] })

      return Object.values(groupedGames)
    },
    scheduleWeeks(): ScheduleWeekRow[] {
      const schedule = []
      let currentWeekStartDate = SEASON_START_DATE

      for (let week = 1; week <= 21; week++) {
        const weekStartDate = currentWeekStartDate
        const weekEndDate = this.isLongSeries(weekStartDate)
          ? currentWeekStartDate.add(13, 'd')
          : currentWeekStartDate.add(6, 'd')

        schedule.push({
          weekNumber: week,
          weekStart: weekStartDate.format('MM/DD/YYYY'),
          weekEnd: weekEndDate.format('MM/DD/YYYY'),
          weekSpecialInfo: this.weekSpecialInfo(week)
        })

        currentWeekStartDate = weekEndDate.add(1, 'd')
      }

      return schedule
    }
  },
  watch: {
    seasonNumber(newValue, oldValue) {
      if (newValue !== oldValue)
        this.fetchData()
    },
    selectedWeekNumber(newValue, oldValue) {
      if (newValue !== oldValue)
        this.fetchData()
    }
  },
  methods: {
    async fetchCurrentWeekNumber(): Promise<void> {
      const leagueInfo: LeagueInfo = await fetchCurrentLeagueInfo()
      this.currentWeekNumber = leagueInfo.week
    },
    async fetchData(): Promise<void> {
      this.weekGames = await fetchGamesBySeasonAndWeek(this.seasonNumber, this.selectedWeekNumber)
    },
    isLongSeries(weekStartDate: dayjs.Dayjs): boolean {
      // current 18-week schedule has 2 week series for any game week that falls 
      // on the week of Thanksgiving or Christmas
      return Math.abs(weekStartDate.diff(THANKSGIVING, 'days')) < 6
        || Math.abs(weekStartDate.diff(CHRISTMAS, 'days')) < 6
    },
    weekSpecialInfo(weekNumber: number): string {
      if (weekNumber === 1) return 'Spring Begins'
      if (weekNumber === 6) return 'Summer Begins'
      if (weekNumber === 14) return 'Trade Deadline'
      if (weekNumber === 15) return 'Fall Begins'
      if (weekNumber === 18) return 'Regular Season Ends'
      if (weekNumber === 19) return 'Division Series - Best of 5'
      if (weekNumber === 20) return 'League Championship Series - Best of 7'
      if (weekNumber === 21) return 'World Series Best of 7'

      return ''
    }
  }
}
</script>