<template>
  <section class="station_table" @scroll="onScroll" ref="tableRef">
    <Loading
      v-if="apiStore.dataStatuses.connection == Status.Loading && filteredStationList.length == 0"
    />

    <table v-else-if="filteredStationList.length > 0">
      <thead>
        <tr>
          <th
            v-for="headerName in headIds"
            :key="headerName"
            @click="changeSorter(headerName)"
            class="header-text"
            :class="headerName"
          >
            <div class="header_wrapper">
              <div v-html="$t(`sceneries.headers.${headerName}`)"></div>

              <img
                class="sort-icon"
                v-if="activeSorter.headerName == headerName"
                :src="`/images/icon-arrow-${activeSorter.dir == 1 ? 'asc' : 'desc'}.svg`"
                alt="sort icon"
              />
            </div>
          </th>

          <th
            v-for="headerName in headIconsIds"
            :key="headerName"
            @click="changeSorter(headerName)"
            class="header-image"
            :class="headerName"
          >
            <span
              class="header_wrapper"
              data-tooltip-type="BaseTooltip"
              :data-tooltip-content="$t(`sceneries.headers.${headerName}`)"
            >
              <img :src="`/images/icon-${headerName}.svg`" :alt="headerName" />

              <img
                class="sort-icon"
                v-if="activeSorter.headerName == headerName"
                :src="`/images/icon-arrow-${activeSorter.dir == 1 ? 'asc' : 'desc'}.svg`"
                alt="sort icon"
              />
            </span>
          </th>
        </tr>
      </thead>

      <tbody>
        <tr
          v-for="station in filteredStationList"
          class="a-row"
          tabindex="0"
          :key="station.name"
          @click.right.prevent="openForumSite($event, station.generalInfo?.url)"
          @click="getSceneryRoute(station)"
          @keydown.enter="getSceneryRoute(station)"
        >
          <td class="station-name" :class="station.generalInfo?.availability">
            <b v-if="station.generalInfo?.project" style="color: salmon">{{
              station.generalInfo.project
            }}</b>
            {{ station.name }}
          </td>

          <td class="station-level">
            <span v-if="station.generalInfo">
              <span
                v-if="
                  station.generalInfo.availability == 'default' ||
                  station.generalInfo.availability == 'nonDefault'
                "
                data-tooltip-type="BaseTooltip"
                :data-tooltip-content="`${$t(`sceneries.info.${station.generalInfo.availability}`)} (${$t(
                  'sceneries.info.req-level',
                  { lvl: station.generalInfo.reqLevel },
                  station.generalInfo.reqLevel
                )})`"
                :style="calculateExpStyle(station.generalInfo.reqLevel)"
              >
                {{ station.generalInfo.reqLevel >= 2 ? station.generalInfo.reqLevel : 'L' }}
              </span>

              <span
                v-else-if="station.generalInfo.availability == 'abandoned'"
                data-tooltip-type="BaseTooltip"
                :data-tooltip-content="$t('sceneries.info.abandoned')"
              >
                <img src="/images/icon-abandoned.svg" alt="non-public" />
              </span>

              <span
                v-else-if="station.generalInfo.availability == 'nonPublic'"
                data-tooltip-type="BaseTooltip"
                :data-tooltip-content="$t('sceneries.info.non-public')"
              >
                <img src="/images/icon-lock.svg" alt="non-public" />
              </span>

              <span
                v-else
                data-tooltip-type="BaseTooltip"
                :data-tooltip-content="$t('sceneries.info.unavailable')"
              >
                <img src="/images/icon-unavailable.svg" alt="unavailable" />
              </span>
            </span>

            <span
              v-else
              data-tooltip-type="BaseTooltip"
              :data-tooltip-content="$t('sceneries.info.unknown')"
            >
              ?
            </span>
          </td>

          <td class="station-status">
            <StationStatusBadge
              :isOnline="station.onlineInfo ? true : false"
              :dispatcherStatus="station.onlineInfo?.dispatcherStatus"
            />
          </td>

          <td class="station-dispatcher-name">
            <span v-if="station.onlineInfo?.dispatcherName">
              <b
                v-if="isCreator(station.onlineInfo.dispatcherName)"
                data-tooltip-type="CreatorTooltip"
                :data-tooltip-content="$t('donations.creator-message')"
              >
                <img src="/images/icon-creator.png" alt="creator icon" />
                <span class="text--creator">&nbsp;{{ station.onlineInfo.dispatcherName }}</span>
              </b>

              <b
                v-else-if="apiStore.donatorsData.includes(station.onlineInfo.dispatcherName)"
                data-tooltip-type="DonatorTooltip"
                :data-tooltip-content="$t('donations.dispatcher-message')"
              >
                <img src="/images/icon-diamond.svg" alt="donator diamond icon" />
                <span class="text--donator">&nbsp;{{ station.onlineInfo.dispatcherName }}</span>
              </b>

              <div v-else>
                {{ station.onlineInfo.dispatcherName }}
              </div>
            </span>
          </td>

          <td class="station-dispatcher-lang">
            <FlagIcon
              v-if="station.onlineInfo && station.onlineInfo.dispatcherLanguageId != -1"
              :language-id="station.onlineInfo.dispatcherLanguageId"
              width="2.25em"
            />
          </td>

          <td class="station-dispatcher-exp">
            <span
              v-if="station.onlineInfo && station.onlineInfo?.dispatcherExp != -1"
              :style="
                calculateExpStyle(
                  station.onlineInfo.dispatcherExp,
                  station.onlineInfo.dispatcherIsSupporter
                )
              "
            >
              {{ station.onlineInfo.dispatcherExp < 2 ? 'L' : station.onlineInfo.dispatcherExp }}
            </span>
          </td>

          <td class="station-tracks">
            <div v-if="station.generalInfo">
              <span
                v-if="station.generalInfo.routes.singleElectrifiedNames.length != 0"
                class="track catenary"
                data-tooltip-type="BaseTooltip"
                :data-tooltip-content="`${$t('sceneries.info.single-track-routes-catenary')}${
                  station.generalInfo.routes.singleElectrifiedNames.length
                }`"
              >
                {{ station.generalInfo.routes.singleElectrifiedNames.length }}
              </span>

              <span
                v-if="station.generalInfo.routes.singleOtherNames.length != 0"
                class="track no-catenary"
                data-tooltip-type="BaseTooltip"
                :data-tooltip-content="`${$t('sceneries.info.single-track-routes-other')}${
                  station.generalInfo.routes.singleOtherNames.length
                }`"
              >
                {{ station.generalInfo.routes.singleOtherNames.length }}
              </span>
            </div>
          </td>

          <td class="station-tracks">
            <div v-if="station.generalInfo">
              <span
                v-if="station.generalInfo.routes.doubleElectrifiedNames.length != 0"
                class="track catenary"
                data-tooltip-type="BaseTooltip"
                :data-tooltip-content="`${$t('sceneries.info.double-track-routes-catenary')}${
                  station.generalInfo.routes.doubleElectrifiedNames.length
                }`"
              >
                {{ station.generalInfo.routes.doubleElectrifiedNames.length }}
              </span>

              <span
                v-if="station.generalInfo.routes.doubleOtherNames.length != 0"
                class="track no-catenary"
                data-tooltip-type="BaseTooltip"
                :data-tooltip-content="`${$t('sceneries.info.double-track-routes-other')}${
                  station.generalInfo.routes.doubleOtherNames.length
                }`"
              >
                {{ station.generalInfo.routes.doubleOtherNames.length }}
              </span>
            </div>
          </td>

          <td class="station-info">
            <span
              v-if="station.generalInfo?.signalType"
              class="scenery-icon icon-info"
              :class="station.generalInfo?.controlType.replace('+', '-')"
              data-tooltip-type="BaseTooltip"
              :data-tooltip-content="
                $t('sceneries.info.control-type') +
                $t(`controls.${station.generalInfo?.controlType}`)
              "
            >
              {{ $t(`controls.abbrevs.${station.generalInfo.controlType}`) }}
            </span>

            <img
              v-if="station.generalInfo?.signalType"
              class="icon-info"
              :src="`/images/icon-${station.generalInfo.signalType}.svg`"
              :alt="station.generalInfo.signalType"
              data-tooltip-type="BaseTooltip"
              :data-tooltip-content="
                $t('sceneries.info.signals-type') + $t(`signals.${station.generalInfo.signalType}`)
              "
            />

            <img
              v-if="station.generalInfo?.SUP"
              class="icon-info"
              src="/images/icon-SUP.svg"
              alt="SUP (RASP-UZK)"
              data-tooltip-type="BaseTooltip"
              :data-tooltip-content="$t('sceneries.info.SUP')"
            />

            <img
              v-if="station.generalInfo?.ASDEK"
              class="icon-info"
              src="/images/icon-ASDEK.svg"
              alt="dSAT ASDEK"
              data-tooltip-type="BaseTooltip"
              :data-tooltip-content="$t('sceneries.info.ASDEK')"
            />

            <img
              v-if="!station.generalInfo"
              class="icon-info"
              src="/images/icon-unknown.svg"
              alt="icon-unknown"
              data-tooltip-type="BaseTooltip"
              :data-tooltip-content="$t('sceneries.info.unknown')"
            />
          </td>

          <td
            class="station-users"
            :class="{ inactive: !station.onlineInfo }"
            data-tooltip-type="UsersTooltip"
            :data-tooltip-content="getUsersTooltipContent(station.onlineInfo?.stationTrains ?? [])"
          >
            <span class="text--primary">{{
              station.onlineInfo?.stationTrains?.length ?? '-'
            }}</span>
            /
            <span class="text--primary">{{ station.onlineInfo?.maxUsers ?? '-' }}</span>
          </td>

          <td class="station-likes" :class="{ inactive: !station.onlineInfo }">
            <span>{{ station.onlineInfo?.dispatcherRate ?? '-' }}</span>
          </td>

          <td
            class="station-spawns"
            :class="{ inactive: !station.onlineInfo }"
            data-tooltip-type="SpawnsTooltip"
            :data-tooltip-content="JSON.stringify(station.onlineInfo?.spawns ?? [])"
          >
            <span>{{ station.onlineInfo?.spawns.length ?? '-' }}</span>
          </td>

          <td
            class="station-schedules all"
            style="width: 30px"
            :class="{ inactive: !station.onlineInfo }"
          >
            {{ station.onlineInfo?.scheduledTrainCount.all ?? '-' }}
          </td>

          <td
            class="station-schedules unconfirmed"
            style="width: 30px"
            :class="{ inactive: !station.onlineInfo }"
          >
            {{ station.onlineInfo?.scheduledTrainCount.unconfirmed ?? '-' }}
          </td>

          <td
            class="station-schedules confirmed"
            style="width: 30px"
            :class="{ inactive: !station.onlineInfo }"
          >
            {{ station.onlineInfo?.scheduledTrainCount.confirmed ?? '-' }}
          </td>
        </tr>
      </tbody>
    </table>

    <div class="no-stations" v-else>
      <div>
        {{ $t('sceneries.no-stations') }} (region: <b>{{ mainStore.region.name }}</b
        >)
      </div>

      <div class="text--primary" v-if="getChangedFilters(filters).length != 0">
        ⚠ {{ $t('sceneries.active-filters') }}
      </div>
    </div>
  </section>
</template>

<script lang="ts">
import { defineComponent, inject, computed } from 'vue';
import StationStatusBadge from '../Global/StationStatusBadge.vue';
import Loading from '../Global/Loading.vue';
import dateMixin from '../../mixins/dateMixin';
import styleMixin from '../../mixins/styleMixin';
import { useApiStore } from '../../store/apiStore';
import { useMainStore } from '../../store/mainStore';
import { Station, Status, TooltipUserTrain, Train } from '../../typings/common';
import { useTooltipStore } from '../../store/tooltipStore';
import { getChangedFilters } from '../../managers/stationFilterManager';
import { ActiveSorter, HeadIdsType, headIconsIds, headIds } from './typings';
import { filterStations, sortStations } from './utils';
import { getLanguageNameById } from '../../utils/languageUtils';
import FlagIcon from '../Global/FlagIcon.vue';
import { isCreator } from '../../utils/userUtils';

export default defineComponent({
  emits: ['toggleDonationCard'],

  components: { Loading, StationStatusBadge, FlagIcon },
  mixins: [styleMixin, dateMixin],

  data: () => ({
    headIconsIds,
    headIds,
    scrollTop: 0,
    getChangedFilters,
    isCreator
  }),

  setup() {
    const mainStore = useMainStore();
    const apiStore = useApiStore();
    const tooltipStore = useTooltipStore();

    const filters = inject('StationsView_filters') as Record<string, any>;
    const activeSorter = inject('StationsView_activeSorter') as ActiveSorter;

    const filteredStationList = computed(() =>
      mainStore.allStationInfo
        .filter((station) => filterStations(station, filters))
        .sort((a, b) => sortStations(a, b, activeSorter))
    );

    return {
      Status: Status.Data,
      mainStore,
      apiStore,
      tooltipStore,
      filters,
      filteredStationList,
      activeSorter
    };
  },

  activated() {
    (this.$refs['tableRef'] as HTMLElement).scrollTop = this.scrollTop;
  },

  methods: {
    getSceneryRoute(station: Station) {
      this.$router.push({
        name: 'SceneryView',
        query: {
          station: station.name,
          region: this.$route.query.region || undefined
        }
      });
    },

    openDonationCard(e: Event) {
      this.$emit('toggleDonationCard', true);
      this.mainStore.modalLastClickedTarget = e.target;
      this.tooltipStore.hide();
    },

    openForumSite(e: Event, url: string | undefined) {
      if (!url) return;
      e.preventDefault();
      window.open(url, '_blank');
    },

    changeSorter(headerName: HeadIdsType) {
      if (headerName == 'general') return;

      if (headerName == this.activeSorter.headerName)
        this.activeSorter.dir = -1 * this.activeSorter.dir;
      else this.activeSorter.dir = 1;

      this.activeSorter.headerName = headerName;
    },

    getUsersTooltipContent(stationTrains: Train[]): string {
      const usersTrains: TooltipUserTrain[] = stationTrains.map((train) => ({
        driverName: train.driverName,
        trainNo: train.trainNo
      }));

      return JSON.stringify(usersTrains);
    },

    onScroll(e: Event) {
      this.scrollTop = (e.target as HTMLElement).scrollTop;
    }
  }
});
</script>

<style lang="scss" scoped>
@use '../../styles/responsive';
@use '../../styles/icons';

@use 'sass:color';

$rowCol: #424242;

.station_table {
  height: calc(100vh - 17em);
  max-height: 2000px;
  min-height: 500px;
  overflow: auto;
  font-weight: 500;
}

.no-stations {
  text-align: center;
  font-size: 1.25em;
  padding: 1em;
  background: #1a1a1a;
  line-height: 1.5em;
}

table {
  border-collapse: collapse;
  table-layout: fixed;
  width: 100%;
  min-width: 1250px;
  white-space: wrap;
}

thead {
  position: sticky;
  top: 0;
  z-index: 50;
}

thead tr {
  background-color: var(--clr-bg3);
}

thead th {
  background-color: var(--clr-bg3);
  white-space: pre-wrap;
  padding: 0.5em 0.25em;

  cursor: pointer;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;

  &.station {
    width: 12em;
  }

  &.min-lvl {
    width: 4em;
  }

  &.status {
    width: 10em;
  }

  &.dispatcher {
    width: 12em;
  }

  &.dispatcher-lang {
    width: 6em;
  }

  &.dispatcher-lvl {
    width: 6em;
  }

  &.routes-double,
  &.routes-single {
    width: 7em;
  }

  &.general {
    width: 11em;
  }

  &.header-image {
    width: 3.5em;

    &.user {
      width: 5em;
    }
  }
}

thead th .header_wrapper {
  display: flex;
  align-items: center;
  justify-content: center;

  img {
    width: 1.5em;
    vertical-align: middle;
  }
}

tbody tr {
  background-color: $rowCol;
  vertical-align: middle;

  &:nth-child(even) {
    background-color: color.adjust($rowCol, $lightness: 5%);
    color: white;
  }

  &:hover,
  &:focus {
    background-color: color.adjust($rowCol, $lightness: 15%);
  }

  td {
    padding: 0.15em 0;
    text-align: center;
    cursor: pointer;
    overflow: hidden;
    text-overflow: ellipsis;
    height: 2.5em;

    &.inactive {
      opacity: 0.2;
    }

    @include responsive.smallScreen {
      margin: 0;
      padding: 0.3em 0.5em;
      font-size: 1em;
    }
  }
}

.station-name {
  font-weight: bold;
  max-width: 200px;
  padding: 0.25em;

  &.default {
    color: var(--clr-primary);
  }

  &.nonPublic {
    color: #bebebe;
  }

  &.unavailable {
    font-weight: 500;
    color: #bebebe;
  }
}

.station-level,
.station-dispatcher-exp {
  span {
    display: block;

    width: 2em;
    height: 2em;
    line-height: 2em;
    margin: 0 auto;
  }

  img {
    width: 2em;
    border-radius: 50%;
  }
}

.station-dispatcher-name {
  img {
    max-height: 1.3em;
    vertical-align: text-top;
  }
}

.station-level {
  span {
    background-color: #888;
    border-radius: 50%;
  }
}

.station-info {
  .icon-info {
    vertical-align: middle;
    line-height: 2.5em;

    width: 2.5em;
    height: 2.5em;
    font-size: 0.8em;
    margin: 0 3px;

    outline: 2px solid #2b2b2b;
    border-radius: 5px;
  }
}

.station-tracks {
  .no-catenary {
    background-color: #939393;
  }

  .catenary {
    background-color: #009dce;
  }

  .separator {
    background-color: #b3b3b3;
    padding: 2px;
  }

  .track {
    display: inline-block;
    text-align: center;
    width: 1.3em;
    padding: 0.35em 0;
    font-size: 1.1em;
    margin: 0 0.2em;
  }
}

.station-schedules {
  &.all {
    color: gold;
  }

  &.unconfirmed {
    color: #ccc;
  }

  &.confirmed {
    color: lime;
  }
}
</style>
