<template>
  <img alt="" class="bg-img" src="">

  <div class="wrapper">
    <div class="container">
      <div class="card mb-3 bg-transparent border-0">
        <div class="row g-0">
          <div class="img-container col-md-2 pt-3">
            <img
                :class="data.tracked ? 'tracked' : ''"
                :src="constructAvatarUrl(store.state.playerDetails.avatar, 'full')"
                :title="data.tracked ? 'Tracked' : ''"
                alt="Player avatar"
                class="img-fluid avatar">
          </div>
          <div class="col-md-8 d-flex">
            <div class="card-body">
              <h3 class="card-title"><a
                  :href="/^\d{17}$/.test(props.id) ? 'https://steamcommunity.com/profiles/' + props.id : 'https://steamcommunity.com/id/' + props.id"
                  class="text-decoration-none text-white"
                  target="_blank"
                  title="Open steam profile">{{
                  store.state.playerDetails.name
                }}
                <i class="fa fa-external-link"></i>
              </a></h3>
              <table class="table table-borderless text-center">
                <tr>
                  <th class="wlt-win text-uppercase text-muted">Wins</th>
                  <th class="wlt-loss text-uppercase text-muted">Losses</th>
                  <th class="wlt-tie text-uppercase text-muted">Ties</th>
                  <th class="wlt-win-rate text-uppercase text-muted">Win-Rate</th>
                  <th class="wlt-tie-rate text-uppercase text-muted">Tie-Rate</th>
                </tr>
                <tr>
                  <td class="wlt-win">{{ data.match_stats.win }}</td>
                  <td class="wlt-loss">{{ data.match_stats.loss }}</td>
                  <td class="wlt-tie">{{ data.match_stats.tie }}</td>
                  <td class="wlt-win-rate">{{
                      data.match_stats.win > 0 ? (data.match_stats.win / data.match_stats.total * 100).toFixed(0) : 0
                    }}%
                  </td>
                  <td class="wlt-tie-rate">{{
                      data.match_stats.tie > 0 ? (data.match_stats.tie / data.match_stats.total * 100).toFixed(0) : 0
                    }}%
                  </td>
                </tr>
              </table>
              <div class="badges">
                <img v-if="store.state.playerDetails.vac"
                     :title="'VAC-Ban: ' + FormatVacDate(store.state.playerDetails.vac_date, store.state.matchDetails.date)"
                     alt="Vac banned"
                     src="../assets/images/icons/vac_banned.svg">
                <img v-if="store.state.playerDetails.game_ban"
                     :title="'Game-Ban: ' + FormatVacDate(store.state.playerDetails.game_ban_date, store.state.matchDetails.date)"
                     alt="Game banned"
                     src="../assets/images/icons/game_banned.svg">
              </div>
            </div>
            <div v-if="!data.tracked" class="dropdown trackme-btn">
              <button
                  id="login-dropdown"
                  aria-expanded="false"
                  class="btn border-2 btn-outline-info"
                  data-bs-toggle="dropdown"
                  type="button"
              >
                Track Me!
              </button>
              <div v-if="data.statusErrorCode === 202" class="alert alert-success" role="alert">
                {{ data.statusError }}
              </div>
              <div v-if="data.statusErrorCode === 418" class="alert alert-warning" role="alert">
                {{ data.statusError }}
              </div>
              <div v-if="data.statusErrorCode !== 0 && data.statusErrorCode !== 202 && data.statusErrorCode !== 418"
                   class="alert alert-danger"
                   role="alert">
                {{ data.statusError }}
              </div>
              <div aria-labelledby="login-dropdown" class="dropdown-menu mt-2 border-2 border-primary bg-body"
                   style="width: 320px">
                <form class="px-4 py-3">
                  <!-- AuthCode input -->
                  <div class="form-outline mb-4">
                    <input id="track-authcode" v-model="data.userData.authcode" class="form-control bg-secondary"
                           placeholder="AuthCode*"
                           required type="text"/>
                  </div>

                  <!-- ShareCode input -->
                  <div class="form-outline mb-2">
                    <input id="track-sharecode" v-model="data.userData.sharecode" class="form-control bg-secondary"
                           placeholder="ShareCode"
                           type="text"/>
                  </div>

                  <div class="form-outline mb-4">
                    <small>You can find your AuthCode and ShareCode <a
                        href="https://help.steampowered.com/en/wizard/HelpWithGameIssue/?appid=730&issueid=128"
                        target="_blank">here</a>.</small>
                  </div>

                  <!-- Submit button -->
                  <button class="btn btn-outline-warning border-2" type="submit"
                          @click.prevent="TrackPlayer">
                    TrackMe
                  </button>
                </form>
              </div>
            </div>
            <div v-if="data.tracked" class="refresh-btn" title="Refresh Match-List" @click="RefreshData">
              <i class="fa fa-refresh fa-2x"></i>
            </div>
          </div>
        </div>
      </div>
      <div class="match-container d-flex">
        <div class="matches">

          <MatchesTable v-if="store.state.playerDetails.matches" :matches="store.state.playerDetails.matches"/>
          <h5 v-else>No matches on record</h5>

        </div>

        <div v-if="store.state.playerDetails.matches" class="side-info">
          <div v-if="data.playerMeta.most_mates" class="side-info-box most-played-with">
            <div class="heading">
              <h5>Most played with</h5>
            </div>
            <hr>
            <ul v-for="mate in data.playerMeta.most_mates" :key="mate.player.steamid64" class="list-unstyled">
              <li @click="GoToPlayer(mate.player.vanity_url || mate.player.steamid64)">
                <span class="start">
                  <img :class="mate.player.tracked ? 'tracked' : ''" :src="constructAvatarUrl(mate.player.avatar)"
                       :title="mate.player.tracked ? 'Tracked' : ''" alt="Player avatar">
                  <span class="text">{{ mate.player.name }}</span>
                </span>
                <span class="end">
                  {{ mate.total }}
                </span>
              </li>
            </ul>
          </div>
          <div v-if="data.playerMeta.best_mates" class="side-info-box best-mate">
            <div class="heading">
              <h5>Best Mate <span class="text-muted">(by winrate)</span></h5>
            </div>
            <hr>
            <ul v-for="mate in data.playerMeta.best_mates" :key="mate.player.steamid64" class="list-unstyled">
              <li @click="GoToPlayer(mate.player.vanity_url || mate.player.steamid64)">
                <span class="start">
                  <img :class="mate.player.tracked ? 'tracked' : ''" :src="constructAvatarUrl(mate.player.avatar)"
                       :title="mate.player.tracked ? 'Tracked' : ''" alt="Player avatar">
                  <span class="text">{{ mate.player.name }}</span>
                </span>
                <span class="end">
                  {{ (mate.win_rate * 100).toFixed(0) }} %
                <span v-if="mate.total" class="total text-muted">({{ mate.total }})</span>
                </span>
              </li>
            </ul>
          </div>
          <div v-if="data.playerMeta.eq_map && data.playerMeta.weapon_dmg" class="side-info-box preferred-weapons">
            <div class="heading">
              <h5>Weapons <span class="text-muted">(by dmg)</span></h5>
            </div>
            <hr>
            <ul v-for="(id, key) in data.best_weapons" :key="id[0]" class="list-unstyled">
              <li>
                <span class="start">
                  <span class="text">{{ id[0] }}</span>
                </span>
                <span :title="id[0] + ' - ' + id[1] + ' dmg'" class="end">
                  <span :class="'dmg-chart-' + key">
                    {{ id[1] }}
                  </span>
                </span>
              </li>
            </ul>
            {{ setDmgGraphWidth() }}
          </div>
          <div v-if="data.playerMeta.win_maps" class="side-info-box best-map">
            <div class="heading">
              <h5>Best Map <span class="text-muted">(by winrate)</span></h5>
            </div>
            <hr>
            <ul v-for="map in data.best_maps" :key="map[0]" class="list-unstyled">
              <li>
                <span class="start">
                  <img :src="require('../assets/images/map_icons/map_icon_' + map[0] + '.svg')" alt="Player avatar">
                  <span class="text">{{ FixMapName(map[0]) }}</span>
                </span>
                <span class="end">
                  {{ (map[1] * 100).toFixed(0) }} %
                <span v-if="data.playerMeta.total_maps[map[0]]"
                      class="total text-muted">({{ data.playerMeta.total_maps[map[0]] }})</span>
                </span>
              </li>
            </ul>
          </div>
        </div>
      </div>
      <div class="load-more col-lg-9 col-md-12 text-center">
        <button v-if="data.match_stats.total !== data.matches.length" :key="scrollToPos(store.state.scroll_state)"
                class="btn border-2 btn-outline-info" @click="setMoreMatches">Load More
        </button>
      </div>
    </div>
  </div>
