<template>
	<div id="chat-container" class="window" :data-current-channel="channel.name">
		<div
			id="chat"
			:class="{
				'hide-motd': !$store.state.settings.motd,
				'colored-nicks': $store.state.settings.coloredNicks,
				'time-seconds': $store.state.settings.showSeconds,
				'time-12h': $store.state.settings.use12hClock,
			}"
		>
			<div
				:id="'chan-' + channel.id"
				class="chat-view"
				:data-type="channel.type"
				:aria-label="channel.name"
				role="tabpanel"
			>
				<div class="header">
					<SidebarToggle />
					<span class="title">{{ channel.name }}</span>
					<div v-if="channel.editTopic === true" class="topic-container">
						<input
							ref="topicInput"
							:value="channel.topic"
							class="topic-input"
							placeholder="Set channel topic"
							@keyup.enter="saveTopic"
							@keyup.esc="channel.editTopic = false"
						/>
						<span aria-label="Save topic" class="save-topic" @click="saveTopic">
							<span type="button" aria-label="Save topic"></span>
						</span>
					</div>
					<span v-else :title="channel.topic" class="topic" @dblclick="editTopic"
						><ParsedMessage
							v-if="channel.topic"
							:network="network"
							:text="channel.topic"
					/></span>
					<button
						class="menu"
						aria-label="Open the context menu"
						@click="openContextMenu"
					/>
					<span
						v-if="channel.type === 'channel'"
						class="rt-tooltip tooltipped tooltipped-w"
						aria-label="Toggle user list"
					>
						<button
							class="rt"
							aria-label="Toggle user list"
							@click="$store.commit('toggleUserlist')"
						/>
					</span>
				</div>
				<div v-if="channel.type === 'special'" class="chat-content">
					<div class="chat">
						<div class="messages">
							<div class="msg">
								<Component
									:is="specialComponent"
									:network="network"
									:channel="channel"
								/>
							</div>
						</div>
					</div>
				</div>
				<div v-else class="chat-content">
					<div
						:class="[
							'scroll-down tooltipped tooltipped-w tooltipped-no-touch',
							{'scroll-down-shown': !channel.scrolledToBottom},
						]"
						aria-label="Jump to recent messages"
						@click="$refs.messageList.jumpToBottom()"
					>
						<div class="scroll-down-arrow" />
					</div>
					<MessageList ref="messageList" :network="network" :channel="channel" />
					<ChatUserList v-if="channel.type === 'channel'" :channel="channel" />
				</div>
			</div>
		</div>
		<div
			v-if="this.$store.state.currentUserVisibleError"
			id="user-visible-error"
			@click="hideUserVisibleError"
		>
			{{ this.$store.state.currentUserVisibleError }}
		</div>
		<ChatInput :network="network" :channel="channel" />
	</div>
</template>

<script>
import socket from "../js/socket";
import ParsedMessage from "./ParsedMessage.vue";
import MessageList from "./MessageList.vue";
import ChatInput from "./ChatInput.vue";
import ChatUserList from "./ChatUserList.vue";
import SidebarToggle from "./SidebarToggle.vue";
import ListBans from "./Special/ListBans.vue";
import ListInvites from "./Special/ListInvites.vue";
import ListChannels from "./Special/ListChannels.vue";
import ListIgnored from "./Special/ListIgnored.vue";

export default {
	name: "Chat",
	components: {
		ParsedMessage,
		MessageList,
		ChatInput,
		ChatUserList,
		SidebarToggle,
	},
	props: {
		network: Object,
		channel: Object,
	},
	computed: {
		specialComponent() {
			switch (this.channel.special) {
				case "list_bans":
					return ListBans;
				case "list_invites":
					return ListInvites;
				case "list_channels":
					return ListChannels;
				case "list_ignored":
					return ListIgnored;
			}

			return undefined;
		},
	},
	watch: {
		channel() {
			this.channelChanged();
		},
		"channel.editTopic"(newValue) {
			if (newValue) {
				this.$nextTick(() => {
					this.$refs.topicInput.focus();
				});
			}
		},
	},
	mounted() {
		this.channelChanged();

		if (this.channel.editTopic) {
			this.$nextTick(() => {
				this.$refs.topicInput.focus();
			});
		}
	},
	methods: {
		channelChanged() {
			// Triggered when active channel is set or changed
			this.channel.highlight = 0;
			this.channel.unread = 0;

			socket.emit("open", this.channel.id);

			if (this.channel.usersOutdated) {
				this.channel.usersOutdated = false;

				socket.emit("names", {
					target: this.channel.id,
				});
			}
		},
		hideUserVisibleError() {
			this.$store.commit("currentUserVisibleError", null);
		},
		editTopic() {
			if (this.channel.type === "channel") {
				this.channel.editTopic = true;
			}
		},
		saveTopic() {
			this.channel.editTopic = false;
			const newTopic = this.$refs.topicInput.value;

			if (this.channel.topic !== newTopic) {
				const target = this.channel.id;
				const text = `/raw TOPIC ${this.channel.name} :${newTopic}`;
				socket.emit("input", {target, text});
			}
		},
		openContextMenu(event) {
			this.$root.$emit("contextmenu:channel", {
				event: event,
				channel: this.channel,
				network: this.network,
			});
		},
	},
};
</script>