<template>
  <div class="box-border">
    <Card style="padding:0;">
      <div class="org-member">
        <div class="tabs flex items-center justify-between">
          <div class="tabs-nav flex items-center">
            <div v-for="(item) in tabList" :key="item.id" :id="item.id" class="tabs-nav-option"
              :class="{ active: tableTab === item.id }" @click="updateTable(item)"><span>{{ item.name }}</span></div>
          </div>
          <div class="right-search pr-3">
            <div v-if="tableTab === 'member'" class="flex items-center">
              <d-input v-model="username" placeholder="搜索组织成员" clearable>
                <template #prefix>
                  <Icon name="gt-search" />
                </template>
              </d-input>
              <d-button class="ml-4 flex-shrink-0" variant="solid" color="primary" @click="router.push({ name: 'orgSettingMember' })"
                v-if="isAdmin">组织成员管理</d-button>
            </div>
            <div v-if="tableTab === 'follow'" class="flex items-center">
              <d-input v-model="keyword" placeholder="搜索关注用户" clearable @keydown="e=>e.key==='Enter'&&searchFollows()">
                <template #prefix>
                  <Icon name="gt-search" @click="searchFollows"/>
                </template>
              </d-input>
            </div>
          </div>
        </div>
        <div v-if="tableTab === 'member'">
          <div class="member">
            <DataPanel :loading="loading" :empty="empty" skeleton :card="false" class="my-[12px]">
              <MemberItems class="" :data="userList" showTags isManager :isAdmin="isAdmin" @statusChange="handleChange"
                @removeMember="handleRemove" @exitProject="handleExit" />
            </DataPanel>
          </div>
        </div>
        <div v-if="tableTab === 'follow'">
          <div class="overflow-hidden">
            <DataPanel :loading="followLoading" :empty="followList.length===0" skeleton :card="false" class="my-[12px]">
              <div v-for="item in followList" :key="item.id" class="flex items-center py-4 px-5">
                <GAvatar
                  :src="item.avatar"
                  :name="item.nickname"
                  :width="48"
                  :height="48"
                  :is_round="true"
                ></GAvatar>
                <div class="flex flex-col ml-5 w-[200px]">
                  <GText class="text-base">{{ xssPurify(item.nickname) }}</GText>
                  <div class="text-CG600 text-sm ellipsis mt-2">@{{ item.username }}</div>
                </div>
                <div class="text-CG600 flex-grow flex justify-center">
                  <span>{{formatTime(item.create_time, 'YYYY-MM-DD HH:mm:ss') }}</span>
                </div>
                <div class="w-[100px] flex justify-center">
                  <template v-if="localUser.username!==item.username">
                    <d-button v-if="item.is_followed" size="sm" class="follow-btn border boder-G400" @click="toggleFollow(item)">取消关注</d-button>
                    <d-button v-else size="sm" class="follow-btn border boder-G400" @click="toggleFollow(item)">关注</d-button>
                  </template>
                </div>
              </div>
            </DataPanel>
          </div>
        </div>
      </div>
    </Card>
    <div v-if="tableTab === 'member'">
      <d-pagination class="px-[20px] py-[20px] flex justify-center" auto-hide size="md" :page-size-options="[10, 20, 50]" :show-page-selector="false"
        :can-view-total="true" :can-change-page-size="true" :max-items="5" :total="pager.total"
        v-model:pageSize="pager.per_page" v-model:pageIndex="pager.page" @page-index-change="getUsers"
        @page-size-change="handleSizeChange" />
    </div>
    <div v-if="tableTab === 'follow'">
      <d-pagination class="px-[20px] py-[20px] flex justify-center" auto-hide size="md" :page-size-options="[10, 20, 50]" :show-page-selector="false"
        :can-view-total="true" :can-change-page-size="true" :max-items="5" :total="followPager.total"
        v-model:pageSize="followPager.per_page" v-model:pageIndex="followPager.page" @page-index-change="getFollowers()"
        @page-size-change="handleFollowSizeChange" />
    </div>
    <GModal v-model="visible" ref="deleteTip" showWarnIcon @confirm="handleConfirm" :title="warningInfo.title">
      <span class="inline-block text-G900 text-sm font-normal leading-[20px] break-all">{{ warningInfo.content }}</span>
    </GModal>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, toRaw, computed, watch, nextTick, onBeforeUnmount } from 'vue';
import { Message } from 'vue-devui/message';
import MemberItems from '@/components/MemberItems/index.vue';
import type { MemberItemData } from '@/components/MemberItems/types';
import { getOrgMembers, removeGroupUser, exitGroup, setGroupUserLevel } from '@/api/org';
import { getGroupFollows } from '@/api/org/devIndex';
import { useAccountStore } from '@/stores/user';
import { useRouter, useRoute } from 'vue-router';
import { storeToRefs } from 'pinia';
import { getOrgInfo } from '@/views/Org/hooks/orgInfo';
import { orgInfoStore } from '@/stores/Org';
import setting from '@/setting';
import { xssPurify } from '@/utils';
import { GModal } from '@/components/Setting/index';
import { useTimeFormat } from '@/utils/hooks/useTimeFormat';
import { reqCatchV2 } from '@/utils/catch';
import { followUser, unfollowUser } from '@/api/user';
import { useLoginCheck } from '@/utils/hooks/useLoginCheck';

