<template>
  <div class="player-view">
    <div class="centerDiv">
      <!-- Heading -->
      <div class="row">
        <div class="col-sm">
          <h1 id="player-name">{{ playerName }}{{ injuryReturnDate }}</h1>
          <h2 v-if="isCurrentPlayer" id="player-wara">{{ player?.wara }} sWAR</h2>
        </div>

        <div v-if="isCurrentPlayer" class="col-sm-1">
          <RouterLink v-if="teamAbbreviation && teamThumbnail"
            :to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: teamAbbreviation } }">
            <img id="thumbnail" height="125" style="float:right; vertical-align:middle; max-height:100%;"
              :src="teamThumbnail">
          </RouterLink>
        </div>
      </div>

      <div v-if="isCurrentPlayer" class="row">
        <div class="col-sm-auto">
          <img style="max-height:485px; max-width: 100%;" id="team-image" :src="playerImageUrl" :alt="playerName">
          <p><a id="bbref-link" target="_blank" :href="baseballReferenceUrl">Baseball Reference Page</a></p>
        </div>

        <div class="col-sm-auto">
          <img v-if="playerCardImage1Url" style="max-height:485px; max-width: 100%;" id="card-image"
            :src="playerCardImage1Url">
          <img v-if="playerCardImage2Url" style="max-height:485px; max-width: 100%;" id="card-image"
            :src="playerCardImage2Url">
        </div>
      </div>

      <!-- Summary -->
      <div v-if="isCurrentPlayer" class="row" id="batter-summary">
        <div class="col-sm-12">
          <h3>Summary</h3>
        </div>
        <PlayerBattingSummaryTable v-if="isBatter" :current-season-batting="currentSeasonBatting"
          :current-post-season-batting="currentPostSeasonBatting"
          :regular-season-batting-stats="regularSeasonBattingStats" />
        <PlayerPitchingSummaryTable v-else :current-season-pitching="currentSeasonPitching"
          :current-post-season-pitching="currentPostSeasonPitching"
          :regular-season-pitching-stats="regularSeasonPitchingStats" />
        <!-- Injury rating + last 2 app -->
        <div class="col-sm-4">
          <div class="table-responsive-xl" style="max-width:20rem">
            <table class="table table-sm table-striped">
              <thead class="thead-dark">
                <tr>
                  <th>Inj</th>
                  <th v-if="lastAppearance">Last App</th>
                  <th v-if="secondLastAppearance">2nd Last App</th>
                </tr>
              </thead>
              <tbody id="batter-summary-helper">
                <tr>
                  <td>{{ injuryRating }}</td>
                  <td v-if="lastAppearance">{{ lastAppearance }}</td>
                  <td v-if="secondLastAppearance">{{ secondLastAppearance }}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <!-- Last 4 Games -->
        <LastFourGamesBattingTable v-if="isBatter" :last4-games-batting="last4GamesBatting"
          :last4-games-fielding="last4GamesFielding" />
        <LastFourGamesPitchingTable v-else :last4-games-pitching="last4GamesPitching" />
      </div>

      <!-- Career Stats -->
      <PlayerCareerBattingTable v-if="isBatter" :regular-season-batting-stats="regularSeasonBattingStats"
        :post-season-batting-stats="postSeasonBattingStats" />
      <PlayerCareerPitchingTable :regular-season-pitching-stats="regularSeasonPitchingStats"
        :post-season-pitching-stats="postSeasonPitchingStats" />
      <PlayerCareerBattingTable v-if="!isBatter" :regular-season-batting-stats="regularSeasonBattingStats"
        :post-season-batting-stats="postSeasonBattingStats" />
      <PlayerCareerFieldingTable :regular-season-fielding-stats="regularSeasonFieldingStats"
        :post-season-fielding-stats="postSeasonFieldingStats" />

      <!-- Transactions and awards -->
      <div v-if="transactions.length || awards.length" class="row" id="transactions-row">
        <div v-if="transactions.length" class="col-sm-6">
          <h3>Transactions</h3>
          <div class="table-responsive-xl" style="max-width:35rem">
            <table class="table table-sm table-striped" id="transactions">
              <thead class="thead-dark">
                <tr>
                  <th>Season</th>
                  <th>Week</th>
                  <th>Player</th>
                  <th>Old Team</th>
                  <th>New Team</th>
                </tr>
              </thead>
              <tbody id="transactions-table">
                <tr v-for="transaction in transactions">
                  <td>{{ transaction.season }}</td>
                  <td>{{ transaction.week }}</td>
                  <td>{{ transaction.player.name }}</td>
                  <td>{{ transaction.oldteam.sname }}</td>
                  <td>{{ transaction.newteam.sname }}</td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>

        <div v-if="awards.length" class="col-sm-6" id="awards-row">
          <h3>Awards</h3>
          <div class="table-responsive-xl" style="max-width:40rem">
            <table class="table table-sm table-striped" id="table-awards">
              <thead class="thead-dark">
                <tr>
                  <th>Season</th>
                  <th>Award</th>
                  <th>Recipient</th>
                  <th>Extras</th>
                </tr>
              </thead>
              <tbody id="team-awards">
                <tr v-for="award in awards">
                  <td>{{ award.season }}</td>
                  <td>{{ award.name }}</td>
                  <td>{{ award.player?.name }}</td>
                  <td>
                    <RouterLink v-if="award.team"
                      :to="{ name: 'team', params: { seasonNumber: award.team.season, teamAbbreviation: award.team.abbrev } }">
                      {{ award.team.sname }}
                    </RouterLink>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { isDiscordAuthenticated } from '@/services/authenticationService'
