<template>
  <div>
    <ListTable ref="ListTable" :header-actions="headerActions" :table-config="tableConfig" />
    <ViewSecret
      v-if="showViewSecretDialog"
      :account="account"
      :url="secretUrl"
      :visible.sync="showViewSecretDialog"
    />
    <UpdateSecretInfo
      v-if="showUpdateSecretDialog"
      :account="account"
      :visible.sync="showUpdateSecretDialog"
      @updateAuthDone="onUpdateAuthDone"
    />
    <AccountCreateUpdate
      v-if="showAddDialog"
      :account="account"
      :asset="iAsset"
      :title="accountCreateUpdateTitle"
      :visible.sync="showAddDialog"
      @add="addAccountSuccess"
      @bulk-create-done="showBulkCreateResult($event)"
    />
    <AccountCreateUpdate
      v-if="showAddTemplateDialog"
      :account="account"
      :add-template="true"
      :asset="iAsset"
      :title="accountCreateUpdateTitle"
      :visible.sync="showAddTemplateDialog"
      @add="addAccountSuccess"
      @bulk-create-done="showBulkCreateResult($event)"
    />
    <ResultDialog
      v-if="showResultDialog"
      :result="createAccountResults"
      :visible.sync="showResultDialog"
    />
  </div>
</template>

<script>
import ListTable from '@/components/Table/ListTable/index.vue'
import { ActionsFormatter } from '@/components/Table/TableFormatters'
import ViewSecret from './ViewSecret.vue'
import UpdateSecretInfo from './UpdateSecretInfo.vue'
import AccountCreateUpdate from './AccountCreateUpdate.vue'
import { connectivityMeta } from './const'
import { openTaskPage } from '@/utils/jms'
import ResultDialog from './BulkCreateResultDialog.vue'

