<script lang="ts" setup>
/**
 * 处方订单管理页
 *
 * 支持「列表 / 卡片」双视图切换（通用 ViewModeSwitch + useViewMode 记忆偏好）：
 * - 搜索表单从 grid 内嵌拆出为顶部统一 SearchForm，双视图共用同一份条件
 * - 状态 Tabs（待审核/已通过/已拒绝）与搜索条件合并后同时驱动两个视图
 * - 卡片视图展示内容与列表一致，行操作复用同一批弹窗
 */
import type { VxeGridListeners } from '#/adapter/vxe-table';

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

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

import { Button, Tabs, Tag } from 'ant-design-vue';

import { useVbenForm } from '#/adapter/form';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { TableAction } from '#/components/table-action';
import { useViewMode, ViewModeSwitch } from '#/components/view-mode-switch';
import StoreCardModal from '#/components/store-card/StoreCardModal.vue';
import PrescriptionDetail from '#/views/doctor/doctor-reception/components/PrescriptionDetail.vue';

import { getPrescriptionListApi } from './api';
import PrescriptionOrderCardList from './components/PrescriptionOrderCardList.vue';
import PrescriptionSource from './components/source.vue';
import {
  PRESCRIPTION_IS_ONLINE_FALLBACK,
  PRESCRIPTION_IS_ONLINE_MAP,
  PRESCRIPTION_ORDER_TYPE_MAP,
  PRESCRIPTION_STATUS_MAP,
} from './config/constants';
import { formOptions } from './config/search';
import { gridOptions as baseGridOptions } from './config/table';

const hasTopTableDropDownActions = ref(false);
/** 审核状态 Tab：0待审核 / 1已通过 / 2已拒绝 */
const statusTab = ref('0');

/** 列表/卡片双视图：通用 useViewMode 自带 localStorage 记忆 */
const viewMode = useViewMode('prescription-order-view-mode');

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

/**
 * 从 schema 提取 defaultValue 作为首屏搜索条件
 * 双视图首屏都要带默认时间范围，保证查询口径与表单显示一致
 */
function collectDefaultSearchValues(): Record<string, any> {
  const values: Record<string, any> = {};
  for (const item of formOptions.schema ?? []) {
    if (item.fieldName && item.defaultValue !== undefined) {
      values[item.fieldName] = item.defaultValue;
    }
  }
  return values;
}

/** 列表与卡片共用的搜索条件（不含 status Tab，Tab 单独合并） */
const searchValues = ref<Record<string, any>>(collectDefaultSearchValues());

/** 卡片视图最终条件：搜索条件 + 状态 Tab（computed 保证 Tab 切换时卡片自动重拉） */
const cardFormValues = computed(() => ({
  ...searchValues.value,
  status: Number(statusTab.value),
}));

/**
 * 顶部统一搜索表单（从 grid 内嵌表单抽出，双视图共用）
 * 列表模式提交后 reload 回第 1 页；卡片模式由 cardFormValues watch 自动拉数
 */
const [SearchForm, searchFormApi] = useVbenForm({
  ...formOptions,
  handleSubmit: async (values) => {
    searchValues.value = { ...(values || {}) };
    if (viewMode.value === 'list') {
      gridApi.reload();
    }
  },
  handleReset: async () => {
    // 自定义 handleReset 会接管默认行为，必须手动还原控件到 defaultValue（reset 为新 API，resetForm 已弃用）
    await searchFormApi.reset();
    searchValues.value = collectDefaultSearchValues();
    if (viewMode.value === 'list') {
      gridApi.reload();
    }
  },
});

const [StoreCardModalComp, StoreCardModalApi] = useVbenModal({
  connectedComponent: StoreCardModal,
});

function openStoreCard(storeId?: number) {
  if (!storeId) return;
  StoreCardModalApi.setData({ storeId: Number(storeId) });
  StoreCardModalApi.open();
}

const [Grid, gridApi] = useVbenVxeGrid({
  gridOptions: {
    ...baseGridOptions,
    // 搜索已抽出为顶部统一表单，关闭 grid 自带的表单开关按钮
    toolbarConfig: { ...baseGridOptions.toolbarConfig, search: false },
    proxyConfig: {
      ajax: {
        /** 始终合并顶部统一搜索条件 + 状态 Tab */
        query: async ({ page }: { page: { currentPage: number; pageSize: number } }) => {
          return await getPrescriptionListApi({
            page: page.currentPage,
            pageSize: page.pageSize,
            status: Number(statusTab.value),
            ...searchValues.value,
          });
        },
      },
    },
  },
  gridEvents,
});

// Tab 切换：列表模式重查（卡片模式由 cardFormValues computed 触发 CardList watch）
watch(statusTab, () => {
  if (viewMode.value === 'list') {
    gridApi.query();
  }
});

// 记忆持久化由 useViewMode 内部完成；切回列表时 grid 被 v-if 卸载过需主动重查
watch(viewMode, (mode, prev) => {
  if (mode === 'list' && prev === 'card') {
    gridApi.query();
  }
});

