<script lang="ts" setup>
import type { VxeGridProps } from '#/adapter/vxe-table';

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

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

import { useVbenVxeGrid } from '#/adapter/vxe-table';

import {
  formatPriceDisplay,
  isMarketGtPrice,
  isPriceChanged,
  type PricePair,
} from '../../admin/utils/priceCompare';

export type PriceCompareFilterTab =
  | 'all'
  | 'changed'
  | 'unchanged'
  | 'marketGtPrice'
  | 'new'
  | 'unmatched';

export type PriceCompareRow = {
  id: number;
  drug_id?: number;
  drug_name: string;
  drug_number: string;
  pinyin_simple?: string;
  orig_market_price: number;
  orig_price: number;
  market_price: number;
  price: number;
  _changed: boolean;
  _marketGtPrice: boolean;
  _isNew: boolean;
  _fromExcel?: boolean;
};

export type UnmatchedRow = {
  drug_name: string;
  drug_number: string;
  market_price: number;
  price: number;
};

const props = withDefaults(
  defineProps<{
    rows: PriceCompareRow[];
    unmatchedRows?: UnmatchedRow[];
    filterTab?: PriceCompareFilterTab;
    savingRowId?: number | null;
    gridMaxHeight?: string;
  }>(),
  {
    unmatchedRows: () => [],
    filterTab: 'all',
    savingRowId: null,
    gridMaxHeight: 'calc(100vh - 260px)',
  },
);

const emit = defineEmits<{
  'update:filterTab': [PriceCompareFilterTab];
  cellChange: [row: PriceCompareRow];
  rowSave: [row: PriceCompareRow];
}>();

const keyword = ref('');
const innerFilterTab = ref<PriceCompareFilterTab>(props.filterTab);

watch(
  () => props.filterTab,
  (v) => {
    innerFilterTab.value = v;
  },
);

watch(innerFilterTab, (v) => {
  emit('update:filterTab', v);
});

const tabCounts = computed(() => {
  const all = props.rows.length;
  const changed = props.rows.filter((r) => r._changed).length;
  const unchanged = all - changed;
  const marketGtPrice = props.rows.filter((r) => r._marketGtPrice).length;
  const newCount = props.rows.filter((r) => r._isNew).length;
  const unmatched = props.unmatchedRows.length;
  return { all, changed, unchanged, marketGtPrice, new: newCount, unmatched };
});

const filteredRows = computed(() => {
  const q = keyword.value.trim().toLowerCase();
  let list = props.rows;

  if (innerFilterTab.value === 'changed') {
    list = list.filter((r) => r._changed);
  } else if (innerFilterTab.value === 'unchanged') {
    list = list.filter((r) => !r._changed);
  } else if (innerFilterTab.value === 'marketGtPrice') {
    list = list.filter((r) => r._marketGtPrice);
  } else if (innerFilterTab.value === 'new') {
    list = list.filter((r) => r._isNew);
  }

  if (q) {
    list = list.filter((r) => {
      const nameOk = r.drug_name.toLowerCase().includes(q);
      const py = (r.pinyin_simple ?? '').toLowerCase();
      const numOk = r.drug_number.toLowerCase().includes(q);
      return nameOk || py.includes(q) || numOk;
    });
  }

  return list;
});

const showSaveColumn = computed(() => innerFilterTab.value === 'changed');

const gridColumns = computed(() => [
  { type: 'seq', width: 56, title: '序号', fixed: 'left' as const },
  {
    field: 'drug_name',
    title: '药品名称',
    minWidth: 140,
    fixed: 'left' as const,
  },
  { field: 'drug_number', title: '商品编码', width: 110 },
  {
    field: 'orig_market_price',
    title: '原供货价',
    width: 100,
    formatter: ({ cellValue }: { cellValue: unknown }) =>
      formatPriceDisplay(cellValue),
  },
  {
    field: 'market_price',
    title: '新供货价',
    width: 110,
    editRender: {
      name: 'input',
      props: { type: 'number', step: 0.01, min: 0 },
    },
    formatter: ({ cellValue }: { cellValue: unknown }) =>
      formatPriceDisplay(cellValue),
  },
  {
    field: 'orig_price',
    title: '原售价',
    width: 100,
    formatter: ({ cellValue }: { cellValue: unknown }) =>
      formatPriceDisplay(cellValue),
  },
  {
    field: 'price',
    title: '新售价',
    width: 110,
    editRender: {
      name: 'input',
      props: { type: 'number', step: 0.01, min: 0 },
    },
    formatter: ({ cellValue }: { cellValue: unknown }) =>
      formatPriceDisplay(cellValue),
  },
  {
    field: '_changed',
    title: '状态',
    width: 96,
    slots: { default: 'status' },
  },
  ...(showSaveColumn.value
    ? [
      {
        title: '操作',
        width: 88,
        fixed: 'right' as const,
        slots: { default: 'action' },
      },
    ]
    : []),
]);