const route = useRoute();
const router = useRouter();
const { namespace, getUserCreateOrg } = getOrgInfo();
const { visitor, developer, admin } = setting.role;
const loading = ref(true);
const { isAdmin, communityInfo, access_level } = storeToRefs(orgInfoStore());
const { formatTime } = useTimeFormat();
const { loginCheck } = useLoginCheck();
const empty = computed(() => {
  return !loading.value && !userList.value?.length;
});
const hasPermission = computed(() => access_level.value >= visitor);
const { accountInfo: localUser } = useAccountStore();
interface RepoGroupUser {
  access_level: number | string
  email: string
  id: number | string
  is_current_source_member: boolean
  name: string
  name_cn?: string
  username: string
  type: string
  web_url: string
  [x: string]: any
}

// 邀请成员
const visible = ref(false);
const username = ref('');
const pager = reactive({
  page: 1,
  per_page: 10,
  total: 0
});
const followPager = reactive({
  page: 1,
  per_page: 10,
  total: 0
});
const warningInfo = reactive<{ title: string, content: string, name: string, type: 'remove' | 'exit' | '' }>({
  title: '',
  content: '',
  name: '',
  type: ''
});
const tableTab = ref(hasPermission.value ? 'member' : 'follow');
const tabList = hasPermission.value ? [
  {
    id: 'member',
    name: '组织成员'
  }, {
    id: 'follow',
    name: '社区粉丝'
  }
] : [{
  id: 'follow',
  name: '社区粉丝'
}];
const updateTable = (item: any) => {
  tableTab.value = item.id;
};
// 判断是否从组织主页banner跳转
const params = new URLSearchParams(window.location.search);
const isOrgToFans = params.get('isOrgToFans');
if (isOrgToFans === 'isOrgToFans') {
  const select = tabList.find(v => v.id === 'follow');
  select && updateTable(select);
}
watch(() => route.query, (val) => {
  if (val?.isOrgToFans === 'isOrgToFans') {
    const select = tabList.find(v => v.id === 'follow');
    select && updateTable(select);
  }
}, { immediate: true, deep: true });
const keyword = ref('');
const followLoading = ref(false);
const followList = ref([]);
const userList = ref<MemberItemData[]>([]);
const getUserInfo = (source: RepoGroupUser, content: RepoGroupUser[]) => {
  const userInfo = JSON.parse(localStorage.getItem('userInfo') as string);
  const adminList = content?.filter(item => item.access_level.toString() === '50') || [];
  return {
    imageSrc: source.avatar || source.avatar_url,
    nickname: source.nickname || source.username || '-',
    userName: source.username,
    isSelf: Number(userInfo.arts_id) === Number(source.id),
    isManager: source.access_level.toString() >= admin,
    isDeveloper: source.access_level.toString() >= developer && source.access_level.toString() < admin,
    isVisitor: source.access_level.toString() >= visitor && source.access_level.toString() < developer,
    allowedExit: source.access_level.toString() !== '50' || adminList.length > 1,
    isApplying: false,
    status: source.access_level.toString(),
    lastStatus: source.access_level.toString(),
    path: `/${source.username}`,
    type: source.type,
    join_way: source.join_way,
    disabledOption: false
  };
};

const getUsers = async() => {
  const { page, per_page } = pager;
  const res = await getOrgMembers({ group_id: namespace.value, page, per_page, query: username.value.trim() });
  if (res.status === 200) {
    userList.value = (res.data.content as RepoGroupUser[]).map(item => {
      return getUserInfo(item, res.data.content);
    });

    pager.total = res?.data?.total;
    pager.page = res?.data?.page_num;
    pager.per_page = res?.data?.page_size;
  }
  loading.value = false;
};
const getFollowers = async() => { // 获取组织的粉丝列表
  const { page, per_page } = followPager;
  followLoading.value = true;
  const res = await getGroupFollows({ groupId: namespace.value, nsId: communityInfo.value?.ns_id, keyword: keyword.value, pageNum: page, pageSize: per_page });
  followLoading.value = false;
  if (res.data) {
    const { content, total } = res.data.data;
    followList.value = (content || []).map(({ nick_name, ...other }) => ({ ...other, nickname: nick_name }));
    // if (code === 200) {
    //   followList.value = (data.content || []).map(({ gitCodeUser, createdAt, ...other }) => ({
    //     ...other,
    //     avatar: gitCodeUser.avatar,
    //     nickname: gitCodeUser.nickname,
    //     username: gitCodeUser.username,
    //     create_time: createdAt,
    //     is_followed: gitCodeUser.isFollowedForGitCodeUser
    //   }));
    //   followPager.total = data.total;
    // }
    followPager.total = total;
  }
};
const searchFollows = () => {
  followPager.page = 1;
  followPager.total = 0;
  getFollowers();
};
const toggleFollow = async(item:any, key = 'is_followed') => { // 关注用户
  if (!loginCheck()) return;
  const params = {
    username: localUser.username || '',
    followType: 0,
    unfollowUsername: item.username,
    followedUsername: item.username
  };
  const followRes = await reqCatchV2(() => item[key] ? unfollowUser(params) : followUser(params));
  if (followRes.data) {
    Message({
      type: 'success',
      message: `${item[key] ? '取消关注' : '关注'}成功`
    });
    await getFollowers();
  }
};
const handleRemove = async(config: any) => {
  const { userName } = config.data;
  visible.value = true;
  warningInfo.type = 'remove';
  warningInfo.name = userName;
  warningInfo.title = `你正在移除成员 ${userName}`;
  warningInfo.content = '移除成员后无法恢复, 确认移除么?';
};