</template>

<script>
import {onBeforeMount, onBeforeUnmount, onMounted, reactive, ref, watch} from "vue";
import {useStore} from "vuex";
import {
  constructAvatarUrl,
  DisplayRank,
  FixMapName,
  FormatVacDate,
  GetPlayerMeta,
  GetUser,
  GetWinLoss,
  GoToLink,
  GoToPlayer,
  LoadImage,
  LoadMoreMatches,
  MatchNotParsedTime,
  SaveLastVisitedToLocalStorage, scrollToPos,
  setTitle,
  sortObjectValue,
  TrackMe
} from "../utils";
import {FOOTER_HEIGHT, NAV_HEIGHT} from "@/constants";
import MatchesTable from "@/components/MatchesTable";

export default {
  name: 'Player',
  components: {MatchesTable},
  props: ['id'],
  setup(props) {
    // Variables
    const store = useStore()

    const displayCounter = 3

    const data = reactive({
      userData: {
        authcode: '',
        sharecode: ''
      },
      tracked: false,
      matches: [],
      statusError: '',
      statusErrorCode: 0,
      match_stats: {
        loss: 0,
        win: 0,
        tie: 0,
        total: 0
      },
      playerMeta: {},
      best_maps: [],
      best_weapons_tmp: [],
      best_weapons: []
    })

    onBeforeMount(() => {
          if (Object.entries(store.state.playerDetails).length === 0) {
            GetPlayer()
          } else {
            console.log(store.state.playerDetails)
            SetPlayerData()
          }
        }
    )

    const SetPlayerData = async () => {
      await store.commit('changeScrollState', 0)

      data.tracked = store.state.playerDetails.tracked
      if (store.state.playerDetails.matches)
        data.matches = store.state.playerDetails.matches
      if (store.state.playerDetails.match_stats) {
        data.match_stats.loss = store.state.playerDetails.match_stats.loss || 0
        data.match_stats.win = store.state.playerDetails.match_stats.win || 0
        data.match_stats.tie = store.state.playerDetails.match_stats.tie || 0
        data.match_stats.total = data.match_stats.loss + data.match_stats.win + data.match_stats.tie
      }

      store.commit({
        type: 'changeId64',
        id: store.state.playerDetails.steamid64
      })
      store.commit({
        type: 'changeVanityUrl',
        id: store.state.playerDetails.vanity_url || ''
      })

      if (store.state.playerDetails.matches) {
        if (data.matches[0].map) {
          await LoadImage(data.matches[0].map)
        } else if (!data.matches[0].map && MatchNotParsedTime(data.matches[0].date) && data.matches[1].map) {
          await LoadImage(data.matches[1].map)
        } else {
          await LoadImage('random')
        }
      }

      let player = {
        'steamid64': store.state.playerDetails.steamid64,
        'vanity_url': store.state.playerDetails.vanity_url || '',
        'name': store.state.playerDetails.name,
        'avatar': constructAvatarUrl(store.state.playerDetails.avatar, 'medium')
      }
      SaveLastVisitedToLocalStorage(player)

      setTitle(store.state.playerDetails.name)
    }

    const GetPlayer = async (reset = false) => {
      if (props.id) {
        const [res, resData] = await GetUser(props.id)

        if (res === 200 && resData) {
          if (resData.steamid64 !== store.state.playerDetails.steamid64 || reset) {
            store.commit('resetPlayerDetails')
            store.commit({
              type: 'changePlayerDetails',
              data: resData
            })
          }

          await SetPlayerData()

          console.log(store.state.playerDetails)
        } else {
          GoToLink('/')
          // TODO: needs 404
        }
      } else {
        GoToLink('/')
        // TODO: needs 404
      }
    }

    const setMoreMatches = async () => {
      const res = await LoadMoreMatches(store.state.playerDetails.steamid64, data.matches[data.matches.length - 1].date)

      await res.matches.forEach(e => data.matches.push(e))

      scrollToPos(window.scrollY)

      console.log(store.state.playerDetails)
    }

    const RefreshData = async () => {
      const refreshButton = document.querySelector('.refresh-btn .fa')
      refreshButton.classList.add('fa-spin')
      refreshButton.classList.add('fa-fw')
      refreshButton.classList.remove('fa-refresh')
      refreshButton.classList.add('fa-spinner')

      await GetPlayer(true).then(() => {
        setTimeout(() => {
          refreshButton.classList.remove('fa-spin')
          refreshButton.classList.remove('fa-fw')
          refreshButton.classList.add('fa-refresh')
          refreshButton.classList.remove('fa-spinner')
        }, 2000)
      })

      data.playerMeta = await GetPlayerMeta(props.id, displayCounter)
    }

    const TrackPlayer = async () => {
      if (data.userData.authcode !== '') {
        [data.statusErrorCode, data.statusError] = await TrackMe(store.state.playerDetails.steamid64, data.userData.authcode, data.userData.sharecode)

        if (data.statusErrorCode === 202) {
          data.statusErrorCode = 0
          data.statusError = ''
          data.tracked = true
        } else {
          setTimeout(() => {
            data.statusError = ''
            data.statusErrorCode = 0
          }, 5000)
        }
      }
    }

    const mapWeaponDamage = () => {
      if (data.playerMeta.eq_map && data.playerMeta.weapon_dmg) {
        Object.keys(data.playerMeta.eq_map).forEach((key) => {
          for (const id in data.playerMeta.weapon_dmg) {
            Object.keys(data.playerMeta.weapon_dmg[id]).forEach((k) => {
              if (k === 'eq') {
                if (data.playerMeta.weapon_dmg[id][k] === key * 1) {
                  data.best_weapons_tmp.push([data.playerMeta.eq_map[key], data.playerMeta.weapon_dmg[id]['dmg']])
                }
              }
            })
          }
        })

        data.best_weapons_tmp.sort((a, b) => {
          return b[1] - a[1]
        })

        data.best_weapons = data.best_weapons_tmp
        data.best_weapons_tmp = []
      }
    }

    const setDmgGraphWidth = () => {
      setTimeout(() => {
        let weaponsContainer
        const dmg100 = ref(0)
        const dmg = ref(0)

        for (let i = 0; i <= 4; i++) {
          weaponsContainer = document.querySelector('.dmplayerMetag-chart-' + i)
          if (weaponsContainer !== null) {
            if (i === 0) {
              dmg100.value = weaponsContainer.innerHTML * 1
              weaponsContainer.style.width = '100%'
            }

            dmg.value = weaponsContainer.innerHTML * 1
            weaponsContainer.style.width = dmg.value * 100 / dmg100.value + '%'
          }
        }
      }, 100)
    }

    watch(() => props.id, async () => {
      await GetPlayer()
      data.playerMeta = await GetPlayerMeta(props.id, displayCounter)
    })

    watch(() => data.playerMeta, () => {
      mapWeaponDamage()

      data.best_maps = sortObjectValue(data.playerMeta.win_maps, 'desc')

      if (data.best_maps.length > displayCounter)
        data.best_maps.splice(displayCounter, data.best_maps.length - displayCounter)
    })

    onMounted(async () => {
      const height = window.innerHeight - NAV_HEIGHT - FOOTER_HEIGHT
      const wrapper = document.querySelector('.wrapper')
      wrapper.style.minHeight = height + 'px'

      await GetPlayer()
      data.playerMeta = await GetPlayerMeta(props.id, displayCounter)
    })

    onBeforeUnmount(() => {
      store.commit('changeScrollState', window.scrollY)
    })

    return {
      data,
      store,
      props,
      TrackPlayer,
      RefreshData,
      TrackMe,
      GetWinLoss,
      DisplayRank,
      constructAvatarUrl,
      FormatVacDate,
      FixMapName,
      GoToPlayer,
      MatchNotParsedTime,
      setMoreMatches,
      setDmgGraphWidth,
      scrollToPos
    }
  }
}
</script>

