<template>
  <div class="table-actions">
    <div class="pane info-pane">
      <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>
        //
        <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 class="pane actions-pane">
      <button @click="addNewStation">Dodaj nową stację</button>
      <button @click="confirmLoadData">Odśwież dane</button>
      &nbsp;
      <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 id="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 style="margin-left: 0.5em" @click="clearInput">Wyczyść</button>
    </div>

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

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

    <div class="changelog" v-if="changelogVisible">
      <div style="margin-bottom: 0.25em">Changelog:</div>

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

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

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

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

  mixins: [dataMixin, 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 == 'routes') value = this.getRouteNames(changeItem[propChange] as string);

            itemChanges.push(`<i>${(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.loadData();
    },

    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();
    },

    signOut() {
      this.store.token = null;
      this.store.authState = AuthState.UNAUTHORIZED;

      window.localStorage.removeItem('auth-token');
      window.localStorage.removeItem('user');

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

    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 response = await axios.post(
          `${this.API_URL}/manager/updateSceneryList`,
          {
            changeList: mappedChangeList,
            token: this.store.token,
            notify: this.store.notifyDiscord,
          },
          {
            headers: {
              'Content-Type': 'application/json',
              Authorization: `Bearer ${this.store.token}`,
            },
          }
        );

        this.store.changesResponse = response.data;

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

    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,
        url: '',
        lines: '',
        project: null,
        reqLevel: -1,
        signalType: 'współczesna',
        controlType: 'SCS',
        SUP: false,
        routes: 'Test_1EPB"',
        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 {
  &[data-disabled='true'] {
    user-select: none;
    -moz-user-select: none;
    -webkit-user-select: none;

    color: #999;
  }
}

.info-file {
  color: greenyellow;
}

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

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

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

.search {
  color: black;

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

  padding: 0.35em 0.4em;
}

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

.actions-pane {
  margin-top: 1em;

  button {
    margin: 0.5em 0.5em 0 0;
  }
}

.notify-pane {
  margin: 1em 0;
}

.search-pane {
  margin-top: 0.5em;
}

label#notify {
  cursor: pointer;
  text-align: center;

  color: #000;

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

  input {
    display: none;

    &:checked + span {
      background-color: lightblue;
    }
  }
}
.changelog {
  height: 200px;
  overflow: auto;
}

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