const gridOptions = computed<VxeGridProps<PriceCompareRow>>(() => ({
  data: filteredRows.value,
  height: props.gridMaxHeight,
  border: true,
  stripe: true,
  showOverflow: true,
  proxyConfig: {
    enabled: false,
    autoLoad: false,
  },
  rowConfig: {
    useKey: true,
    keyField: 'id',
    isHover: true,
  },
  columnConfig: {
    useKey: true,
  },
  editConfig: {
    mode: 'cell',
    trigger: 'click',
    showStatus: true,
  },
  rowClassName: ({ row }: { row: PriceCompareRow }) => {
    // Enhanced status classes for visual hierarchy
    if (row._marketGtPrice) {
      return 'excel-compare-row-warning';
    }
    if (row._changed) {
      return 'excel-compare-row-changed';
    }
    return 'excel-compare-row-normal';
  },
  columns: gridColumns.value,
}));

function onEditClosed(params: { row: PriceCompareRow }) {
  const row = params.row;
  const snapshot: PricePair = {
    market_price: row.orig_market_price,
    price: row.orig_price,
  };
  const current: PricePair = {
    market_price: row.market_price,
    price: row.price,
  };
  row._changed = isPriceChanged(snapshot, current);
  row._marketGtPrice = isMarketGtPrice(current);
  emit('cellChange', { ...row });
}

function handleRowSave(row: PriceCompareRow) {
  emit('rowSave', row);
}

const [Grid, gridApi] = useVbenVxeGrid({
  gridOptions,
  gridEvents: {
    editClosed: onEditClosed,
  },
});

async function refreshGridData() {
  await nextTick();
  const data = filteredRows.value;
  gridApi.setGridOptions({
    data,
    columns: gridColumns.value,
    height: props.gridMaxHeight,
  });
  if (gridApi.grid?.loadData) {
    await gridApi.grid.loadData(data);
  }
  gridApi.grid?.recalculate?.();
}

watch([filteredRows, showSaveColumn, () => props.rows, () => props.gridMaxHeight], refreshGridData, {
  deep: true,
  flush: 'post',
});
</script>

