<template>
  <d2-container>
    <template #header>
      <div class="problem-header">
        <el-input
          :placeholder="$t(key('search_placeholder'))"
          v-model="searchTitle"
          size="mini"
          clearable
          style="width:220px"
          @clear="onClearSearch"
          @keyup.enter.native="onSearch"
        >
          <el-button slot="append" icon="el-icon-search" @click="onSearch" />
        </el-input>
        <el-button
          type="primary"
          size="mini"
          icon="el-icon-plus"
          style="margin-left:10px"
          @click="openCategoryCreate"
        >
          {{ $t(key('add_directory')) }}
        </el-button>
      </div>
    </template>

    <el-container class="problem-content">
      <el-aside width="300px" class="problem-aside">
        <div v-if="searchShow" class="search-result">
          <el-card
            v-for="item in searchData"
            :key="item.id"
            :body-style="{ padding: '10px' }"
            shadow="never"
          >
            <div class="search-item-title" @click="handleSelect(item.id)">
              <span class="tree-icon">
                <i
                  v-if="item.type === 'md'"
                  class="el-icon-folder-opened"
                  style="color: rgba(144, 198, 252, 1)"
                />
                <i v-else class="el-icon-files" style="color: rgba(144, 198, 252, 1)" />
              </span>
              {{ item.title }}
            </div>
            <div class="search-item-desc">{{ item.describe }}</div>
          </el-card>
        </div>

        <div class="aside-toolbar">
          <el-button type="primary" size="mini" icon="el-icon-plus" @click="openEditor">
            {{ $t(key('add_document')) }}
          </el-button>
          <el-button type="success" size="mini" icon="el-icon-edit-outline" @click="openCategoryEdit" v-permission="'/setting/aide/problem/set'">
            {{ $t(key('edit')) }}
          </el-button>
          <el-button type="danger" size="mini" icon="el-icon-delete" @click="handleDeleteCategory" v-permission="'/setting/aide/problem/del'">
            {{ $t(key('delete')) }}
          </el-button>
        </div>

        <el-menu
          class="problem-menu"
          :unique-opened="true"
          @select="handleSelect"
          @open="handleOpen"
        >
          <MenuTree :data-list="problemTree">
            <template slot="menu" slot-scope="ctx">
              <div class="menu-actions">
                <el-button
                  v-if="ctx.type === 'file'"
                  type="text"
                  size="mini"
                  @click.stop="handleDownload(ctx.fileList.url, ctx.fileList.file_type)"
                >
                  {{ $t(key('download')) }}
                </el-button>
                <el-button v-if="ctx.type === 'md'" type="text" size="mini" @click.stop="handleEditMarkdown(ctx.menuId)">
                  {{ $t(key('edit')) }}
                </el-button>
                <el-button type="text" size="mini" style="margin-left:0" @click.stop="handleDeleteMarkdown(ctx.menuId)">
                  {{ $t(key('delete')) }}
                </el-button>
              </div>
            </template>
          </MenuTree>
        </el-menu>
      </el-aside>

      <el-main class="problem-main">
        <el-card v-if="docVisible" class="doc-card" shadow="never">
          <div slot="header" class="doc-header">
            <h1 style="margin:0">{{ docDetail.title }}</h1>
            <h6 style="margin:0">
              {{ docDetail.create_time }}
              {{ $t(key('submitter')) }}{{ docDetail.admin && docDetail.admin.name }}
            </h6>
          </div>
          <d2-markdown :key="markdownKey" :source="docDetail.markdown" />
        </el-card>
        <div v-else class="doc-empty">
          <i class="el-icon-document" style="font-size:64px;color:#dcdfe6" />
          <p style="color:#909399">{{ $t(key('select_document_tip')) }}</p>
        </div>
      </el-main>
    </el-container>

    <category-dialog
      ref="categoryDialog"
      :visible.sync="categoryVisible"
      :category-tree="categoryTree"
      :role-list="roleList"
      :pre="i18nPrefix"
      @submit="onCategorySubmit"
    />

    <markdown-editor
      ref="editorDrawer"
      :visible.sync="editorVisible"
      :edit-data="editDocData"
      :category-tree-data="categoryTree"
      :role-list="roleList"
      :pre="i18nPrefix"
      @submit="onEditorSubmit"
    />
  </d2-container>
</template>

<script>
import { i18nMixin } from '@/composables/useI18n'
import {
  getCategoryTree,
  setCategoryAdd,
  setCategoryUpdate,
  delCategory,
  getProblemTree,
  getMarkdownDetails,
  setMarkdownAdd,
  setMarkdownEdit,
  delMarkdownDetails,
  searchMarkdown,
  getRoleAll
} from '@/api/system-administration/problem-help'
import MenuTree from './components/MenuTree/index.vue'
import CategoryDialog from './components/CategoryDialog/index.vue'
import MarkdownEditor from './components/MarkdownEditor/index.vue'