function onStatusTabChange(key: number | string) {
  statusTab.value = String(key);
}

const [PrescriptionDetailModal, PrescriptionDetailModalApi] = useVbenModal({
  connectedComponent: PrescriptionDetail,
});

const [PrescriptionSourceModal, PrescriptionSourceModalApi] = useVbenModal({
  connectedComponent: PrescriptionSource,
});

const openPrescriptionDetail = (values: number) => {
  PrescriptionDetailModalApi.setData({ values });
  PrescriptionDetailModalApi.open();
};

const openPrescriptionSourceModal = (id: number) => {
  PrescriptionSourceModalApi.setData({ id });
  PrescriptionSourceModalApi.open();
};

/** 列表槽用元数据取值 helper：v-if 双重索引无法类型收窄，统一在这里兜底 */
function rowTypeMeta(row: Record<string, any>) {
  return PRESCRIPTION_ORDER_TYPE_MAP[Number(row?.prescription_type)] ?? null;
}
function rowStatusMeta(row: Record<string, any>) {
  return PRESCRIPTION_STATUS_MAP[Number(row?.status)] ?? null;
}
function rowIsOnlineMeta(row: Record<string, any>) {
  return PRESCRIPTION_IS_ONLINE_MAP[Number(row?.is_online)] ?? PRESCRIPTION_IS_ONLINE_FALLBACK;
}
</script>

<template>
  <Page auto-content-height title="处方管理">
    <PrescriptionDetailModal />
    <PrescriptionSourceModal />
    <StoreCardModalComp />
    <div class="mb-3">
      <Tabs :active-key="statusTab" @change="onStatusTabChange">
        <Tabs.TabPane key="0" tab="待审核" />
        <Tabs.TabPane key="1" tab="已通过" />
        <Tabs.TabPane key="2" tab="已拒绝" />
      </Tabs>
    </div>
    <!-- 顶部统一搜索（双视图共用，替代原 grid 内嵌表单） -->
    <div class="mb-3 rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--card,var(--background)))] p-3">
      <SearchForm />
    </div>
    <!-- 视图切换：列表 / 卡片看板 -->
    <div class="mb-3 flex items-center justify-between gap-3">
      <ViewModeSwitch v-model="viewMode" />
    </div>
    <Grid v-if="viewMode === 'list'">
      <template #toolbar-actions>
        <TableAction :actions="[]" :drop-down-actions="[]">
          <template #more>
            <Button style="margin-left: 16px">
              批量操作
            </Button>
          </template>
        </TableAction>
      </template>
      <template #store-name="{ row }">
        <Button
          v-if="row.store?.id || row.store_id"
          type="link"
          size="small"
          class="!px-0"
          @click="openStoreCard(row.store?.id || row.store_id)"
        >
          {{ row.store?.name || '—' }}
        </Button>
        <span v-else>{{ row.store?.name || '—' }}</span>
      </template>
      <template #status="{ row }">
        <!-- 处方类型与审核状态渲染统一走 constants 映射，与卡片视图同语义 -->
        <div>
          <Tag v-if="rowTypeMeta(row)" :color="rowTypeMeta(row)!.color">
            {{ rowTypeMeta(row)!.label }}
          </Tag>
        </div>
        <div class="mt-3">
          <Tag v-if="rowStatusMeta(row)" :color="rowStatusMeta(row)!.color">
            {{ rowStatusMeta(row)!.label
            }}<template v-if="row.status === 2 && row.reject_reason">
              ：{{ row.reject_reason }}</template
            >
          </Tag>
        </div>
      </template>
      <template #is-online="{ row }">
        <Tag :color="rowIsOnlineMeta(row).color">
          {{ rowIsOnlineMeta(row).label }}
        </Tag>
      </template>
      <template #toolbar-tools></template>
      <template #action="{ row }">
        <TableAction
          :actions="[
            {
              label: '查看处方',
              type: 'link',
              icon: 'marketeq:eye',
              onClick: openPrescriptionDetail.bind(null, row.id),
            },
            {
              label: '处方溯源',
              type: 'link',
              icon: 'mdi:timeline-text',
              onClick: openPrescriptionSourceModal.bind(null, row.id),
            },
          ]"
          :drop-down-actions="[]"
        />
      </template>
    </Grid>
    <!-- 卡片看板视图：展示内容与列表一致，弹窗复用父级（纯查看操作，无需操作后刷新句柄） -->
    <div v-else class="rx-card-wrap">
      <PrescriptionOrderCardList
        :form-values="cardFormValues"
        @open-detail="openPrescriptionDetail"
        @open-source="openPrescriptionSourceModal"
        @open-store="openStoreCard"
      />
    </div>
  </Page>
</template>
<style scoped lang="scss">
/* 卡片看板容器：撑满剩余高度，内部滚动（Tabs + 收起态搜索一行 + 切换行约 220px，min-height 兜底） */
.rx-card-wrap {
  height: calc(100% - 220px);
  min-height: 420px;
}
</style>