import { fetchLast2DecisionsByPlayerId, type Decision } from '@/services/decisionsService'
import { type Player, fetchPlayerByName } from '@/services/playersService'
import { fetchBattingStatsBySeasonAndPlayerId, fetchBattingStatsForLastFourGamesBySeasonAndPlayerId, type BattingStat } from '@/services/battingStatsService'
import { CURRENT_SEASON, isNotUndefined } from '@/services/utilities'
import LastFourGamesBattingTable from '@/components/LastFourGamesBattingTable.vue'
import LastFourGamesPitchingTable from '@/components/LastFourGamesPitchingTable.vue'
import PlayerCareerBattingTable from '@/components/PlayerCareerBattingTable.vue'
import PlayerCareerPitchingTable from '@/components/PlayerCareerPitchingTable.vue'
import PlayerCareerFieldingTable from '@/components/PlayerCareerFieldingTable.vue'
import PlayerBattingSummaryTable from '@/components/PlayerBattingSummaryTable.vue'
import PlayerPitchingSummaryTable from '@/components/PlayerPitchingSummaryTable.vue'
import { fetchPitchingStatsBySeasonAndPlayerId, fetchPitchingStatsForLastFourGamesBySeasonAndPlayerId, type PitchingStat } from '@/services/pitchingStatsService'
import { fetchFieldingStatsBySeasonAndPlayerId, fetchFieldingStatsForLastFourGamesBySeasonAndPlayerId, type FieldingStat } from '@/services/fieldingStatsService'
import { fetchTransactionsForCurrentSeasonByPlayerName, type Transaction } from '@/services/transactionsService'
import { fetchAwardsByPlayerName, type Award } from '@/services/awardsService'

