<script lang="ts" setup>
import type { LoginLog } from '#/api/core/login-log';

import { ref } from 'vue';

import { Page } from '@vben/common-ui';
import { Eye, Trash2 } from '@vben/icons';
import { $t } from '@vben/locales';

import { ElButton, ElMessage, ElMessageBox, ElTag } from 'element-plus';

import {
  batchDeleteLoginLogApi,
  deleteLoginLogApi,
  getLoginLogDetailApi,
  getLoginLogListApi,
} from '#/api/core/login-log';
import { useZqTable } from '#/components/zq-table';

import {
  getDeviceTypeOptions,
  getFailureReasonOptions,
  getLoginTypeOptions,
  getStatusOptions,
  getTagLabel,
  getTagType,
  useSearchFormSchema,
  useZqTableColumns,
} from './data';
import DetailDrawer from './modules/detail-drawer.vue';

defineOptions({ name: 'SystemLoginLog' });

const selectedRows = ref<LoginLog[]>([]);
const detailDrawerRef = ref();
const currentLog = ref<LoginLog>();

const statusOptions = getStatusOptions();
const loginTypeOptions = getLoginTypeOptions();
const failureReasonOptions = getFailureReasonOptions().map((item) => ({
  ...item,
  type: 'danger' as const,
}));
const deviceTypeOptions = getDeviceTypeOptions().map((item) => ({
  ...item,
  type: 'info' as const,
}));

async function onDetail(row: LoginLog) {
  try {
    const log = await getLoginLogDetailApi(row.id);
    currentLog.value = log;
    detailDrawerRef.value?.open();
  } catch (error) {
    ElMessage.error($t('loginLog.getDetailError'));
    console.error($t('loginLog.getDetailError'), error);
  }
}

function onDelete(row: LoginLog) {
  ElMessageBox.confirm(
    $t('loginLog.deleteConfirm', [row.username]),
    $t('common.delete'),
    {
      confirmButtonText: $t('common.confirm'),
      cancelButtonText: $t('common.cancel'),
      type: 'warning',
    },
  )
    .then(async () => {
      try {
        await deleteLoginLogApi(row.id);
        ElMessage.success($t('loginLog.deleteSuccess'));
        refreshGrid();
      } catch {
        ElMessage.error($t('loginLog.deleteError'));
      }
    })
    .catch(() => {});
}

function onBatchDelete() {
  if (selectedRows.value.length === 0) {
    ElMessage.warning($t('loginLog.selectLogsToDelete'));
    return;
  }

  const usernames = selectedRows.value.map((row) => row.username).join('、');
  const confirmMessage = $t('loginLog.batchDeleteConfirm', [
    selectedRows.value.length,
    usernames,
  ]);

  ElMessageBox.confirm(confirmMessage, $t('loginLog.batchDeleteTitle'), {
    confirmButtonText: $t('common.confirm'),
    cancelButtonText: $t('common.cancel'),
    type: 'warning',
  })
    .then(async () => {
      try {
        const ids = selectedRows.value.map((row) => row.id);
        await batchDeleteLoginLogApi(ids);
        ElMessage.success($t('loginLog.deleteSuccess'));
        selectedRows.value = [];
        refreshGrid();
      } catch {
        ElMessage.error($t('loginLog.deleteError'));
      }
    })
    .catch(() => {});
}

function handleSelectionChange(items: Record<string, any>[]) {
  selectedRows.value = items as LoginLog[];
}

const fetchLoginLogList = async (params: any) => {
  const res = await getLoginLogListApi({
    page: params.page.currentPage,
    pageSize: params.page.pageSize,
    username: params.form?.username,
    status: params.form?.status,
    login_type: params.form?.login_type,
  });
  return {
    items: res.items,
    total: res.total,
  };
};

const [Grid, gridApi] = useZqTable({
  gridOptions: {
    columns: useZqTableColumns(),
    border: true,
    stripe: true,
    showIndex: true,
    showSelection: true,
    proxyConfig: {
      autoLoad: true,
      ajax: {
        query: fetchLoginLogList,
      },
    },
    pagerConfig: {
      enabled: true,
      pageSize: 20,
    },
    toolbarConfig: {
      search: true,
      refresh: true,
      zoom: true,
      custom: true,
    },
  },
  formOptions: {
    schema: useSearchFormSchema(),
    showCollapseButton: true,
    submitOnChange: true,
  },
});

function refreshGrid() {
  gridApi.reload();
}
</script>

<template>
  <Page auto-content-height>
    <DetailDrawer ref="detailDrawerRef" :log="currentLog" />

    <Grid @selection-change="handleSelectionChange">
      <template #toolbar-actions>
        <ElButton type="danger" plain @click="onBatchDelete">
          {{ $t('loginLog.batchDelete') }}
          {{ selectedRows.length > 0 ? `(${selectedRows.length})` : '' }}
        </ElButton>
      </template>

      <template #cell-status="{ row }">
        <ElTag :type="getTagType(row.status, statusOptions)" size="small">
          {{ getTagLabel(row.status, statusOptions) }}
        </ElTag>
      </template>

      <template #cell-login_type="{ row }">
        <ElTag
          v-if="row.login_type"
          :type="getTagType(row.login_type, loginTypeOptions)"
          size="small"
        >
          {{ getTagLabel(row.login_type, loginTypeOptions) }}
        </ElTag>
        <span v-else>-</span>
      </template>

      <template #cell-failure_reason="{ row }">
        <ElTag
          v-if="row.failure_reason !== undefined && row.failure_reason !== null"
          :type="getTagType(row.failure_reason, failureReasonOptions)"
          size="small"
        >
          {{ getTagLabel(row.failure_reason, failureReasonOptions) }}
        </ElTag>
        <span v-else>-</span>
      </template>

      <template #cell-device_type="{ row }">
        <ElTag
          v-if="row.device_type"
          :type="getTagType(row.device_type, deviceTypeOptions)"
          size="small"
        >
          {{ getTagLabel(row.device_type, deviceTypeOptions) }}
        </ElTag>
        <span v-else>-</span>
      </template>

      <template #cell-actions="{ row }">
        <ElButton link type="primary" :icon="Eye" @click="onDetail(row)">
          {{ $t('loginLog.detail') }}
        </ElButton>
        <ElButton link type="danger" :icon="Trash2" @click="onDelete(row)">
          {{ $t('common.delete') }}
        </ElButton>
      </template>
    </Grid>
  </Page>
</template>
