<script setup lang="ts">
import {
  DelBiliBlackList,
  SaveAccountSettings,
  SaveEnableFunctions,
  downloadConfigDirect,
  useAccount,
} from '@/api/account'
import { FunctionTypes, ScheduleWeekInfo, SongFrom, SongLanguage, SongRequestOption, SongsInfo } from '@/api/api-models'
import DynamicForm from '@/components/DynamicForm.vue'
import { TemplateConfig } from '@/data/VTsuruTypes'
import { FETCH_API, IndexTemplateMap, ScheduleTemplateMap, SongListTemplateMap } from '@/data/constants'
import {
  NAlert,
  NButton,
  NCard,
  NCheckbox,
  NCheckboxGroup,
  NDivider,
  NEmpty,
  NList,
  NListItem,
  NModal,
  NSelect,
  NSpace,
  NSpin,
  NTabPane,
  NTabs,
  NText,
  SelectOption,
  useMessage,
} from 'naive-ui'
import { computed, h, nextTick, onActivated, onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'

interface TemplateDefineTypes {
  TemplateMap: { [name: string]: { name: string; compoent: any } }
  Options: SelectOption[]
  Data: any
  Selected: string
  Config?: any | undefined
}

const accountInfo = useAccount()
const message = useMessage()
const route = useRoute()

const isSaving = ref(false)

const templates = ref({
  index: {
    TemplateMap: IndexTemplateMap,
    Options: Object.entries(IndexTemplateMap).map((v) => ({
      label: v[1].name,
      value: v[0],
    })),
    Data: null,
    Selected: accountInfo.value?.settings.indexTemplate ?? '',
  },
  schedule: {
    TemplateMap: ScheduleTemplateMap,
    Options: Object.entries(ScheduleTemplateMap).map((v) => ({
      label: v[1].name,
      value: v[0],
    })),
    Data: [
      {
        year: 2023,
        week: 30,
        days: [
          {
            title: '唱唱歌!',
            tag: '歌回',
            tagColor: '#61B589',
            time: '10:00 AM',
          },
          {
            title: '玩点游戏',
            tag: '游戏',
            tagColor: '#A36565',
            time: '20:00 PM',
          },
          {
            title: 'Title 3',
            tag: 'Tag 3',
            tagColor: '#7BCDEF',
            time: '11:00 PM',
          },
          {
            title: null,
            tag: null,
            tagColor: null,
            time: null,
          },
          {
            title: null,
            tag: null,
            tagColor: null,
            time: null,
          },
          {
            title: null,
            tag: null,
            tagColor: null,
            time: null,
          },
          {
            title: null,
            tag: null,
            tagColor: null,
            time: null,
          },
        ],
      },
    ] as ScheduleWeekInfo[],
    Selected: accountInfo.value?.settings.scheduleTemplate ?? '',
  },
  songlist: {
    TemplateMap: SongListTemplateMap,
    Options: Object.entries(SongListTemplateMap).map((v) => ({
      label: v[1].name,
      value: v[0],
    })),
    Data: [
      {
        id: 1,
        key: 'song1',
        name: '歌曲1',
        author: ['作者1'],
        tags: ['标签1', '标签2'],
        description: '这是一段描述',
        url: 'https://example.com/song1.mp3',
        from: SongFrom.Custom,
        language: [SongLanguage.Chinese],
        createTime: Date.now(),
        updateTime: Date.now(),
      },
      {
        id: 2,
        key: 'song2',
        name: '歌曲2',
        author: ['作者1'],
        tags: ['标签1', '标签2'],
        url: 'https://example.com/song2.mp3',
        from: SongFrom.Custom,
        language: [SongLanguage.Chinese],
        createTime: Date.now(),
        updateTime: Date.now(),
        description: '这还是一段描述',
        options: {
          scMinPrice: 30,
          fanMedalMinLevel: 5,
          needJianzhang: true,
        } as SongRequestOption,
      },
      {
        id: 3,
        key: 'song3',
        name: '歌曲3',
        tags: ['标签3', '很长很长很长很长很长很长很长很长很长很长的标签'],
        author: ['作者3'],
        url: 'https://example.com/song3.mp3',
        from: SongFrom.Custom,
        description: '这是一段很长很长很长很长很长很长很长很长很长很长的描述',
        language: [SongLanguage.Chinese],
        createTime: Date.now(),
        updateTime: Date.now(),
      },
      {
        id: 4,
        key: 'song4',
        name: '歌曲4',
        author: ['作者4'],
        url: 'https://example.com/song4.mp3',
        from: SongFrom.Custom,
        language: [SongLanguage.Chinese],
        createTime: Date.now(),
        updateTime: Date.now(),
      },
      {
        id: 5,
        key: 'song5',
        name: '歌曲5',
        author: ['作者5'],
        tags: ['标签1', '标签5', '标签6', '标签7', '标签8', '标签9', '标签10'],
        url: 'https://example.com/song5.mp3',
        from: SongFrom.Custom,
        language: [SongLanguage.Chinese],
        createTime: Date.now(),
        updateTime: Date.now(),
      },
    ] as SongsInfo[],
    Selected: accountInfo.value?.settings.songListTemplate ?? '',
  },
} as { [type: string]: TemplateDefineTypes })

const templateOptions = [
  {
    label: '主页',
    value: 'index',
  },
  {
    label: '歌单',
    value: 'songlist',
  },
  {
    label: '日程表',
    value: 'schedule',
  },
] as SelectOption[]
const selectedOption = ref(route.query.template?.toString() ?? 'index')
const selectedTab = ref(route.query.tab?.toString() ?? 'general')

const dynamicConfigRef = ref()
const selectedTemplateData = computed(() => templates.value[selectedOption.value])
const selectedComponent = computed(
  () => selectedTemplateData.value?.TemplateMap[selectedTemplateData.value.Selected].compoent,
)
const selectedTemplateConfig = computed(() => {
  if (dynamicConfigRef.value?.Config) {
    return dynamicConfigRef.value?.Config as TemplateConfig<any>
  }
  return undefined
})

const biliUserInfo = ref()
const settingModalVisiable = ref(false)

async function RequestBiliUserData() {
  await fetch(FETCH_API + `https://account.bilibili.com/api/member/getCardByMid?mid=10021741`).then(async (respone) => {
    const data = await respone.json()
    if (data.code == 0) {
      biliUserInfo.value = data.card
    } else {
      throw new Error('Bili User API Error: ' + data.message)
    }
  })
}
async function SaveComboGroupSetting(
  value: (string | number)[],
  meta: { actionType: 'check' | 'uncheck'; value: string | number },
) {
  if (accountInfo.value) {
    isSaving.value = true
    //UpdateEnableFunction(meta.value as FunctionTypes, meta.actionType == 'check')
    await SaveEnableFunctions(accountInfo.value.settings.enableFunctions)
      .then((data) => {
        if (data.code == 200) {
          //message.success('保存成功')
        } else {
          message.error('修改失败')
          if (accountInfo.value) {
            accountInfo.value.settings.enableFunctions = accountInfo.value.settings.enableFunctions.filter(
              (f) => f != (meta.value as FunctionTypes),
            )
          }
        }
      })
      .catch((err) => {
        message.error('修改失败: ' + err)
      })
      .finally(() => {
        isSaving.value = false
      })
  }
}
async function SaveComboSetting() {
  isSaving.value = true
  if (accountInfo.value) {
    //UpdateEnableFunction(meta.value as FunctionTypes, meta.actionType == 'check')
    await SaveAccountSettings()
      .then((data) => {
        if (data.code == 200) {
          message.success('已保存')
        } else {
          message.error('修改失败')
        }
      })
      .catch((err) => {
        message.error('修改失败: ' + err)
      })
      .finally(() => {
        isSaving.value = false
      })
  }
}
async function SaveTemplateSetting() {
  if (accountInfo.value) {
    switch (selectedOption.value) {
      case 'index': {
        accountInfo.value.settings.indexTemplate = selectedTemplateData.value.Selected ?? ''
        break
      }
      case 'songlist': {
        accountInfo.value.settings.songListTemplate = selectedTemplateData.value.Selected ?? ''
        break
      }
      case 'schedule': {
        accountInfo.value.settings.scheduleTemplate = selectedTemplateData.value.Selected ?? ''
        break
      }
    }
    await SaveComboSetting()
  }
}
async function onOpenTemplateSettings() {
  settingModalVisiable.value = true
  nextTick(async () => {
    await getTemplateConfig()
  })
}
async function getTemplateConfig() {
  if (selectedTemplateConfig.value && !selectedTemplateData.value.Config) {
    await downloadConfigDirect(selectedTemplateConfig.value.name)
      .then((data) => {
        if (data.code == 200) {
          message.success('已获取配置文件')
          console.log(`已获取模板配置: ${selectedTemplateConfig.value?.name}`)
          selectedTemplateData.value.Config = JSON.parse(data.data)
        } else if (data.code == 404) {
          //message.error(`未找到名为 ${name} 的配置文件`)
          console.error(`未找到名为 ${selectedTemplateConfig.value?.name} 的配置文件`)
          selectedTemplateData.value.Config = dynamicConfigRef.value.DefaultConfig
        } else {
          message.error('获取失败: ' + data.message)
          console.error('获取失败: ' + data.message)
        }
      })
      .catch((err) => {
        message.error(err)
      })
  }
}
const buttonGroup = computed(() => {
  return h(NSpace, () => [
    h(NButton, { type: 'primary', onClick: () => SaveTemplateSetting() }, () => '设为展示模板'),
    h(NButton, { type: 'info', onClick: onOpenTemplateSettings }, () => '模板设置'),
  ])
})

function unblockUser(id: number) {
  DelBiliBlackList(id)
    .then((data) => {
      if (data.code == 200) {
        message.success(`[${id}] 已移除黑名单`)
        if (accountInfo.value) {
          delete accountInfo.value.biliBlackList[id]
        }
      } else {
        message.error(data.message)
      }
    })
    .catch((err) => {
      message.error(err)
    })
}

onActivated(() => {
  if (route.query.tab) {
    selectedTab.value = route.query.tab.toString()
  }
  if (route.query.template) {
    selectedOption.value = route.query.template.toString()
  }
})
onMounted(async () => {
  await RequestBiliUserData()
})
</script>

<template>
  <NCard title="设置" :style="`${selectedTab === 'general' ? '' : 'min-height: 800px;'}`">
    <NSpin :show="isSaving">
      <NTabs v-model:value="selectedTab">
        <NTabPane tab="常规" name="general">
          <NDivider style="margin: 0"> 启用功能 </NDivider>
          <NCheckboxGroup v-model:value="accountInfo.settings.enableFunctions" @update:value="SaveComboGroupSetting">
            <NCheckbox :value="FunctionTypes.SongList"> 歌单 </NCheckbox>
            <NCheckbox :value="FunctionTypes.QuestionBox"> 提问箱(棉花糖 </NCheckbox>
            <NCheckbox :value="FunctionTypes.Schedule"> 日程 </NCheckbox>
            <NCheckbox :value="FunctionTypes.SongRequest"> 点歌 </NCheckbox>
            <NCheckbox :value="FunctionTypes.Queue"> 排队 </NCheckbox>
          </NCheckboxGroup>
          <NDivider> 通知 </NDivider>
          <NSpace>
            <NCheckbox v-model:checked="accountInfo.settings.sendEmail.recieveQA" @update:checked="SaveComboSetting">
              收到新提问时发送邮件
            </NCheckbox>
            <NCheckbox
              v-model:checked="accountInfo.settings.sendEmail.recieveQAReply"
              @update:checked="SaveComboSetting"
            >
              提问收到回复时发送邮件
            </NCheckbox>
          </NSpace>
          <NDivider> 提问箱 </NDivider>
          <NSpace>
            <NCheckbox
              v-model:checked="accountInfo.settings.questionBox.allowUnregistedUser"
              @update:checked="SaveComboSetting"
            >
              允许未注册用户提问
            </NCheckbox>
          </NSpace>
        </NTabPane>
        <NTabPane tab="黑名单" name="blacklist">
          <NList v-if="accountInfo.biliBlackList && Object.keys(accountInfo.biliBlackList).length > 0">
            <NListItem v-for="item in Object.entries(accountInfo.biliBlackList)" :key="item[0]">
              <NSpace align="center">
                <NText>
                  {{ item[1] }}
                </NText>
                <NText depth="3">
                  {{ item[0] }}
                </NText>
                <NButton type="error" @click="unblockUser(Number(item[0]))" size="small"> 移除 </NButton>
              </NSpace>
            </NListItem>
          </NList>
          <NEmpty v-else />
        </NTabPane>
        <NTabPane tab="模板" name="template">
          <NAlert type="success"> 如果有合适的设计稿或者想法可以给我说然后做成模板捏 </NAlert>
          <br />
          <NSpace vertical>
            <NSpace align="center">
              页面 <NSelect :options="templateOptions" v-model:value="selectedOption" style="width: 150px" />
            </NSpace>
            <NDivider style="margin: 5px 0 5px 0" title-placement="left"> 模板 </NDivider>
            <div>
              <NSpace>
                <NSelect
                  style="width: 150px"
                  :options="selectedTemplateData.Options"
                  v-model:value="selectedTemplateData.Selected"
                />
                <component :is="buttonGroup" />
              </NSpace>
              <NDivider />
              <Transition name="fade" mode="out-in">
                <div v-if="selectedComponent" :key="selectedTemplateData.Selected">
                  <component
                    ref="dynamicConfigRef"
                    :is="selectedComponent"
                    :user-info="accountInfo"
                    :bili-info="biliUserInfo"
                    :current-data="selectedTemplateData.Data"
                  />
                </div>
              </Transition>
            </div>
          </NSpace>
        </NTabPane>
      </NTabs>
    </NSpin>
  </NCard>
  <NModal
    preset="card"
    v-model:show="settingModalVisiable"
    closable
    style="width: 600px; max-width: 90vw"
    title="模板设置"
  >
    只是测试, 没用
    <NSpin v-if="!selectedTemplateData.Config" show />
    <DynamicForm
      v-else
      :key="selectedTemplateData.Selected"
      :configData="selectedTemplateData.Config"
      :config="selectedTemplateConfig"
    />
  </NModal>
</template>