const handleConfirm = async() => {
  const { type, name } = warningInfo;
  const config = {
    group_id: namespace.value,
    username: name
  };
  const reqFn = type === 'remove'
    ? removeGroupUser
    : exitGroup;
  const res = await reqFn(config);
  if (!res.error) {
    visible.value = false;
    Message.success('操作成功');
    if (type === 'exit') {
      router.replace('/');
    } else {
      for (const key in warningInfo) {
        warningInfo[key as keyof typeof warningInfo] = '';
      }
      getUsers();
    }
  }
};

const handleChange = async(data: any) => {
  const { status, userName, nickname } = toRaw(data.data);
  const cData = await getUserCreateOrg(userName);
  if (status === '50' && !cData) {
    data.data.status = data.data.lastStatus;
    return Message.warning(`${nickname}已经是 5 个组织的管理员，无法再添加为管理员。`);
  }
  const res = await setGroupUserLevel({ group_id: namespace.value, username: userName, access_level: status });
  if (!res.error) {
    Message.success('操作成功');
    getUsers();
  }
};

const handleSearch = async() => {
  pager.total = 0;
  pager.page = 1;
  pager.per_page = 10;
  nextTick(() => {
    getUsers();
  });
};

const setSearch = () => {
  const timer = setTimeout(() => {
    handleSearch();
  }, 200);
  const cancel = () => {
    clearTimeout(timer);
  };
  return {
    cancel
  };
};

const stop = watch(() => username.value.trim(), (_new, _old, onCleanup) => {
  const { cancel } = setSearch();
  onCleanup(cancel);
});
const handleExit = () => {
  visible.value = true;
  warningInfo.type = 'exit';
  warningInfo.title = `退出组织?`;
  warningInfo.content = `你确定你想退出吗？你将无法访问所有存储库和团队。`;
};

const handleSizeChange = () => {
  pager.page = 1;
  nextTick(() => {
    getUsers();
  });
};
const handleFollowSizeChange = () => {
  followPager.page = 1;
  getFollowers();
};
onMounted(() => {
  if (hasPermission.value) getUsers();
  getFollowers();
});
// watch(() => communityInfo.value, (val) => {
//   if (val.ns_id) getFollowers();
// }, { immediate: true });
onBeforeUnmount(() => {
  stop();
});

</script>

<style lang="scss" scoped>
.org-member{
  .tabs{
    height: 60px;
    border-bottom: 1px solid var(--color-G300);
    .tabs-nav{
      .tabs-nav-option{
        line-height: 58px;
        color: var(--color-CG600);
        cursor: pointer;
        padding: 0 4px;
        margin: 0 12px;
        &::after{
          content: "";
          display: block;
          margin: auto;
          height: 2px;
          width: 0;
          background: transparent;
          //transition: width var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out, cubic-bezier(.5, .05, .5, .95)), background-color var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out, cubic-bezier(.5, .05, .5, .95));
        }
        &.active{color:var(--color-G900);}
        &.active::after{
          content: "";
          display: block;
          margin: auto;
          height: 2px;
          width: 100%;
          background: var(--color-G900);
          //transition: width var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out, cubic-bezier(.5, .05, .5, .95)), background-color var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out, cubic-bezier(.5, .05, .5, .95));
        }
        &:hover::after{
          content: "";
          display: block;
          margin: auto;
          height: 2px;
          width: 100%;
          background: var(--color-G900);
          //transition: width var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out, cubic-bezier(.5, .05, .5, .95)),background-color var(--devui-animation-duration-slow, .3s) var(--devui-animation-ease-in-out, cubic-bezier(.5, .05, .5, .95));
        }
      }
    }
  }
}

.repo-setting-member-modal {
  width: 370px;
  box-sizing: border-box;
  padding: 0 0 20px;

  .devui-modal__body {
    padding: 0;
  }

  .modal-slot-header {
    @apply box-border py-[18px] mx-[22px] text-[var(--color-G900)] text-[16px] border-b-[1px] border-solid border-[var(--color-G200)] font-bold;
  }

  .devui-flexible-overlay {
    left: 30px !important;
    right: 30px !important;
    max-height: 320px;
    overflow-y: scroll;
  }
}
</style>
