<script lang="ts" setup>
/**
 * 病历词条列表（公共/门店共用）
 * - scope=public → store_id=0；scope=store → 当前登录门店
 * - fixedFieldCode：按字段拆分菜单时锁定字段，隐藏字段筛选
 * - 支持 Excel 导入 + 手动同步空拼音首拼
 */
import type { VxeGridListeners } from '#/adapter/vxe-table';

import { computed, ref, watch } from 'vue';

import { Page, useVbenModal } from '@vben/common-ui';

import { Button, message, Modal as AntModal, Tag, Upload } from 'ant-design-vue';

import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { TableAction } from '#/components/table-action';
import { downloadByData } from '#/util/tool';

import {
  deleteMedicalRecordEntry,
  getMedicalRecordEntryList,
  importMedicalRecordEntry,
  syncMedicalRecordEntryPinyin,
} from '../api';
import { MEDICAL_RECORD_FIELD_OPTIONS, STATUS_OPTIONS } from '../config/constants';
import { exportMedicalRecordEntryTemplate } from '../utils/exportMedicalRecordEntryExcel';
import { parseMedicalRecordEntryExcelBuffer } from '../utils/parseMedicalRecordEntryExcel';
import EntryModal from './EntryModal.vue';

const props = defineProps<{
  scope: 'public' | 'store';
  pageTitle: string;
  pageName: string;
  /** 锁定字段编码（按类型拆菜单时传入） */
  fixedFieldCode?: string;
}>();

defineOptions({ name: 'MedicalRecordEntryList' });

const hasTopTableDropDownActions = ref(false);
const importing = ref(false);
const syncing = ref(false);

const formOptions = computed(() => {
  const schema: any[] = [
    {
      component: 'VbenInput',
      fieldName: 'title',
      label: '词条名称',
      componentProps: { placeholder: '名称/首拼模糊搜索' },
    },
  ];
  if (!props.fixedFieldCode) {
    schema.push({
      component: 'VbenSelect',
      fieldName: 'field_code',
      label: '所属字段',
      componentProps: {
        allowClear: true,
        options: MEDICAL_RECORD_FIELD_OPTIONS,
      },
    });
  }
  schema.push({
    component: 'VbenSelect',
    fieldName: 'status',
    label: '状态',
    componentProps: { allowClear: true, options: STATUS_OPTIONS },
  });
  return { schema };
});

const gridOptions = computed(() => ({
  checkboxConfig: { highlight: true, labelField: '' },
  columns: [
    { type: 'checkbox', width: 60 },
    { field: 'id', title: 'ID', width: 80 },
    ...(props.fixedFieldCode
      ? []
      : [{ field: 'field_code_txt', title: '字段', width: 120 }]),
    { field: 'title', title: '词条名称', minWidth: 140 },
    { field: 'pinyin_initials', title: '首拼(全拼)', minWidth: 160 },
    { field: 'content', title: '正文', minWidth: 200 },
    { field: 'remark', title: '临床意义', width: 140 },
    { field: 'status', title: '状态', width: 90, slots: { default: 'status' } },
    { field: 'sort', title: '排序', width: 80 },
    { field: 'created_at', title: '创建时间', width: 170 },
    { title: '操作', slots: { default: 'action' }, width: 160, fixed: 'right' },
  ],
  keepSource: true,
  pagerConfig: {},
  proxyConfig: {
    ajax: {
      query: async ({ page }: any, formValues: any) => {
        return await getMedicalRecordEntryList({
          page: page.currentPage,
          pageSize: page.pageSize,
          scope: props.scope,
          field_code: props.fixedFieldCode || undefined,
          ...formValues,
          ...(props.fixedFieldCode ? { field_code: props.fixedFieldCode } : {}),
        });
      },
    },
  },
  height: 'auto',
  toolbarConfig: {
    search: true,
    refresh: true,
    slots: { buttons: 'toolbar-actions' },
  },
}));

const gridEvents: VxeGridListeners<any> = {
  checkboxChange() {
    hasTopTableDropDownActions.value =
      gridApi.grid.getCheckboxRecords().length > 0;
  },
  checkboxAll() {
    hasTopTableDropDownActions.value =
      gridApi.grid.getCheckboxRecords().length > 0;
  },
};

const [Grid, gridApi] = useVbenVxeGrid({
  formOptions: formOptions.value as any,
  gridOptions: gridOptions.value as any,
  gridEvents,
});

watch(
  () => props.fixedFieldCode,
  () => {
    gridApi.reload?.();
  },
);

const [FormModal, formModalApi] = useVbenModal({
  connectedComponent: EntryModal,
});