export default {
  name: "PlayerView",
  data() {
    return {
      isAuthenticated: false as Boolean,
      player: undefined as Player | undefined,
      last2Decisions: [] as Decision[],
      // Batting stats
      regularSeasonBattingStats: [] as BattingStat[],
      postSeasonBattingStats: [] as BattingStat[],
      last4GamesBatting: [] as BattingStat[],
      // Pitching stats
      regularSeasonPitchingStats: [] as PitchingStat[],
      postSeasonPitchingStats: [] as PitchingStat[],
      last4GamesPitching: [] as PitchingStat[],
      // Fielding stats
      regularSeasonFieldingStats: [] as FieldingStat[],
      postSeasonFieldingStats: [] as FieldingStat[],
      last4GamesFielding: [] as FieldingStat[],

      // Transactions and Awards
      transactions: [] as Transaction[],
      awards: [] as Award[]
    }
  },
  components: {
    PlayerBattingSummaryTable,
    PlayerCareerBattingTable,
    LastFourGamesBattingTable,
    PlayerPitchingSummaryTable,
    PlayerCareerPitchingTable,
    LastFourGamesPitchingTable,
    PlayerCareerFieldingTable
  },
  props: {
    seasonNumber: { type: Number, required: true },
    playerName: { type: String, required: true }
  },
  computed: {
    playerSeasonNumber(): number | undefined {
      return this.player?.season
    },
    isCurrentPlayer(): boolean {
      return this.seasonNumber === this.playerSeasonNumber
    },
    // TODO use to determine order of stats to display
    isBatter(): boolean {
      return !this.player?.pos_1.includes('P')
    },
    teamAbbreviation(): string | undefined {
      return this.player?.team?.abbrev
    },
    teamThumbnail(): string | undefined {
      return this.player?.team?.thumbnail
    },
    baseballReferenceUrl(): string | undefined {
      if (!this.player?.bbref_id)
        return undefined
      const firstChar = this.player.bbref_id.slice(0, 1)
      return `https://www.baseball-reference.com/players/${firstChar}/${this.player.bbref_id}.shtml`
    },
    playerImageUrl(): string | undefined {
      return this.player?.vanity_card ?? this.teamThumbnail
    },
    playerCardImage1Url(): string | undefined {
      if (!this.isAuthenticated)
        return undefined
      return this.player?.image
    },
    playerCardImage2Url(): string | undefined {
      if (!this.isAuthenticated)
        return undefined
      return this.player?.image2
    },
    injuryReturnDate(): string | undefined {
      if (!this.player?.il_return)
        return undefined
      return ` 🏥 (${this.player.il_return})`
    },
    injuryRating(): string | undefined {
      return this.player?.injury_rating
    },
    currentSeasonBatting(): BattingStat | undefined {
      if (!this.regularSeasonBattingStats.length)
        return undefined
      return this.regularSeasonBattingStats.find(stat => stat.player.season === CURRENT_SEASON)
    },
    currentPostSeasonBatting(): BattingStat | undefined {
      if (!this.postSeasonBattingStats.length)
        return undefined
      return this.postSeasonBattingStats.find(stat => stat.player.season === CURRENT_SEASON)
    },
    currentSeasonPitching(): PitchingStat | undefined {
      if (!this.regularSeasonPitchingStats.length)
        return undefined
      return this.regularSeasonPitchingStats.find(stat => stat.player.season === CURRENT_SEASON)
    },
    currentPostSeasonPitching(): PitchingStat | undefined {
      if (!this.postSeasonPitchingStats.length)
        return undefined
      return this.postSeasonPitchingStats.find(stat => stat.player.season === CURRENT_SEASON)
    },
    lastAppearance(): string | undefined {
      if (!this.last2Decisions?.length)
        return undefined
      if (this.last2Decisions.length <= 0)
        return undefined
      return this.formatDecisionToAppearance(this.last2Decisions[0])
    },
    secondLastAppearance(): string | undefined {
      if (!this.last2Decisions?.length)
        return undefined
      if (this.last2Decisions.length <= 1)
        return '-'
      return this.formatDecisionToAppearance(this.last2Decisions[1])
    }
  },
  created() {
    this.fetchData()
  },
  watch: {
    seasonNumber(newValue, oldValue) {
      if (newValue !== oldValue)
        this.fetchData()
    },
    playerName(newName, oldName) {
      if (newName !== oldName)
        this.fetchData()
    }
  },
  methods: {
    async fetchData(): Promise<void> {
      this.isAuthenticated = await isDiscordAuthenticated()
      this.player = await this.tryFetchPlayerByNameForAnySeason(this.seasonNumber, this.playerName)
      if (!this.player)
        return
      this.last2Decisions = await fetchLast2DecisionsByPlayerId(this.seasonNumber, this.player.id)
      this.last4GamesBatting = await fetchBattingStatsForLastFourGamesBySeasonAndPlayerId(this.seasonNumber, this.player.id)
      this.last4GamesPitching = await fetchPitchingStatsForLastFourGamesBySeasonAndPlayerId(this.seasonNumber, this.player.id)
      this.last4GamesFielding = await fetchFieldingStatsForLastFourGamesBySeasonAndPlayerId(this.seasonNumber, this.player.id)

      // TODO: this should change, either with an api that can take a player name for every season, a way
      // to get multiple seasons stats at once, or a players ids across all seasons at once
      const playerSeasons = await Promise.all(Array.from(Array(CURRENT_SEASON), (element, index) => index + 1).map(seasonNumber => fetchPlayerByName(seasonNumber, this.player!.name)))
      this.regularSeasonBattingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchBattingStatsBySeasonAndPlayerId(player!.season, player!.id, true)))).filter(isNotUndefined)
      this.postSeasonBattingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchBattingStatsBySeasonAndPlayerId(player!.season, player!.id, false)))).filter(isNotUndefined)
      this.regularSeasonPitchingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchPitchingStatsBySeasonAndPlayerId(player!.season, player!.id, true)))).filter(isNotUndefined)
      this.postSeasonPitchingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchPitchingStatsBySeasonAndPlayerId(player!.season, player!.id, false)))).filter(isNotUndefined)
      this.regularSeasonFieldingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchFieldingStatsBySeasonAndPlayerId(player!.season, player!.id, true)))).flatMap(stat => stat).filter(isNotUndefined)
      this.postSeasonFieldingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchFieldingStatsBySeasonAndPlayerId(player!.season, player!.id, false)))).flatMap(stat => stat).filter(isNotUndefined)

      this.transactions = await fetchTransactionsForCurrentSeasonByPlayerName(this.player.name)
      this.awards = await fetchAwardsByPlayerName(this.player.name)
    },
    async tryFetchPlayerByNameForAnySeason(seasonNumber: number, playerName: string): Promise<Player | undefined> {
      do {
        const player: Player | undefined = await fetchPlayerByName(seasonNumber, playerName)
        if (player)
          return player
        seasonNumber--
      } while (seasonNumber > 0)
    },
    formatDecisionToAppearance(decision: Decision): string {
      return `${decision.rest_ip.toFixed(1)}IP w${decision.week}g${decision.game_num}`
    }
  }
}
</script>
