<script lang="ts" setup>

import type {

  SpreadsheetBatchCellChange,

  SpreadsheetColumnConfig,

  SpreadsheetTableConfig,

} from '#/components/canvas-spreadsheet';



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



import { useUserStore } from '@vben/stores';



import { message } from 'ant-design-vue';



import {

  listSpreadsheetTableConfig,

  updateSpreadsheetTableConfig,

} from '#/api/spreadsheet-table-config';

import { CanvasSpreadsheet } from '#/components/canvas-spreadsheet';



import {

  applyBatchPriceApi,

  getAllForBatchPriceApi,

  type WarehouseBatchPriceItem,

} from '../api';

import type { SpreadsheetConfigJson } from '../config/spreadsheetDefaults';

import {

  getWarehouseSpreadsheetDefaults,

  mergeSpreadsheetConfig,

  WAREHOUSE_SPREADSHEET_TABLE_NAME,

  warehouseSpreadsheetSheetKey,

} from '../config/spreadsheetDefaults';

import { normalizePricePair, parsePriceValue } from '../utils/priceCompare';

import { canManageSpreadsheetConfig } from '../utils/spreadsheetAdminRole';



import SpreadsheetAddColumnModal from './SpreadsheetAddColumnModal.vue';

import SpreadsheetSetColumnModal from './SpreadsheetSetColumnModal.vue';



const props = defineProps<{

  productType: number;

}>();



const emit = defineEmits<{

  openConfig: [];

}>();



const userStore = useUserStore();



const loading = ref(false);

const configLoading = ref(false);



const rows = ref<WarehouseBatchPriceItem[]>([]);

const sheetData = ref<Record<string, unknown>[]>([]);



const mergedConfig = ref(getWarehouseSpreadsheetDefaults(props.productType));

const activeConfigId = ref<number | null>(null);

const workbookName = ref('默认');



const addColumnModalRef = ref<InstanceType<

  typeof SpreadsheetAddColumnModal

> | null>(null);

const setColumnModalRef = ref<InstanceType<

  typeof SpreadsheetSetColumnModal

> | null>(null);



const showConfigButton = computed(() =>

  canManageSpreadsheetConfig(userStore.userInfo),

);



async function loadSpreadsheetConfig() {

  configLoading.value = true;

  try {

    const defaults = getWarehouseSpreadsheetDefaults(props.productType);

    const list = await listSpreadsheetTableConfig({

      table_name: WAREHOUSE_SPREADSHEET_TABLE_NAME,

      sheet_key: warehouseSpreadsheetSheetKey(props.productType),

    });

    const picked =

      list.find((i) => i.is_default === 1) ?? list[0] ?? null;

    activeConfigId.value = picked?.id ?? null;

    workbookName.value = picked?.name ?? '默认';

    mergedConfig.value = mergeSpreadsheetConfig(picked?.config, defaults);

  } catch {

    activeConfigId.value = null;

    workbookName.value = '默认';

    mergedConfig.value = getWarehouseSpreadsheetDefaults(props.productType);

  } finally {

    configLoading.value = false;

  }

}



async function persistConfig(config: SpreadsheetConfigJson) {

  if (!activeConfigId.value) {

    message.error('未找到可写入的配置，请先在 Excel 配置中创建');

    return false;

  }

  await updateSpreadsheetTableConfig({

    id: activeConfigId.value,

    config,

  });

  mergedConfig.value = config;

  message.success('配置已保存');

  return true;

}



async function handleConfigSave(config: SpreadsheetConfigJson) {

  await persistConfig(config);

}



async function handleFormulaUpdate(payload: { col: number; formula: string }) {

  const columns = mergedConfig.value.columns.map((c) =>

    c.col === payload.col ? { ...c, formula: payload.formula } : c,

  );

  await persistConfig({ ...mergedConfig.value, columns });

}



function onAdminAddColumn() {

  addColumnModalRef.value?.open();

}



function onAdminSetColumn(col: number) {

  setColumnModalRef.value?.open(col);

}