const showModal = (data: any = {}, isUpdate = false) => {
  formModalApi.setData({
    values: {
      ...data,
      ...(props.fixedFieldCode && !isUpdate
        ? { field_code: props.fixedFieldCode }
        : {}),
    },
    update: isUpdate,
    gridApi,
    scope: props.scope,
    fixedFieldCode: props.fixedFieldCode || '',
  });
  formModalApi.open();
};

const handleDelete = async (ids: number[]) => {
  await deleteMedicalRecordEntry({ ids });
  message.success('删除成功');
  gridApi.query();
};

async function handleDownloadTemplate() {
  const buffer = await exportMedicalRecordEntryTemplate();
  downloadByData(
    buffer,
    '病历词条导入模板.xlsx',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  );
}

async function handleImportFile(file: File) {
  importing.value = true;
  try {
    const buffer = await file.arrayBuffer();
    // 按字段拆分页传入 defaultFieldCode：允许 Excel 字段编码留空 / 填中文名
    const parsed = await parseMedicalRecordEntryExcelBuffer(buffer, {
      defaultFieldCode: props.fixedFieldCode || '',
    });
    let rows = parsed.items;
    if (props.fixedFieldCode) {
      rows = rows
        .map((r) => ({ ...r, field_code: props.fixedFieldCode as string }))
        .filter((r) => r.title);
    }
    if (!rows.length) {
      const detail = parsed.firstInvalidReason
        ? `：${parsed.firstInvalidReason}`
        : '';
      message.warning(
        parsed.invalidCount
          ? `没有可导入的有效行（无效 ${parsed.invalidCount} 行）${detail}`
          : '文件无有效数据，请确认填写的是「词条导入」工作表',
      );
      return false;
    }
    const res = await importMedicalRecordEntry({
      scope: props.scope,
      rows,
    });
    const success = Number(res?.success ?? 0);
    const fail = Number(res?.fail ?? 0);
    const errors = Array.isArray(res?.errors) ? res.errors : [];
    if (fail > 0) {
      message.warning(
        `导入完成：成功 ${success}，失败 ${fail}${
          errors.length ? `；${errors.slice(0, 3).join('；')}` : ''
        }`,
      );
    } else {
      message.success(`成功导入 ${success} 条`);
    }
    gridApi.reload();
  } catch (e: any) {
    message.error(e?.message || '导入失败');
  } finally {
    importing.value = false;
  }
  return false;
}

/** 手动同步当前 scope 下空拼音首拼 */
function handleSyncPinyin() {
  AntModal.confirm({
    title: '同步拼音首拼',
    content: '将扫描拼音为空的词条并自动生成，已有值不会覆盖。确认执行？',
    onOk: async () => {
      syncing.value = true;
      try {
        const res = await syncMedicalRecordEntryPinyin({ scope: props.scope });
        message.success(
          `同步完成：更新 ${Number(res?.updated || 0)} 条，跳过 ${Number(res?.skipped || 0)} 条`,
        );
        gridApi.query();
      } finally {
        syncing.value = false;
      }
    },
  });
}
</script>
<template>
  <Page auto-content-height :title="pageTitle">
    <FormModal />
    <Grid>
      <template #toolbar-actions>
        <TableAction
          :actions="[
            {
              label: '新增词条',
              type: 'primary',
              onClick: () => showModal({}, false),
            },
            {
              label: '下载模板',
              onClick: () => handleDownloadTemplate(),
            },
            {
              label: '批量删除',
              danger: true,
              ifShow: () => hasTopTableDropDownActions,
              popConfirm: {
                title: '确认删除所选词条？',
                confirm: () => {
                  const ids = gridApi.grid
                    .getCheckboxRecords()
                    .map((r: any) => r.id);
                  handleDelete(ids);
                },
              },
            },
          ]"
        />
        <Upload
          :show-upload-list="false"
          accept=".xlsx,.xls"
          :before-upload="handleImportFile"
          class="ml-2 inline-block"
        >
          <Button :loading="importing">导入 Excel</Button>
        </Upload>
        <Button class="ml-2" :loading="syncing" @click="handleSyncPinyin">
          同步拼音首拼
        </Button>
      </template>
      <template #status="{ row }">
        <Tag :color="row.status === 1 ? 'success' : 'default'">
          {{ row.status_txt || (row.status === 1 ? '启用' : '禁用') }}
        </Tag>
      </template>
      <template #action="{ row }">
        <TableAction
          :actions="[
            { label: '编辑', onClick: () => showModal(row, true) },
            {
              label: '删除',
              danger: true,
              popConfirm: {
                title: '确认删除？',
                confirm: () => handleDelete([row.id]),
              },
            },
          ]"
        />
      </template>
    </Grid>
  </Page>
</template>
