<template>
  <div class="table-actions">
    <div class="info-pane">
      <div>
        <img src="/favicon.svg" width="50" alt="" />
      </div>

      <div>
        <div style="font-size: 0.75em; color: #ccc">v{{ packageVersion }}</div>
        <div>
          <span v-if="store.user">
            Zalogowany jako <b>{{ store.user.name }}</b>
          </span>
          &bull;
          <span class="info-file" :class="store.dataState">
            <span v-if="store.dataState == 'LOADING'">Ładowanie danych...</span>
            <span v-if="store.dataState == 'LOADED'">Załadowano dane z bazy!</span>
            <span v-if="store.dataState == 'ERROR'">Błąd podczas pobierania danych!</span>
          </span>
        </div>

        <div>
          <span class="file-changes" style="color: salmon" v-if="store.unsavedChanges">Niezapisane zmiany!</span>
          <span class="file-changes" style="color: #aaa" v-else>Brak niezapisanych zmian</span>
        </div>
      </div>
    </div>

    <div class="pane actions-pane">
      <button @click="addNewStation">Dodaj nową stację</button>
      <button @click="confirmLoadData">Odśwież dane</button>
      <button @click="confirmUpdateList" :data-disabled="!store.unsavedChanges" :disabled="!store.unsavedChanges">Zapisz zmiany</button>
      <button @click="signOut">Wyloguj się</button>
    </div>

    <div class="pane notify-pane">
      <label class="notify">
        <input type="checkbox" v-model="store.notifyDiscord" @input="onNotifyCheckboxChange(($event.target as HTMLInputElement)!.checked)" />
        <span>
          Powiadom o zmianach: <b>{{ store.notifyDiscord ? 'TAK' : 'NIE' }}</b>
        </span>
      </label>
    </div>

    <div class="pane search-pane">
      <input class="search" ref="search" type="text" v-model="store.searchedSceneryName" placeholder="Wpisz nazwę scenerii..." width="350" />

      <button @click="clearInput">Wyczyść</button>
    </div>

    <div class="pane">
      Pokazuj maks.
      <input type="number" min="1" v-model="store.maxVisibleResults" style="width: 50px" />
      wyników
    </div>

    <div class="pane">
      Obecnie pokazane scenerie:
      {{ Math.min(store.maxVisibleResults, store.stationList.length, store.sortedStationList.length) }} /
      {{ store.stationList.length }}
    </div>

    <div class="pane">
      <button @click="changelogVisible = !changelogVisible">{{ changelogVisible ? 'Ukryj' : 'Pokaż' }} changelog</button>
    </div>

    <div class="changelog" v-if="changelogVisible">
      <div>Changelog:</div>

      <div v-html="changelog || 'brak zmian'"></div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import routesMixin from '../mixins/routesMixin';
import { useStore } from '../store';
import { Availability, ChangeProp, HeaderTypes, SceneryRoutesInfo, SceneryRowItem } from '../types/types';
import { getAvailabilityValue } from '../types/typeUitls';
import client from '../common/http';

import { version } from '../../package.json';

