<script lang="ts" setup>
import { computed, ref, watch } from 'vue';

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

import {
  formatPriceDisplay,
  getPriceDelta,
  isFieldChanged,
  isMarketGtPrice,
  isPriceChanged,
  type PriceDelta,
  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;
  _marketDelta: PriceDelta;
  _priceDelta: PriceDelta;
  _marketChanged: boolean;
  _priceChanged: 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;
  }>(),
  {
    unmatchedRows: () => [],
    filterTab: 'all',
    savingRowId: null,
  },
);

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;
});

function deltaClass(delta: PriceDelta): string {
  if (delta === 'up') {
    return 'text-rose-500 bg-rose-50 px-1 rounded dark:text-rose-400 dark:bg-rose-500/10 font-medium';
  }
  if (delta === 'down') {
    return 'text-emerald-500 bg-emerald-50 px-1 rounded dark:text-emerald-400 dark:bg-emerald-500/10 font-medium';
  }
  return 'text-gray-400 dark:text-gray-500';
}

function deltaSymbol(delta: PriceDelta): string {
  if (delta === 'up') return '↑';
  if (delta === 'down') return '↓';
  return '';
}

function cardClass(row: PriceCompareRow): string[] {
  // Enhanced card UI with smooth transitions and hover physics
  const classes = [
    'relative group rounded-xl border p-3 shadow-sm transition-all duration-300 ease-out hover:-translate-y-1 hover:shadow-md dark:bg-gray-800/80',
  ];
  if (row._isNew) {
    classes.push('border-blue-200 bg-blue-50/30 dark:border-blue-500/30 dark:bg-blue-900/10');
  } else if (row._marketGtPrice) {
    classes.push(
      'border-red-200 bg-red-50/50 ring-1 ring-red-100 dark:border-red-500/40 dark:bg-red-900/10 dark:ring-red-900/30',
    );
  } else if (row._changed) {
    classes.push(
      'border-amber-200 bg-amber-50/50 dark:border-amber-500/30 dark:bg-amber-900/10',
    );
  } else {
    classes.push('border-gray-100 bg-white dark:border-gray-700/60');
  }
  return classes;
}

function refreshRowFlags(row: PriceCompareRow) {
  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._marketDelta = getPriceDelta(snapshot.market_price, current.market_price);
  row._priceDelta = getPriceDelta(snapshot.price, current.price);
  row._marketChanged = isFieldChanged(
    snapshot.market_price,
    current.market_price,
  );
  row._priceChanged = isFieldChanged(snapshot.price, current.price);
  row._changed = row._isNew || isPriceChanged(snapshot, current);
  row._marketGtPrice = isMarketGtPrice(current);
}

function onPriceChange(
  row: PriceCompareRow,
  field: 'market_price' | 'price',
  value: number | string | null,
) {
  row[field] = Number(value) || 0;
  refreshRowFlags(row);
  emit('cellChange', { ...row });
}

function handleRowSave(row: PriceCompareRow) {
  emit('rowSave', row);
}
</script>