async function handleBatchPriceEdit(changes: SpreadsheetBatchCellChange[]) {

  if (changes.length === 0) return;



  const rowMap = new Map<number, Record<string, unknown>>();



  for (const ch of changes) {

    const id = Number(ch.ctx.rowKey);

    const row = sheetData.value.find((r) => String(r.id) === String(id));

    if (!row) continue;



    if (!rowMap.has(id)) {

      rowMap.set(id, { ...row });

    }



    rowMap.get(id)![ch.ctx.fieldId] = parsePriceValue(ch.after);

  }



  const updates = [...rowMap.entries()].map(([id, row]) => {

    const pair = normalizePricePair({

      market_price: parsePriceValue(row.market_price),

      price: parsePriceValue(row.price),

    });



    return {

      id,

      market_price: pair.market_price,

      price: pair.price,

    };

  });



  await applyBatchPriceApi({

    type: props.productType,

    updates,

    notify: false,

  });



  for (const [id, row] of rowMap) {

    const sheetRow = sheetData.value.find((r) => Number(r.id) === id);

    if (!sheetRow) continue;

    sheetRow.market_price = parsePriceValue(row.market_price);

    sheetRow.price = parsePriceValue(row.price);

  }



  message.success('保存成功');

}



const tableConfig = computed<SpreadsheetTableConfig>(() => ({

  tableName: WAREHOUSE_SPREADSHEET_TABLE_NAME,

  sheetKey: warehouseSpreadsheetSheetKey(props.productType),

  enableFilter: mergedConfig.value.enableFilter ?? true,

  enableHistory: mergedConfig.value.enableHistory ?? true,

  rowHeight: mergedConfig.value.rowHeight ?? 'auto',

  defaultColWidth: mergedConfig.value.defaultColWidth ?? 120,

  defaultTextAlign: mergedConfig.value.defaultTextAlign ?? 'left',

  onBatchEdit: handleBatchPriceEdit,

  onRefresh: refreshData,

  headers: mergedConfig.value.headers,

}));



const columns = computed<SpreadsheetColumnConfig[]>(

  () => mergedConfig.value.columns,

);



async function refreshData() {

  const res = await getAllForBatchPriceApi({ type: props.productType });

  rows.value = res.items ?? [];

  sheetData.value = rows.value.map((item) => ({

    id: item.id,

    drug_id: item.drug_id,

    drug_name: item.drug_name,

    pinyin_simple: item.pinyin_simple,

    drug_number: item.drug_number,

    market_price: parsePriceValue(item.market_price),

    price: parsePriceValue(item.price),

  }));

}



async function loadData() {

  loading.value = true;

  try {

    await Promise.all([loadSpreadsheetConfig(), refreshData()]);

  } finally {

    loading.value = false;

  }

}



function onSheetChange(payload: { data: Record<string, unknown>[] }) {

  sheetData.value = payload.data;

}



async function reloadConfig() {

  await loadSpreadsheetConfig();

}



defineExpose({ reloadConfig });



onMounted(loadData);

</script>



<template>

  <div class="warehouse-drug-excel-view">

    <CanvasSpreadsheet

      :key="`${productType}-${columns.length}-${tableConfig.headers.length}-${activeConfigId}`"

      :columns="columns"

      :data="sheetData"

      :loading="loading || configLoading"

      :show-config-button="showConfigButton"

      :table-config="tableConfig"

      :workbook-name="workbookName"

      class="warehouse-excel-canvas"

      row-key-field="id"

      @admin-add-column="onAdminAddColumn"

      @admin-set-column="onAdminSetColumn"

      @change="onSheetChange"

      @open-config="emit('openConfig')"

      @update-column-formula="handleFormulaUpdate"

    />



    <SpreadsheetAddColumnModal

      ref="addColumnModalRef"

      :config="mergedConfig"

      @save="handleConfigSave"

    />

    <SpreadsheetSetColumnModal

      ref="setColumnModalRef"

      :config="mergedConfig"

      @save="handleConfigSave"

    />

  </div>

</template>



<style scoped lang="scss">

.warehouse-drug-excel-view {

  flex: 1;

  min-height: 0;

  height: 100%;

  display: flex;

  flex-direction: column;

}



.warehouse-excel-canvas {

  flex: 1;

  min-height: 0;

}

</style>

