<template>
  <Progress
    v-if="isProcessing"
    :size="20"
    class="processing-progress"
  />

  <div
    v-if="!isProcessing && presentCommunity && channels"
    class="community"
  >
    <div class="left">
      <div class="community-top-info">
        {{ presentCommunity.name }}
      </div>

      <div class="channels">
        <RouterLink
          v-for="channel of channels"
          :to="`/community/${$route.params.communityId}/${channel.id}`"
          :class='route.fullPath === `/community/${$route.params.communityId}/${channel.id}`
            ? "isActive"
            : ""'
        >
          <Icon icon="material-symbols:chat-rounded" />
          <span>{{ channel.name }}</span>
        </RouterLink>
      </div>
    </div>

    <span class="border" />

    <div class="community-inner">
      <RouterView
        :key="route.matched[1]?.path"
      />
    </div>
  </div>
</template>

<style>
.community-top-info {
  display: flex;
  gap: 0.25rem;
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-bottom: 1px solid var(--border-color);
  padding: 1rem;
  font-size: 1.1rem;
  font-weight: bold;
  box-sizing: border-box;
}
</style>

<style scoped>
.processing-progress {
  margin: auto;
}

.community {
  height: 100%;
  display: flex;
}

.left {
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  width: 18rem;
  height: 100%;
  border-top-right-radius: 2rem;
  border-bottom-right-radius: 2rem;
}

.channels,
.border {
  flex-shrink: 0;
}

.channels {
  display: flex;
  flex-direction: column;
  width: 100%;
  flex-grow: 1;
  gap: 1rem;
  overflow: scroll;
  padding: 1rem 1rem 0 1rem;
  box-sizing: border-box;
}

.channels a {
  display: flex;
  color: var(--text-color);
  text-decoration: none;
  padding-left: 1rem;
  gap: 0.25rem;
  height: 2rem;
  border: 1px solid transparent;
  border-radius: 1rem;
  padding: 0.5rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  user-select: none;
  -webkit-user-select: none;
}

.channels a:hover,
.channels a.isActive {
  background-color: var(--bg-sub-color);
}

.channels a.isActive {
  border: 1px solid var(--border-color);
}

.channels a * {
  margin: auto 0;
}

.channels a svg {
  width: 1.25rem;
  height: 1.25rem;
}

.channels a span {
  font-size: 1.25rem;
}

.community .border {
  width: 1px;
  height: 100%;
  background-color: var(--border-color);
}

.community .community-inner {
  flex-grow: 1;
  height: 100%;
  box-sizing: border-box;
}

.community-inner {
  display: flex;
  flex-direction: column;
}
</style>

<script lang="ts" setup>
import { RouterLink, RouterView, useRoute, useRouter } from "vue-router";
import { account, presentCommunity, serverInfo } from "@/lib/account";
import client from "@/lib/client";
import { createModal } from "@/lib/modal";
import GoHomeError from "@/components/Modal/GoHomeError.vue";
import { ref } from "vue";
import Progress from "@/components/Progress.vue";
import { title } from "@/lib/router";
import type ApiMap from "lynqchat-js/1.0.0-alpha.0/map";
import { Icon } from "@iconify/vue";

const route = useRoute();
const router = useRouter();
const isProcessing = ref<boolean>(false);

const channels = ref<Extract<ApiMap["channel/list"]["response"], { channels: any }>["channels"]>();

if (!serverInfo.value?.success) {
  throw new Error("サーバー情報の取得に失敗しました。");
}

if (!serverInfo.value.isInitialized) {
  router.replace("/setup/initialization");
}

if (!account.value?.success) {
  switch (account.value?.error.bad) {
    case "client":
      router.replace("/signin");
      break;
    default:
      throw new Error("アカウント情報の取得に失敗しました。");
  }
}

(async () => {
  isProcessing.value = true;

  if (!serverInfo.value?.success) {
    throw new Error("サーバー情報の取得に失敗しました。");
  }

  const communityId = route.params.communityId;
  if (typeof communityId !== "string") {
    isProcessing.value = false;
    createModal({
      component: GoHomeError,
      onClose: async () => await router.push("/"),
      props: {
        error: "不正なアクセスです。",
      },
    });
    return;
  }

  const community = await client.value.request("community/get", {
    id: communityId,
  });

  if (!community.success) {
    isProcessing.value = false;
    createModal({
      component: GoHomeError,
      onClose: async () => await router.push("/"),
      props: {
        error: "コミュニティが取得できませんでした。",
      },
    });
    return;
  }

  presentCommunity.value = community.community;

  document.title = `${community.community.name} | ${serverInfo.value.name}`;
  title.value = community.community.name;

  const channelsRes = await client.value.request("channel/list", {
    community: communityId,
  });

  if (!channelsRes.success) {
    isProcessing.value = false;
    createModal({
      component: GoHomeError,
      onClose: async () => await router.push("/"),
      props: {
        error: "チャンネルが取得できませんでした。",
      },
    });
    return;
  }

  channels.value = channelsRes.channels;

  isProcessing.value = false;
})();
</script>