export default {
  name: 'system-administration-problem-help',
  components: { MenuTree, CategoryDialog, MarkdownEditor },
  mixins: [i18nMixin('page.system_administration.system_utilities.problem_help')],
  data () {
    return {
      loading: false,
      searchTitle: '',
      searchData: [],
      searchShow: false,
      categoryTree: [],
      problemTree: [],
      roleList: [],
      selectedMenuId: null,
      docVisible: false,
      docDetail: { title: '', create_time: '', admin: {}, markdown: '' },
      markdownKey: false,
      categoryVisible: false,
      editorVisible: false,
      editDocData: null
    }
  },
  computed: {
    i18nPrefix () {
      return 'page.system_administration.system_utilities.problem_help'
    }
  },
  mounted () {
    this.fetchTree()
  },
  methods: {
    async fetchTree () {
      try {
        const [catRes, probRes, roleRes] = await Promise.all([
          getCategoryTree(),
          getProblemTree(),
          getRoleAll()
        ])
        this.categoryTree = catRes.data || []
        this.problemTree = probRes.data || []
        this.roleList = Array.isArray(roleRes) ? roleRes : (roleRes.data || [])
      } catch { /* ignore */ }
    },
    onSearch () {
      if (!this.searchTitle) { this.onClearSearch(); return }
      searchMarkdown({ title: this.searchTitle }).then(res => {
        this.searchData = res.data || []
        this.searchShow = this.searchData.length > 0
      })
    },
    onClearSearch () {
      this.searchShow = false
      this.searchData = []
    },
    handleOpen (key) {
      this.selectedMenuId = key
    },
    handleSelect (id) {
      getMarkdownDetails({ id }).then(res => {
        if (res.data && res.data.type !== 'file') {
          this.docDetail = res.data
          this.markdownKey = !this.markdownKey
          this.docVisible = true
        }
      })
    },
    handleDeleteCategory () {
      if (!this.selectedMenuId) {
        this.$message.error(this.$t(this.key('select_delete_directory')))
        return
      }
      this.$confirm(this.$t(this.key('confirm_message')), this.$t(this.key('prompt')), { type: 'warning' })
        .then(() => delCategory({ id: this.selectedMenuId }))
        .then(() => {
          this.$message.success(this.$t(this.key('delete_success')))
          this.fetchTree()
        })
        .catch(() => {})
    },
    handleEditMarkdown (menuId) {
      getMarkdownDetails({ id: menuId }).then(res => {
        if (res.data && res.data.type !== 'file') {
          this.editDocData = res.data
          this.editorVisible = true
        }
      })
    },
    handleDeleteMarkdown (menuId) {
      this.$confirm(this.$t(this.key('confirm_message')), this.$t(this.key('prompt')), { type: 'warning' })
        .then(() => delMarkdownDetails({ id: menuId }))
        .then(() => {
          this.$message.success(this.$t(this.key('delete_success')))
          this.fetchTree()
        })
        .catch(() => {})
    },
    handleDownload (url, fileType) {
      window.open(url, '_blank')
    },
    openCategoryCreate () {
      this.$refs.categoryDialog && this.$refs.categoryDialog.openCreate()
      this.categoryVisible = true
    },
    openCategoryEdit () {
      if (!this.selectedMenuId) {
        this.$message.warning(this.$t(this.key('select_edit_directory')))
        return
      }
      const findNode = (nodes) => {
        for (const n of nodes) {
          if (n.id === this.selectedMenuId) return n
          if (n.children) {
            const found = findNode(n.children)
            if (found) return found
          }
        }
        return null
      }
      const node = findNode(this.categoryTree)
      if (node) {
        this.$refs.categoryDialog && this.$refs.categoryDialog.openEdit(node)
        this.categoryVisible = true
      }
    },
    onCategorySubmit ({ status, id, form }) {
      const api = status === 'create' ? setCategoryAdd : setCategoryUpdate
      const data = status === 'create' ? form : { id, ...form }
      api(data).then(() => {
        this.$message.success(status === 'create'
          ? this.$t(this.key('add_success'))
          : this.$t(this.key('update_success')))
        this.categoryVisible = false
        this.fetchTree()
      })
    },
    openEditor () {
      this.editDocData = null
      this.editorVisible = true
    },
    onEditorSubmit (form) {
      const promise = form.id
        ? setMarkdownEdit({ id: form.id, ...form })
        : setMarkdownAdd(form)
      promise.then(() => {
        this.$message.success(this.$t(this.key(form.id ? 'edit_success' : 'create_success')))
        this.editorVisible = false
        this.editDocData = null
        this.fetchTree()
      })
    }
  }
}
</script>

<style scoped>
.problem-header {
  padding: 10px 0;
}
.problem-content {
  height: calc(100vh - 160px);
}
.problem-aside {
  border: solid 1px rgba(240, 240, 240, 1);
  border-radius: 4px 0 0 4px;
  overflow-y: auto;
}
.problem-menu {
  border-top: solid 1px rgba(240, 240, 240, 1);
}
.aside-toolbar {
  padding: 10px;
  margin-bottom: 10px;
}
.aside-toolbar .el-button {
  margin-bottom: 4px;
}
.search-result {
  max-height: 400px;
  overflow: auto;
  margin-bottom: 10px;
}
.search-item-title {
  font-size: 14px;
  padding: 3px 0;
  cursor: pointer;
}
.search-item-desc {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}
.menu-actions {
  position: absolute;
  right: 40px;
  top: 0;
}
.tree-icon {
  background: rgba(232, 239, 248, 1);
  width: 14px;
  height: 14px;
  padding: 0 0 2px 2px;
  border-radius: 2px;
  display: inline-block;
}
.problem-main {
  border: solid 1px rgba(240, 240, 240, 1);
  border-left: none;
  border-radius: 0 4px 4px 0;
}
.doc-card {
  min-height: 100%;
}
.doc-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 300px;
}
</style>