export default {
  name: 'AccountListTable',
  components: {
    ResultDialog,
    ListTable,
    UpdateSecretInfo,
    ViewSecret,
    AccountCreateUpdate
  },
  props: {
    url: {
      type: String,
      required: true
    },
    exportUrl: {
      type: String,
      default() {
        return this.url.replace('/accounts/accounts/', '/accounts/account-secrets/')
      }
    },
    hasLeftActions: {
      type: Boolean,
      default: false
    },
    otherActions: {
      type: Array,
      default: null
    },
    hasClone: {
      type: Boolean,
      default: false
    },
    asset: {
      type: Object,
      default: null
    },
    columns: {
      type: Array,
      default: () => []
    },
    hasExport: {
      type: Boolean,
      default: true
    },
    hasImport: {
      type: Boolean,
      default: true
    },
    hasDeleteAction: {
      type: Boolean,
      default: true
    },
    columnsMeta: {
      type: Object,
      default: () => {
      }
    },
    columnsDefault: {
      type: Array,
      default: () => ([
        'name', 'username', 'asset', 'privileged',
        'secret_type', 'is_active', 'date_updated'
      ])
    },
    headerExtraActions: {
      type: Array,
      default: () => []
    }
  },
  data() {
    const vm = this
    return {
      showViewSecretDialog: false,
      showUpdateSecretDialog: false,
      showResultDialog: false,
      showAddDialog: false,
      showAddTemplateDialog: false,
      createAccountResults: [],
      accountCreateUpdateTitle: this.$t('assets.AddAccount'),
      iAsset: this.asset,
      account: {},
      secretUrl: '',
      tableConfig: {
        url: this.url,
        permissions: {
          app: 'assets',
          resource: 'account'
        },
        extraQuery: {
          order: '-date_updated'
        },
        columnsExclude: ['spec_info'],
        columns: [
          'name', 'username', 'asset', 'privileged',
          'secret_type', 'source', 'actions'
        ],
        columnsShow: {
          min: ['name', 'username', 'actions'],
          default: this.columnsDefault
        },
        columnsMeta: {
          name: {
            formatter: function(row) {
              const to = {
                name: 'AssetAccountDetail',
                params: { id: row.id }
              }
              if (vm.$hasPerm('accounts.view_account')) {
                return <router-link to={to}>{row.name}</router-link>
              } else {
                return <span>{row.name}</span>
              }
            }
          },
          asset: {
            label: this.$t('assets.Asset'),
            formatter: function(row) {
              const to = {
                name: 'AssetDetail',
                params: { id: row.asset.id }
              }
              if (vm.$hasPerm('assets.view_asset')) {
                return <router-link to={to}>{row.asset.name}</router-link>
              } else {
                return <span>{row.asset.name}</span>
              }
            }
          },
          secret_type: {
            width: '100px',
            formatter: function(row) {
              return row.secret_type.label
            }
          },
          source: {
            formatter: function(row) {
              return row.source.label
            }
          },
          has_secret: {
            width: '100px',
            formatterArgs: {
              showFalse: false
            }
          },
          privileged: {
            label: this.$t('assets.Privileged'),
            width: '120px',
            formatterArgs: {
              showText: false,
              showFalse: false
            }
          },
          connectivity: connectivityMeta,
          actions: {
            formatter: ActionsFormatter,
            formatterArgs: {
              hasUpdate: false, // can set function(row, value)
              hasDelete: false, // can set function(row, value)
              hasClone: this.hasClone,
              moreActionsTitle: this.$t('common.More'),
              extraActions: [
                {
                  name: 'View',
                  title: this.$t('common.View'),
                  can: this.$hasPerm('accounts.view_accountsecret'),
                  type: 'primary',
                  callback: ({ row }) => {
                    // debugger
                    vm.secretUrl = `/api/v1/accounts/account-secrets/${row.id}/`
                    vm.account = row
                    vm.showViewSecretDialog = false
                    setTimeout(() => {
                      vm.showViewSecretDialog = true
                    })
                  }
                },
                {
                  name: 'ClearSecret',
                  title: this.$t('common.ClearSecret'),
                  can: this.$hasPerm('accounts.change_account'),
                  type: 'primary',
                  callback: ({ row }) => {
                    this.$axios.patch(
                      `/api/v1/accounts/accounts/clear-secret/`,
                      { account_ids: [row.id] }
                    ).then(() => {
                      this.$message.success(this.$tc('common.ClearSuccessMsg'))
                    })
                  }
                },
                {
                  name: 'Test',
                  title: this.$t('common.Test'),
                  can: ({ row }) =>
                    !this.$store.getters.currentOrgIsRoot &&
                    this.$hasPerm('accounts.change_account') &&
                    row.asset['auto_config'].ansible_enabled &&
                    row.asset['auto_config'].ping_enabled,
                  callback: ({ row }) => {
                    this.$axios.post(
                      `/api/v1/accounts/accounts/tasks/`,
                      { action: 'verify', accounts: [row.id] }
                    ).then(res => {
                      openTaskPage(res['task'])
                    })
                  }
                },
                {
                  name: 'Update',
                  title: this.$t('common.Update'),
                  can: this.$hasPerm('accounts.change_account') && !this.$store.getters.currentOrgIsRoot,
                  callback: ({ row }) => {
                    const data = {
                      ...this.asset,
                      ...row.asset
                    }
                    vm.account = row
                    vm.iAsset = data
                    vm.showAddDialog = false
                    vm.accountCreateUpdateTitle = this.$t('assets.UpdateAccount')
                    setTimeout(() => {
                      vm.showAddDialog = true
                    })
                  }
                }
              ]
            }
          },
          ...this.columnsMeta
        }
      },
      headerActions: {
        hasLeftActions: this.hasLeftActions,
        hasMoreActions: true,
        hasCreate: false,
        hasImport: this.hasImport,
        hasExport: this.hasExport && this.$hasPerm('accounts.view_accountsecret'),
        handleImportClick: ({ selectedRows }) => {
          this.$eventBus.$emit('showImportDialog', {
            selectedRows,
            url: '/api/v1/accounts/accounts/',
            name: this?.name
          })
        },
        exportOptions: {
          url: this.exportUrl,
          mfaVerifyRequired: true,
          tips: this.$t('accounts.AccountExportTips')
        },
        importOptions: {
          canImportCreate: this.$hasPerm('accounts.add_account'),
          canImportUpdate: this.$hasPerm('accounts.change_account')
        },
        extraActions: [
          {
            name: 'add',
            title: this.$t('common.Add'),
            type: 'primary',
            can: () => {
              return vm.$hasPerm('accounts.add_account') && !this.$store.getters.currentOrgIsRoot
            },
            callback: async() => {
              await this.getAssetDetail()
              setTimeout(() => {
                vm.iAsset = this.asset
                vm.account = {}
                vm.accountCreateUpdateTitle = this.$t('assets.AddAccount')
                vm.showAddDialog = true
              })
            }
          },
          {
            name: 'add-template',
            title: this.$t('common.TemplateAdd'),
            has: !(this.platform || this.asset),
            can: () => {
              return vm.$hasPerm('accounts.add_account') && !this.$store.getters.currentOrgIsRoot
            },
            callback: async() => {
              await this.getAssetDetail()
              setTimeout(() => {
                vm.iAsset = this.asset
                vm.account = {}
                vm.accountCreateUpdateTitle = this.$t('assets.AddAccount')
                vm.showAddTemplateDialog = true
              })
            }
          },
          ...this.headerExtraActions
        ],
        extraMoreActions: [
          {
            name: 'ClearSecrets',
            title: this.$t('common.ClearSecret'),
            type: 'primary',
            fa: 'clean',
            can: ({ selectedRows }) => {
              return selectedRows.length > 0 && vm.$hasPerm('accounts.change_account')
            },
            callback: function({ selectedRows }) {
              const ids = selectedRows.map(v => { return v.id })
              this.$axios.patch(
                '/api/v1/accounts/accounts/clear-secret/',
                { account_ids: ids }).then(() => {
                this.$message.success(this.$tc('common.ClearSuccessMsg'))
              }).catch(err => {
                this.$message.error(this.$tc('common.bulkClearErrorMsg' + ' ' + err))
              })
            }.bind(this)
          }
        ],
        canBulkDelete: vm.$hasPerm('accounts.delete_account'),
        searchConfig: {
          getUrlQuery: false,
          exclude: ['asset']
        },
        hasSearch: true
      }
    }
  },
  watch: {
    url(iNew) {
      this.$set(this.tableConfig, 'url', iNew)
      this.$set(this.headerActions.exportOptions, 'url', iNew.replace(/(.*)accounts/, '$1account-secrets'))
    }
  },
  mounted() {
    if (this.columns.length > 0) {
      this.tableConfig.columns = this.columns
    }
    if (this.otherActions) {
      const actionColumn = this.tableConfig.columns[this.tableConfig.columns.length - 1]
      for (const item of this.otherActions) {
        actionColumn.formatterArgs.extraActions.push(item)
      }
    }
    if (this.hasDeleteAction) {
      this.tableConfig.columnsMeta.actions.formatterArgs.extraActions.push(
        {
          name: 'Delete',
          title: this.$t('common.Delete'),
          can: this.$hasPerm('accounts.delete_account'),
          type: 'primary',
          callback: ({ row }) => {
            this.$axios.delete(`/api/v1/accounts/accounts/${row.id}/`).then(() => {
              this.$message.success(this.$tc('common.deleteSuccessMsg'))
              this.$refs.ListTable.reloadTable()
            })
          }
        }
      )
    }
  },
  methods: {
    onUpdateAuthDone(account) {
      Object.assign(this.account, account)
    },
    addAccountSuccess() {
      this.$refs.ListTable.reloadTable()
    },
    async getAssetDetail() {
      const { query: { asset }} = this.$route
      if (asset) {
        this.iAsset = await this.$axios.get(`/api/v1/assets/assets/${asset}/`)
      }
    },
    refresh() {
      this.$refs.ListTable.reloadTable()
    },
    showBulkCreateResult(results) {
      this.showResultDialog = false
      this.createAccountResults = results
      setTimeout(() => {
        this.showResultDialog = true
      }, 100)
    }
  }
}
</script>

<style lang='scss' scoped>
.cell a {
  color: var(--color-info);
}
</style>