<template>
  <div class="flex min-h-0 flex-1 flex-col overflow-hidden">
    <!-- Header Controls -->
    <div class="mb-4 flex flex-shrink-0 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-shrink-0 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 Content Area -->
    <div
      v-if="innerFilterTab !== 'unmatched'"
      class="min-h-0 flex-1 overflow-y-auto pr-1 custom-scrollbar"
    >
      <Transition name="fade" mode="out-in">
        <div
          v-if="filteredRows.length === 0"
          class="flex h-32 items-center justify-center text-sm text-gray-400"
        >
          暂无匹配的数据
        </div>

        <!-- Animated Grid -->
        <TransitionGroup
          v-else
          tag="div"
          name="list"
          class="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5"
        >
          <div
            v-for="row in filteredRows"
            :key="row.id"
            :class="cardClass(row)"
          >
            <!-- Card Header -->
            <div class="mb-3 flex items-start justify-between gap-2 border-b border-gray-100/50 pb-2 dark:border-gray-700/50">
              <div
                class="min-w-0 flex-1 truncate text-sm font-semibold text-gray-800 dark:text-gray-100"
                :title="row.drug_name"
              >
                {{ row.drug_name || '—' }}
              </div>
              <span
                class="flex-shrink-0 rounded bg-gray-100 px-1.5 py-0.5 text-[11px] text-gray-500 dark:bg-gray-700 dark:text-gray-300"
                :title="row.drug_number"
              >
                {{ row.drug_number || '—' }}
              </span>
            </div>

            <!-- Status Tags -->
            <div v-if="row._isNew" class="mb-2">
              <Tag color="blue" class="!mr-0 !border-blue-200 !text-[11px] shadow-sm">待新增</Tag>
            </div>

            <!-- Price Inputs Area -->
            <div class="space-y-2.5 text-xs">
              <!-- Market Price Row -->
              <div class="flex items-center justify-between group/row">
                <span class="w-12 flex-shrink-0 font-medium text-gray-500 dark:text-gray-400">
                  供货价
                </span>
                <div class="flex flex-1 items-center justify-end gap-2">
                  <template v-if="!row._isNew">
                    <span class="text-gray-400 line-through decoration-gray-300 dark:text-gray-500 dark:decoration-gray-600">
                      {{ formatPriceDisplay(row.orig_market_price) }}
                    </span>
                    <span class="text-gray-300 dark:text-gray-600">→</span>
                  </template>
                  <InputNumber
                    class="!w-[85px] !rounded-md shadow-sm transition-all focus-within:ring-2 focus-within:ring-blue-100"
                    :min="0"
                    :precision="4"
                    :step="0.0001"
                    size="small"
                    :value="row.market_price"
                    @update:value="
                      (v) => onPriceChange(row, 'market_price', v as number)
                    "
                  />
                  <span
                    v-if="!row._isNew && row._marketChanged"
                    class="w-4 text-center transition-opacity"
                    :class="deltaClass(row._marketDelta)"
                  >
                    {{ deltaSymbol(row._marketDelta) }}
                  </span>
                  <span v-else class="w-4"></span>
                </div>
              </div>

              <!-- Sell Price Row -->
              <div class="flex items-center justify-between group/row">
                <span class="w-12 flex-shrink-0 font-medium text-gray-500 dark:text-gray-400">
                  售价
                </span>
                <div class="flex flex-1 items-center justify-end gap-2">
                  <template v-if="!row._isNew">
                    <span class="text-gray-400 line-through decoration-gray-300 dark:text-gray-500 dark:decoration-gray-600">
                      {{ formatPriceDisplay(row.orig_price) }}
                    </span>
                    <span class="text-gray-300 dark:text-gray-600">→</span>
                  </template>
                  <InputNumber
                    class="!w-[85px] !rounded-md shadow-sm transition-all focus-within:ring-2 focus-within:ring-blue-100"
                    :min="0"
                    :precision="4"
                    :step="0.0001"
                    size="small"
                    :value="row.price"
                    @update:value="
                      (v) => onPriceChange(row, 'price', v as number)
                    "
                  />
                  <span
                    v-if="!row._isNew && row._priceChanged"
                    class="w-4 text-center transition-opacity"
                    :class="deltaClass(row._priceDelta)"
                  >
                    {{ deltaSymbol(row._priceDelta) }}
                  </span>
                  <span v-else class="w-4"></span>
                </div>
              </div>
            </div>

            <!-- Action Area -->
            <div
              class="mt-3 flex h-7 items-end justify-end overflow-hidden"
            >
              <Transition name="slide-up">
                <Button
                  v-if="row._changed"
                  :loading="savingRowId === row.id"
                  size="small"
                  type="primary"
                  class="!rounded-md !px-4 shadow-sm hover:shadow-md"
                  @click="handleRowSave(row)"
                >
                  保存更新
                </Button>
              </Transition>
            </div>
          </div>
        </TransitionGroup>
      </Transition>
    </div>

    <!-- Unmatched Rows View -->
    <Transition name="fade" mode="out-in">
      <div
        v-if="innerFilterTab === 'unmatched'"
        class="min-h-0 flex-1 overflow-y-auto rounded-xl border border-orange-100 bg-gradient-to-b from-orange-50/50 to-orange-50/10 p-4 shadow-inner custom-scrollbar dark:border-orange-900/40 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>
        <div
          v-for="(row, index) in unmatchedRows"
          :key="`${row.drug_name}-${index}`"
          class="group mb-2 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>
      </div>
    </Transition>
  </div>
</template>

<style scoped>
/* List Transitions for Grid Cards */
.list-move,
.list-enter-active,
.list-leave-active {
  transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateY(15px) scale(0.98);
}

/* Ensure leaving items are taken out of flow so moving items animate smoothly */
.list-leave-active {
  position: absolute;
}

/* Fade Transitions */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

/* Slide Up Transition for Button */
.slide-up-enter-active,
.slide-up-leave-active {
  transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
}

.slide-up-enter-from,
.slide-up-leave-to {
  opacity: 0;
  transform: translateY(10px);
}

/* Scrollbar styling for modern look */
.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>