<style lang="scss" scoped>
.bg-img {
  z-index: -1;
  position: fixed;
  width: 100%;
  height: 100%;
  object-fit: cover;
  overflow: hidden;
}

.wrapper {
  background: rgba(0, 0, 0, .7);

  .load-more {
    padding: 1rem 0;
  }

  .trackme-btn,
  .refresh-btn {
    position: absolute;
    right: 0;
    bottom: 0;
  }

  .refresh-btn {
    cursor: pointer;

    &:hover,
    &:focus {
      .fa-refresh {
        color: var(--bs-warning);
      }
    }

    .fa {
      font-size: 1.3rem;
    }
  }
}

.card {
  padding-top: 10px;

  .badges {
    height: 30px;

    img {
      width: auto;
      height: 100%;
      margin-right: 5px;
    }
  }

  .avatar {
    border-radius: 50%;
    height: 150px;
    width: 150px;
    box-shadow: 0 0 10px black;

    &.tracked {
      box-shadow: 0 0 20px 5px var(--bs-success);
    }
  }

  .fa {
    font-size: .75rem;
    vertical-align: top;
  }

  table {
    max-width: 500px;

    .wlt-win, .wlt-loss, .wlt-tie {
      text-align: start;
      max-width: 70px;
      margin: 0;
      padding: 0;
    }

    .wlt-tie-rate, .wlt-win-rate {
      text-align: end;
      max-width: 90px;
    }
  }
}

