<template>
  <modal title="Edit Station">
    <template v-slot:body>
      <label class="label">Name</label>
      <p class="control">
        <input class="input" type="text" placeholder="Station Name" v-model="editing.name" />
      </p>
      <label class="label">Display name</label>
      <p class="control">
        <input
          class="input"
          type="text"
          placeholder="Station Display Name"
          v-model="editing.displayName"
        />
      </p>
      <label class="label">Description</label>
      <p class="control">
        <input
          class="input"
          type="text"
          placeholder="Station Description"
          v-model="editing.description"
        />
      </p>
      <label class="label">Privacy</label>
      <p class="control">
        <span class="select">
          <select v-model="editing.privacy">
            <option value="public">Public</option>
            <option value="unlisted">Unlisted</option>
            <option value="private">Private</option>
          </select>
        </span>
      </p>
      <br />
      <p class="control">
        <label class="checkbox party-mode-inner">
          <input type="checkbox" v-model="editing.partyMode" />
          &nbsp;Party mode
        </label>
      </p>
      <small>With party mode enabled, people can add songs to a queue that plays. With party mode disabled you can play a private playlist on loop.</small>
      <br />
      <div v-if="station.partyMode">
        <br />
        <br />
        <label class="label">Queue lock</label>
        <small
          v-if="station.partyMode"
        >With the queue locked, only owners (you) can add songs to the queue.</small>
        <br />
        <button
          class="button is-danger"
          v-if="!station.locked"
          v-on:click="$parent.toggleLock()"
        >Lock the queue</button>
        <button
          class="button is-success"
          v-if="station.locked"
          v-on:click="$parent.toggleLock()"
        >Unlock the queue</button>
      </div>
    </template>
    <template v-slot:footer>
      <button class="button is-success" v-on:click="update()">Update Settings</button>
      <button
        class="button is-danger"
        v-on:click="deleteStation()"
        v-if="station.type === 'community'"
      >Delete station</button>
    </template>
  </modal>
</template>

<script>
import { mapState } from "vuex";

import { Toast } from "vue-roaster";
import Modal from "./Modal.vue";
import io from "../../io";
import validation from "../../validation";

export default {
  computed: mapState("station", {
    station: state => state.station,
    editing: state => state.editing
  }),
  methods: {
    update: function() {
      if (this.station.name !== this.editing.name) this.updateName();
      if (this.station.displayName !== this.editing.displayName)
        this.updateDisplayName();
      if (this.station.description !== this.editing.description)
        this.updateDescription();
      if (this.station.privacy !== this.editing.privacy) this.updatePrivacy();
      if (this.station.partyMode !== this.editing.partyMode)
        this.updatePartyMode();
    },
    updateName: function() {
      const name = this.editing.name;
      if (!validation.isLength(name, 2, 16))
        return Toast.methods.addToast(
          "Name must have between 2 and 16 characters.",
          8000
        );
      if (!validation.regex.az09_.test(name))
        return Toast.methods.addToast(
          "Invalid name format. Allowed characters: a-z, 0-9 and _.",
          8000
        );

      this.socket.emit("stations.updateName", this.editing._id, name, res => {
        if (res.status === "success") {
          if (this.station) this.station.name = name;
          else {
            this.$parent.stations.forEach((station, index) => {
              if (station._id === this.editing._id)
                return (this.$parent.stations[index].name = name);
            });
          }
        }
        Toast.methods.addToast(res.message, 8000);
      });
    },
    updateDisplayName: function() {
      let _this = this;

      const displayName = this.editing.displayName;
      if (!validation.isLength(displayName, 2, 32))
        return Toast.methods.addToast(
          "Display name must have between 2 and 32 characters.",
          8000
        );
      if (!validation.regex.azAZ09_.test(displayName))
        return Toast.methods.addToast(
          "Invalid display name format. Allowed characters: a-z, A-Z, 0-9 and _.",
          8000
        );

      this.socket.emit(
        "stations.updateDisplayName",
        this.editing._id,
        displayName,
        res => {
          if (res.status === "success") {
            if (this.station) this.station.displayName = displayName;
            else {
              this.$parent.stations.forEach((station, index) => {
                if (station._id === this.editing._id)
                  return (this.$parent.stations[
                    index
                  ].displayName = displayName);
              });
            }
          }
          Toast.methods.addToast(res.message, 8000);
        }
      );
    },
    updateDescription: function() {
      let _this = this;

      const description = this.editing.description;
      if (!validation.isLength(description, 2, 200))
        return Toast.methods.addToast(
          "Description must have between 2 and 200 characters.",
          8000
        );
      let characters = description.split("");
      characters = characters.filter(character => {
        return character.charCodeAt(0) === 21328;
      });
      if (characters.length !== 0)
        return Toast.methods.addToast(
          "Invalid description format. Swastika's are not allowed.",
          8000
        );

      this.socket.emit(
        "stations.updateDescription",
        this.editing._id,
        description,
        res => {
          if (res.status === "success") {
            if (_this.station) _this.station.description = description;
            else {
              _this.$parent.stations.forEach((station, index) => {
                if (station._id === station._id)
                  return (_this.$parent.stations[
                    index
                  ].description = description);
              });
            }
            return Toast.methods.addToast(res.message, 4000);
          }
          Toast.methods.addToast(res.message, 8000);
        }
      );
    },
    updatePrivacy: function() {
      let _this = this;
      this.socket.emit(
        "stations.updatePrivacy",
        this.editing._id,
        this.editing.privacy,
        res => {
          if (res.status === "success") {
            if (_this.station) _this.station.privacy = _this.editing.privacy;
            else {
              _this.$parent.stations.forEach((station, index) => {
                if (station._id === station._id)
                  return (_this.$parent.stations[index].privacy =
                    _this.editing.privacy);
              });
            }
            return Toast.methods.addToast(res.message, 4000);
          }
          Toast.methods.addToast(res.message, 8000);
        }
      );
    },
    updatePartyMode: function() {
      let _this = this;
      this.socket.emit(
        "stations.updatePartyMode",
        this.editing._id,
        this.editing.partyMode,
        res => {
          if (res.status === "success") {
            if (_this.station)
              _this.station.partyMode = _this.editing.partyMode;
            else {
              _this.$parent.stations.forEach((station, index) => {
                if (station._id === station._id)
                  return (_this.$parent.stations[index].partyMode =
                    _this.editing.partyMode);
              });
            }
            return Toast.methods.addToast(res.message, 4000);
          }
          Toast.methods.addToast(res.message, 8000);
        }
      );
    },
    deleteStation: function() {
      let _this = this;
      this.socket.emit("stations.remove", this.editing._id, res => {
        Toast.methods.addToast(res.message, 8000);
      });
    }
  },
  mounted: function() {
    let _this = this;
    io.getSocket(socket => (_this.socket = socket));
  },
  components: { Modal }
};
</script>

<style lang='scss' scoped>
.controls {
  display: flex;

  a {
    display: flex;
    align-items: center;
  }
}

.table {
  margin-bottom: 0;
}

h5 {
  padding: 20px 0;
}

.party-mode-inner,
.party-mode-outer {
  display: flex;
  align-items: center;
}

.select:after {
  border-color: #029ce3;
}
</style>