export default defineComponent({
  setup() {
    return {
      store: useStore(),
    };
  },

  data() {
    return {
      changelogVisible: false,
      packageVersion: version,
    };
  },

  mixins: [routesMixin],

  computed: {
    changelog() {
      return this.store.changeList
        .map((changeItem) => {
          let itemChanges = [];

          if (changeItem.toRemove) return `<b class='text--accent'>${changeItem.name} -></b> do usunięcia`;

          for (let change in changeItem) {
            let propChange = change as ChangeProp;

            if (/id|name/.test(propChange)) continue;

            let value = typeof changeItem[propChange] === 'boolean' ? (changeItem[propChange] ? 'TAK' : 'NIE') : changeItem[propChange];

            if (propChange == 'availability') value = getAvailabilityValue(changeItem[propChange] as Availability);
            if (propChange == 'routesInfo') value = this.getRouteNames(changeItem[propChange] as SceneryRoutesInfo[]);

            itemChanges.push(`<i style='color: white'>${(HeaderTypes as any)[propChange]}:</i> ${value ?? '-'}`);
          }

          return `<b class='text--accent'>${changeItem.name} -></b> ` + itemChanges.join('; ');
        })
        .join(' <br /> ');
    },
  },

  methods: {
    confirmLoadData() {
      const confirmed = confirm('Czy na pewno chcesz odświeżyć dane? Wszelkie niezapisane zmiany zostaną utracone!');

      if (confirmed) this.store.fetchSceneriesData();
    },

    confirmRestoreList() {
      const confirmed = confirm('Czy na pewno chcesz zresetować listę do ustawień z pliku? Wszelkie niezapisane zmiany zostaną utracone!');

      if (confirmed) this.restoreList();
    },

    confirmUpdateList() {
      const confirmed = confirm('Czy na pewno chcesz wprowadzić obecne zmiany?');

      if (confirmed) this.updateListToDb();
    },

    async signOut() {
      await client.post('/auth/logout');

      this.$router.push('/login');
      this.store.removeUserData();
    },

    onNotifyCheckboxChange(value: boolean) {
      window.localStorage.setItem('notifyDiscord', Number(value).toString());
    },

    async updateListToDb() {
      try {
        const mappedChangeList = this.store.changeList.map((v) => {
          if (/^#/.test(v.id)) {
            return { ...v, id: undefined };
          }

          return { ...v };
        });

        const updateResData = (await this.store.updateSceneriesData(mappedChangeList)).data;
        this.store.changesResponse = updateResData;

        this.store.fetchSceneriesData();
      } catch (error) {
        this.store.alertMessage = 'Ups! Wystąpił błąd podczas zapisywania danych!';
        console.error(error);
      }
    },

    addNewStation() {
      const name = prompt('Nazwa nowej scenerii');
      if (!name) return;

      if (this.store.stationList.some((station) => station.name.toLocaleLowerCase('pl-PL') == name.toLocaleLowerCase('pl-PL'))) {
        this.store.alertMessage = 'Sceneria o takiej nazwie już istnieje!';
        return;
      }

      this.store.newStationsCount++;

      const newSt: SceneryRowItem = {
        name,
        abbr: name.slice(0, 2),
        url: '',
        hash: '',
        lines: '',
        project: null,
        projectUrl: null,
        reqLevel: -1,
        signalType: 'współczesna',
        controlType: 'SCS',
        SUP: false,
        routes: 'Test_1EPB:0:0',
        routesInfo: [
          {
            isElectric: true,
            isInternal: false,
            isRouteSBL: false,
            routeLength: 0,
            routeSpeed: 0,
            routeTracks: 1,
            routeName: 'Test',
          },
        ],
        checkpoints: '',
        authors: '',
        availability: 'default',
        id: `#${Math.random().toString(32).substring(2)}`,
      };

      this.store.changeList.push({ ...newSt });
      // this.store.changeBackupList[newSt.id] = null;
      this.store.searchedSceneryName = name;

      this.store.unsavedChanges = true;

      this.store.stationList.unshift(newSt);
    },

    restoreList() {
      if (this.store.backupList.length == 0) return;

      this.store.stationList = JSON.parse(JSON.stringify(this.store.backupList));
      this.store.changeList = [];
      this.store.stationsToRemove = [];
      this.store.unsavedChanges = false;
      this.store.searchedSceneryName = '';
    },

    clearInput() {
      this.store.searchedSceneryName = '';
    },
  },
});
</script>

<style lang="scss" scoped>
button {
  background-color: #3c5a89;

  &:hover:not([data-disabled='true']),
  &:focus-visible {
    background-color: lighten($color: #3c5a89, $amount: 10%);
  }

  &[data-disabled='true'] {
    user-select: none;
    -moz-user-select: none;
    -webkit-user-select: none;

    color: #999;
  }
}

.table-actions {
  display: flex;
  flex-direction: column;
  gap: 1em;
}

.pane {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}

.info-pane {
  display: flex;
  align-items: center;
  gap: 0.5em;
}

.info-file {
  color: greenyellow;
}

.info-file.LOADING {
  color: #aaa;
}

.info-file.ERROR {
  color: salmon;
}

#notify-checkbox:checked + label {
  color: gold;
}

.search-pane {
  display: flex;

  gap: 0.5em;

  .search {
    color: black;

    border: 1px solid white;
    outline: none;
    appearance: none;

    padding: 0.35em 0.4em;
  }
}

.actions-pane {
  display: flex;
  gap: 0.5em;
}

label.notify {
  display: flex;
  cursor: pointer;
  text-align: center;

  color: #000;

  span {
    padding: inherit;
    background-color: salmon;
    padding: 0.3em 2em;
  }

  input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;

    &:checked + span {
      background-color: lightblue;
    }

    &:focus-visible + span {
      outline: 1px solid gold;
    }
  }
}
.changelog {
  height: 200px;
  overflow: auto;
}

@media screen and (max-width: 550px) {
  .pane {
    justify-content: center;
    text-align: center;
  }
}
</style>