.match-container {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  gap: 1rem;

  .matches {
    width: 75%;
  }

  .side-info {
    display: flex;
    flex-direction: column;
    gap: 1rem;

    width: 25%;
    height: auto;
    margin-top: 30px;

    .side-info-box {
      width: 100%;
      height: auto;
      background: rgba(20, 20, 20, .8);
      border: 1px solid rgba(white, .3);
      border-radius: 5px;
    }

    .best-mate,
    .preferred-weapons,
    .most-played-with,
    .best-map {
      .heading {
        display: flex;
        align-items: center;
        justify-content: center;

        height: 30px;

        h5 {
          font-size: 1rem;
          margin: 0;
          padding: 0;
        }
      }

      hr {
        margin: 0 0 5px 0;
        border-color: rgba(white, .3);
      }

      ul li {
        line-height: 25px;
        font-size: .9rem;
        padding: 0 10px;
        margin: 5px 0;
        cursor: pointer;

        display: flex;
        justify-content: space-between;
        gap: 1rem;

        .start {
          width: 50%;

          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;

          .tracked {
            font-size: .8rem;
            margin-right: 5px;
          }

          img {
            width: 25px;
            height: 25px;
            border-radius: 50%;
            margin-right: 5px;
            margin-left: 5px;

            &.tracked {
              border: 2px solid var(--bs-success);
            }
          }
        }

        .end {
          display: flex;
          width: 45%;
          justify-content: flex-end;
          align-items: flex-end;
        }
      }
    }

    .best-map, .best-mate {
      ul li {
        .start {
          width: 75%;
        }

        .end {
          .total {
            padding-left: 5px;
          }
        }
      }
    }

    .preferred-weapons,
    .best-map {
      ul li {
        cursor: default;
      }
    }

    .preferred-weapons {
      .end {
        position: relative;

        @for $i from 0 through 3 {
          .dmg-chart-#{$i} {
            position: absolute;
            background: rgba(150, 50, 50, 1);
            border-radius: 15px;
            color: transparent;
            user-select: none;
            cursor: help;

            &:hover {
              background: rgba(220, 50, 50, 1);
            }
          }
        }
      }
    }
  }
}

@media screen and (max-width: 768px) {
  .card {
    .avatar {
      height: 75px !important;
      width: 75px !important;
    }
  }
  .trackme-btn,
  .refresh-btn {
    top: 25px;
  }

  .refresh-btn {
    &:hover,
    &:focus {
      .fa {
        color: white !important;
      }
    }
  }
}

@media screen and (max-width: 991px) {
  .matches {
    width: 100% !important;
  }
  .side-info {
    display: none !important;
  }
}
</style>
