import utils, { ROOM_TYPE_CHANNEL } from "../plugins/utils";
import roomTypeMixin from "./roomTypeMixin";

export default {
  mixins: [roomTypeMixin],
  data() {
    return {
      roomJoinRule: null,
      userCanChangeJoinRule: false,
      userCanPurgeRoom: false,
      editedRoomName: "",
      isRoomNameEditMode: false,
      roomNameErrorMessage: null,
      editedRoomTopic: "",
      isRoomTopicEditMode: false,
      roomTopicErrorMessage: null,
      messageRetentionDisplay: "",
      retentionPeriods: [
        {
          text: this.$t("room_info.message_retention_none"),
          value: 0
        },
        {
          text: this.$t("room_info.message_retention_4_week"),
          value: 3600 * 24 * 28 * 1000
        },
        {
          text: this.$t("room_info.message_retention_2_week"),
          value: 3600 * 24 * 14 * 1000
        },
        {
          text: this.$t("room_info.message_retention_1_week"),
          value: 3600 * 24 * 7 * 1000
        },
        {
          text: this.$t("room_info.message_retention_1_day"),
          value: 3600 * 24 * 1000
        },
        {
          text: this.$t("room_info.message_retention_8_hours"),
          value: 3600 * 8 * 1000
        },
        {
          text: this.$t("room_info.message_retention_1_hour"),
          value: 3600 * 1000
        }
      ]
    };
  },
  mounted() {
    this.$matrix.on("Room.timeline", this.roomInfoMixinOnEvent);
    this.updatePermissions();
    this.updateMessageRetention();
  },

  destroyed() {
    this.$matrix.off("Room.timeline", this.roomInfoMixinOnEvent);
  },

  computed: {
    room() {
      return this.$matrix.currentRoom;
    },

    roomName() {
      if (this.room) {
        return this.room.name;
      }
      return "";
    },

    roomTopic() {
      if (this.room) {
        return this.room.topic;
      }
      return "";
    },

    roomAvatar() {
      if (this.room) {
        return this.room.avatar;
      }
      return "";
    },

    roomIsEncrypted() {
      if (this.room) {
        return this.$matrix.matrixClient.isRoomEncrypted(this.room.roomId);
      }
      return false;
    },

    publicRoomLink() {
      if (this.room && this.roomJoinRule == "public") {
        return this.$router.getRoomLink(
          this.room.getCanonicalAlias(),
          this.room.roomId,
          this.room.name,
          utils.roomDisplayTypeToQueryParam(this.room, this.roomDisplayType),
          this.roomDisplayType == ROOM_TYPE_CHANNEL /* Auto join for channels */
        );
      }
      return null;
    },

    roomHistory() {
      if (this.room) {
        return this.room.shouldEncryptForInvitedMembers();
      }
      return false;
    },

    userCanExportChat() {
      // We say that if you can redact events, you are allowed to export chats.
      const me = this.room && this.room.getMember(this.$matrix.currentUserId);
      let isAdmin =
        me && this.room.currentState && this.room.currentState.hasSufficientPowerLevelFor("redact", me.powerLevel);
      return isAdmin;
    },

    isPrivate() {
      return this.$matrix.isDirectRoom(this.room);
    },

    /**
     * If this is a direct chat with someone, return that member here.
     * @returns MXMember of the one we are chatting with, or 'undefined'.
     */
    privateParty() {
      if (this.isPrivate) {
        const membersButMe = this.room.getMembers().filter((m) => m.userId != this.$matrix.currentUserId);
        if (membersButMe.length == 1) {
          return membersButMe[0];
        }
      }
      return undefined;
    },

    canViewRetentionPolicy() {
      return true;
    },

    /**
     * Return true if we can set message retention policy in the room.
     */
    canChangeRetentionPolicy() {
      return this.userCanExportChat;
    },
  },
  watch: {
    room: {
      handler(ignoredNewVal, ignoredOldVal) {
        this.updatePermissions();
      },
    },
    roomJoinRule: {
      handler(newVal, oldVal) {
        if (newVal && oldVal && newVal != oldVal) {
          this.setRoomJoinRule(newVal);
        }
      },
    },
  },
  methods: {
    memberAvatar(member) {
      if (member) {
        return member.getAvatarUrl(
          this.$matrix.matrixClient.getHomeserverUrl(),
          40,
          40,
          "scale",
          true
        );
      }
      return null;
    },
    // TODO - following power level comparisons assume that default power levels are used in the room!
    isAdmin(member) {
      return member.powerLevelNorm > 50;
    },
    isModerator(member) {
      return member.powerLevelNorm > 0 && member.powerLevelNorm <= 50;
    },
    /**
     * Get a string describing current room retention setting.
     * Can be "None", "1 week", "1 hour" etc...
     */
    roomMessageRetentionDisplay(maybeEvent) {
      const retention = this.roomMessageRetention(maybeEvent);
      const retentionPeriodsFound = this.retentionPeriods.find(rp=>rp.value===retention)
      if(retentionPeriodsFound) {
        return retentionPeriodsFound.text
      }
    },

    roomMessageRetention(maybeEvent) {
      const retentionEvent = maybeEvent || (this.room && this.room.currentState.getStateEvents("m.room.retention", ""));
      if (retentionEvent) {
        console.log("Retention event found", JSON.stringify(retentionEvent));
        const maxLifetime = parseInt(retentionEvent.getContent().max_lifetime);
        if (maxLifetime) {
          return maxLifetime;
        }
      }
      return 0;
    },

    onRoomNameClicked() {
      if (this.userCanPurgeRoom) {
        this.isRoomNameEditMode = !this.isRoomNameEditMode;
        this.editedRoomName = this.roomName;
      }
    },
    updateRoomName() {
      if (this.editedRoomName) {
        this.$matrix.matrixClient.setRoomName(this.room.roomId, this.editedRoomName);
        this.isRoomNameEditMode = !this.isRoomNameEditMode;
      } else {
        this.$refs.editedRoomName.focus();
      }
    },
    onRoomTopicClicked() {
      if (this.userCanPurgeRoom) {
        this.isRoomTopicEditMode = !this.isRoomTopicEditMode;
        this.editedRoomTopic = this.roomTopic;
      }
    },
    updateRoomTopic() {
      if (this.editedRoomTopic) {
        this.$matrix.matrixClient.setRoomTopic(this.room.roomId, this.editedRoomTopic);
        this.isRoomTopicEditMode = !this.isRoomTopicEditMode;
      } else {
        this.$refs.editedRoomTopic.focus();
      }
    },
    setRoomJoinRule(ignoredJoinRule) {
      // Do nothing in the general mixin, override in RoomInfo.vue
    },
    getRoomJoinRule() {
      return this.$matrix.getRoomJoinRule(this.room);
    },

    updatePermissions() {
      if (this.room) {
        this.roomJoinRule = this.getRoomJoinRule();
        const canChangeAccess =
          this.room.currentState.mayClientSendStateEvent("m.room.join_rules", this.$matrix.matrixClient) &&
          this.room.currentState.mayClientSendStateEvent("m.room.guest_access", this.$matrix.matrixClient);
        this.userCanChangeJoinRule = canChangeAccess;
        this.userCanPurgeRoom = canChangeAccess; //TODO - need different permissions here?
      } else {
        this.roomJoinRule = null;
        this.userCanChangeJoinRule = false;
        this.userCanPurgeRoom = false;
      }
    },

    roomInfoMixinOnEvent(event) {
      if (this.room && this.room.roomId == event.getRoomId()) {
        if (event.getType() == "m.room.join_rules" || event.getType() == "m.room.guest_access") {
          this.updatePermissions();
        } else if (event.getType() == "m.room.retention") {
          this.updateMessageRetention(event);
        }
      }
    },

    updateMessageRetention(event) {
      this.messageRetentionDisplay = this.roomMessageRetentionDisplay(event);
    },

    privatePartyAvatar(size) {
      const other = this.privateParty;
      if (other) {
        return other.getAvatarUrl(this.$matrix.matrixClient.getHomeserverUrl(), size, size, "scale", true);
      }
      return undefined;
    },
  },
};