<template>
  <div>
    <n-tabs v-model:value="tabValue" :bar-width="28" placement="left" style="height: 100%" type="line">
      <n-tab-pane name="api信息" tab="api信息">
        <NCard>
          <div class="title">
            <label class="lable">{{ data?.info.title }}</label>
            <n-tag :bordered="false" style="font-weight: 900" type="success">V{{ data?.info.version }}</n-tag>
            <n-tag :bordered="false" style="font-weight: 900" type="info">openapi-{{ data?.openapi }}</n-tag>
          </div>
          <div style="margin-bottom: 20px">
            <a :href="apiUrl">{{ apiUrl }}</a>
          </div>
          <div style="margin-bottom: 20px">{{ data?.info.summary }}</div>
          <div style="margin-bottom: 20px">{{ data?.info.description }}</div>
          <div><a :href="data?.info.termsOfService">Terms of service</a></div>
          <div>
            <a :href="data?.info.contact?.url">{{ data?.info.contact?.name }} - Website</a>
          </div>
          <div>
            <a :href="data?.info.contact?.url">Send email to {{ data?.info.contact?.name }}</a>
          </div>
          <div>
            <a :href="data?.info.license?.url">{{ data?.info.license?.name }}</a>
          </div>
          <div>
            <a :href="data?.externalDocs?.url">{{ data?.externalDocs?.description }}</a>
          </div>
        </NCard>
      </n-tab-pane>
      <n-tab-pane v-for="(v, k) in tags" :name="k" :tab="k">
        <NCard
          :segmented="{
            content: true,
            footer: 'soft',
          }">
          <template #header>
            <div>
              <label style="font-weight: 700; font-size: 27px">{{ k }}</label>
            </div>
            <div>
              <label style="font-weight: 700; font-size: 20px">{{ v.description }}</label>
            </div>
          </template>
          <n-collapse accordion default-expanded-names="1">
            <template v-for="(v2, k2) in v.data">
              <template v-for="(v3, k3) in v2">
                <OpenApiDocMethod :id="`${k}+${k3}-${k2}`" :type="k3" :url="k2" :data="v3" />
              </template>
            </template>
          </n-collapse>
        </NCard>
      </n-tab-pane>
      <n-tab-pane name="schema" tab="架构">
        <NCard
          :segmented="{
            content: true,
            footer: 'soft',
          }">
          <template #header>
            <div>
              <label style="font-weight: 700; font-size: 27px">架构</label>
            </div>
            <div>
              <label style="font-weight: 700; font-size: 20px">一些类型而已</label>
            </div>
          </template>
          <n-collapse accordion default-expanded-names="2">
            <OpenApiDocSchema :id="`schema+${k}`" v-for="(v, k) in
            data?.components?.schemas"
                               :data="v" :name="k" />
          </n-collapse>
        </NCard>
      </n-tab-pane>
      <n-tab-pane name="权限验证" tab="权限验证">
        <NCard
          :segmented="{
            content: true,
            footer: 'soft',
          }">
          <template #header>
            <div>
              <label style="font-weight: 700; font-size: 27px">权限验证</label>
            </div>
            <div>
              <label style="font-weight: 700; font-size: 20px">验证你的权限</label>
            </div>
          </template>
          <n-collapse accordion default-expanded-names="3">
            <OpenApiDocSecuritySchemes v-for="(v, k) in data?.components?.securitySchemes" :data="v" :name="k" />
          </n-collapse>
        </NCard>
      </n-tab-pane>
    </n-tabs>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, type PropType, ref } from 'vue';
import { NTag } from 'naive-ui';
import type { OpenAPIV3_1 } from 'openapi-types';
import OpenApiDocMethod from '@/components/OpenApiDocMethod.vue';
import { router } from '@/plugin';
import type { RouteLocationNormalizedGeneric } from 'vue-router';
import OpenApiDocSchema from '@/components/OpenApiDocSchema.vue';
import OpenApiDocSecuritySchemes from '@/components/OpenApiDocSecuritySchemes.vue';

const data = ref<OpenAPIV3_1.Document>();
const tags = ref<{
  [key: string]: {
    data: { [key: string]: OpenAPIV3_1.PathItemObject };
    description: string;
  };
}>({});
export type TFunctionType = (args: string) => string;
export type getApiFunType = (args: string) => PromiseLike<string>;

onMounted(() => {
  prop
    .getApiFun(prop.apiUrl)
    .then((res) => {
      data.value = JSON.parse(res);
      return data.value;
    })
    .then((res) => {
      for (const pathsKey in res?.paths) {
        const models = res?.paths[pathsKey];
        for (const model in models) {
          for (const i of models[model]?.tags) {
            if (!tags.value[i]) {
              tags.value[i] = {
                data: {},
                description: data.value?.tags?.find((is) => is.name === i)?.description,
              };
            }
            tags.value[i].data[pathsKey] = models;
          }
        }
      }
    })
    .then(() => {
      hashback(router.currentRoute.value);
    });
});

function hashback(to: RouteLocationNormalizedGeneric) {
  if (!to.hash) return;
  const tab = to.hash.split('+')?.[0].replace('#', '');
  setTimeout(() => {
    tabValue.value = tab;
    setTimeout(()=>{
      const ele = document.getElementById(to.hash.replace('#', ''));
      ele?.scrollIntoView();
      const ele2 = ele?.children[0].children[0];
      ele2?.click()
    },100)
  }, 100  );
}

const removeAfterEach = router.afterEach(hashback);

onUnmounted(() => removeAfterEach());

const tabValue = ref<string>('api信息');

const prop = defineProps({
  apiUrl: {
    type: String,
    required: true,
  },
  getApiFun: {
    type: Function as PropType<getApiFunType>,
    default: async (url: string) => (await fetch(url)).text(),
  },
  i18nFun: {
    type: Function as PropType<TFunctionType>,
    default: (s: string) => s,
  },
});
</script>

<style lang="scss" scoped>
.lable {
  font-size: 36px;
  font-weight: 900;
}

.title {
  display: flex;
  justify-content: left;
  align-items: flex-start;
  gap: 5px;
}
</style>