<template>
  <div class="excel-compare-grid min-h-0 flex-1 flex flex-col">
    <!-- Header Controls -->
    <div class="mb-4 flex flex-wrap items-center gap-3">
      <Input
        v-model:value="keyword"
        allow-clear
        class="max-w-xs !rounded-lg shadow-sm"
        placeholder="按药品名称、编码或拼音筛选"
      />
      <Tag class="!rounded-full !border-gray-200 !bg-white px-3 py-1 shadow-sm dark:!border-gray-700 dark:!bg-gray-800">
        {{ filteredRows.length }} 条
      </Tag>
    </div>

    <!-- Segmented Control -->
    <Segmented
      v-model:value="innerFilterTab"
      class="mb-4 flex-wrap !rounded-lg !p-1 shadow-sm"
      :options="[
        { label: `全部 ${tabCounts.all}`, value: 'all' },
        { label: `有修改 ${tabCounts.changed}`, value: 'changed' },
        { label: `无修改 ${tabCounts.unchanged}`, value: 'unchanged' },
        {
          label: `供价超售价 ${tabCounts.marketGtPrice}`,
          value: 'marketGtPrice',
        },
        { label: `待新增 ${tabCounts.new}`, value: 'new' },
        { label: `未匹配 ${tabCounts.unmatched}`, value: 'unmatched' },
      ]"
    />

    <!-- Main Grid / List -->
    <div class="relative flex-1 min-h-0 overflow-hidden rounded-xl border border-gray-200 shadow-sm dark:border-gray-700">
      <Transition name="fade" mode="out-in">
        <Grid v-if="innerFilterTab !== 'unmatched'" class="h-full min-h-0">
          <template #status="{ row }">
            <Tag v-if="row._isNew" color="processing" class="!border-blue-200 shadow-sm">待新增</Tag>
            <Tag v-else-if="row._changed" color="warning" class="!border-amber-200 shadow-sm">已变更</Tag>
            <Tag v-else color="default" class="!bg-gray-50 dark:!bg-gray-800">无变化</Tag>
          </template>
          <template #action="{ row }">
            <Button
              :loading="savingRowId === row.id"
              size="small"
              type="primary"
              ghost
              class="!rounded-md"
              @click="handleRowSave(row)"
            >
              保存
            </Button>
          </template>
        </Grid>

        <!-- Unmatched Rows View -->
        <div
          v-else
          class="h-full overflow-auto bg-gradient-to-b from-orange-50/50 to-orange-50/10 p-4 custom-scrollbar dark:from-orange-950/20 dark:to-transparent"
        >
          <div
            v-if="unmatchedRows.length === 0"
            class="flex h-full items-center justify-center text-sm text-gray-400"
          >
            暂无未匹配行
          </div>
          <TransitionGroup name="list" tag="div" class="space-y-2">
            <div
              v-for="(row, index) in unmatchedRows"
              :key="`${row.drug_name}-${index}`"
              class="group flex items-center justify-between rounded-lg bg-white p-3 shadow-sm transition-all hover:shadow-md dark:bg-gray-800"
            >
              <div class="flex items-center gap-3">
                <span class="font-medium text-gray-800 dark:text-gray-200">{{ row.drug_name || '—' }}</span>
                <span class="rounded bg-gray-100 px-2 py-0.5 text-xs text-gray-500 dark:bg-gray-700">{{ row.drug_number || '—' }}</span>
              </div>
              <div class="flex gap-4 text-sm text-gray-600 dark:text-gray-400">
                <span>供货价 <strong class="font-semibold text-gray-800 dark:text-gray-200">{{ formatPriceDisplay(row.market_price) }}</strong></span>
                <span class="text-gray-300">|</span>
                <span>售价 <strong class="font-semibold text-gray-800 dark:text-gray-200">{{ formatPriceDisplay(row.price) }}</strong></span>
              </div>
            </div>
          </TransitionGroup>
        </div>
      </Transition>
    </div>
  </div>
</template>

<style scoped>
/* Modern styling for vxe-table custom rows */
/* Use subtle tinting instead of harsh solid colors, add a left accent border */

:deep(.excel-compare-row-changed) > td {
  background-color: rgba(253, 246, 227, 0.6) !important; /* Soft Amber */
}
:deep(.excel-compare-row-changed) > td:first-child {
  box-shadow: inset 3px 0 0 0 #f59e0b; /* Amber accent */
}

:deep(.dark .excel-compare-row-changed) > td {
  background-color: rgba(120, 53, 15, 0.15) !important;
}
:deep(.dark .excel-compare-row-changed) > td:first-child {
  box-shadow: inset 3px 0 0 0 #d97706;
}

:deep(.excel-compare-row-warning) > td {
  background-color: rgba(254, 242, 242, 0.7) !important; /* Soft Red */
}
:deep(.excel-compare-row-warning) > td:first-child {
  box-shadow: inset 3px 0 0 0 #ef4444; /* Red accent */
}

:deep(.dark .excel-compare-row-warning) > td {
  background-color: rgba(127, 29, 29, 0.15) !important;
}
:deep(.dark .excel-compare-row-warning) > td:first-child {
  box-shadow: inset 3px 0 0 0 #dc2626;
}

:deep(.excel-compare-row-normal) > td {
  transition: background-color 0.2s ease;
}

/* Transitions for Unmatched List */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

.list-enter-active,
.list-leave-active {
  transition: all 0.3s ease;
}
.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateX(-10px);
}

/* Custom Scrollbar */
.custom-scrollbar::-webkit-scrollbar {
  width: 6px;
}
.custom-scrollbar::-webkit-scrollbar-track {
  background: transparent;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
  background-color: rgba(156, 163, 175, 0.3);
  border-radius: 20px;
}
.custom-scrollbar:hover::-webkit-scrollbar-thumb {
  background-color: rgba(156, 163, 175, 0.5);
}
</style>
