<script lang="ts" setup>
import type { CardListProps, ExtendedCardListApi } from './types';

import { computed, h, nextTick, onMounted, onUnmounted, ref } from 'vue';

import { usePriorityValues } from '@vben/hooks';
import { cn } from '@vben/utils';

import { VbenLoading } from '@vben-core/shadcn-ui';

import { Card, DatePicker, Empty, Input, Select } from 'ant-design-vue';

import SelectDropdownRender from '#/components/SelectDropdownRender/index.vue';

const props = withDefaults(defineProps<Props>(), {});

// 创建一个全局缓存对象
const selectOptionsCache: Record<string, any[]> = {};

interface Props extends CardListProps {
  api: ExtendedCardListApi;
}

const listData = computed(() => {
  return gridOptions.value?.data || [];
});

const state = props.api?.useStore?.();

const { class: className, gridClass, gridOptions, gridEvents } = usePriorityValues(props, state);

// 计算标题字段
const titleFieldName = computed(() => {
  const titleField = gridOptions.value?.titleField;
  if (titleField) return titleField;
  const columns = gridOptions.value?.columns || [];
  if (columns.length > 0) return columns[0]?.field || '';
  return '';
});

// 卡片网格样式
const gridStyle = computed(() => {
  const gridHeight = gridOptions.value?.gridHeight || 'auto';
  const gridColumns = gridOptions.value?.gridColumns || 3;
  const cardGap = gridOptions.value?.cardGap || '10px';

  return {
    display: 'grid',
    gridTemplateColumns: `repeat(${gridColumns}, 1fr)`,
    gap: cardGap,
    height: gridHeight,
    overflow: 'auto',
    padding: '5px',
  };
});

// 卡片样式
const cardStyle = (item: any) => {
  const cardHeight = gridOptions.value?.cardHeight;
  const cardWidth = gridOptions.value?.cardWidth || '100%';

  const style: any = {
    width: cardWidth,
    minWidth: 0, // 添加最小宽度为0，防止内容撑开
    overflow: 'hidden', // 添加溢出隐藏
    borderColor: item.error ? 'red' : 'inherit',
  };

  if (cardHeight && cardHeight !== 'auto') {
    style.height = cardHeight;
  }

  return style;
};

// 卡片内容样式
const cardContentStyle = computed(() => {
  const fieldColumns = gridOptions.value?.fieldColumns || 1;

  if (fieldColumns > 1) {
    return {
      display: 'grid',
      gridTemplateColumns: `repeat(${fieldColumns}, 1fr)`,
      columnGap: '10px', // 控制列间距
      rowGap: '8px', // 控制行间距，设置更小的值
    };
  }

  return {};
});

// 卡片字段样式
const cardFieldStyle = (column: any) => {
  const fieldColumns = gridOptions.value?.fieldColumns || 1;
  const colSpan = column?.colSpan || 1;

  if (fieldColumns > 1) {
    return {
      marginBottom: '0px',
      paddingBottom: '0px',
      height: 'auto',
      lineHeight: 'normal',
      gridColumn: `span ${colSpan}`,
    };
  }

  return {};
};

// const errorCardStyle = (item: any) => {
//   const errorData = gridOptions.value?.errorData || [];
//   return errorData.some((errorItem) => errorItem.id === item.id)
//     ? {
//         ...cardStyle.value,
//         borderColor: 'red',
//       }
//     : false;
// };

// 格式化字段值
const formatFieldValue = (column: any, row: any) => {
  if (!column?.field) return '';
  const value = row[column.field];
  if (column?.formatter) {
    return column.formatter(value, row);
  }
  return value;
};

// 渲染编辑组件
const renderEditComponent = (column: any, row: any) => {
  const fieldName = column.field;
  const value = row[fieldName];
  const editRender = column.editRender;
  const editProps = editRender?.props || {};

  // 创建更新函数，避免直接修改只读对象
  const updateValue = (val: any) => {
    // 获取当前数据数组
    const currentData = gridOptions.value?.data || [];
    // 找到要修改的项的索引
    const index = currentData.findIndex((item: any) => item.id === row.id);
    if (index !== -1) {
      // 创建新的数据数组，避免直接修改原数组
      const newData = [...currentData];
      // 创建新的对象，避免直接修改原对象
      newData[index] = { ...newData[index], [fieldName]: val };
      // 更新数据
      props.api.setData(newData);
    }
  };

  switch (editRender.name) {
    case 'date-picker':
    case 'DatePicker': {
      return h(DatePicker, {
        value,
        valueFormat: 'YYYY-MM-DD',
        ...editProps,
        'onUpdate:value': updateValue,
      });
    }
    case 'Input':
    case 'input': {
      return h(Input, {
        value,
        ...editProps,
        'onUpdate:value': updateValue,
      });
    }
    case 'input-number':
    case 'InputNumber': {
      return h(Input, {
        value,
        type: 'number',
        ...editProps,
        'onUpdate:value': updateValue,
      });
    }
    case 'Select':
    case 'select': {
      return h(Select, {
        value,
        ...editProps,
        'onUpdate:value': updateValue,
      });
    }
    case 'SelectDropdownRender':
    case 'selectDropdownRender': {
      // 创建一个响应式的选项数组
      const options = ref<any[]>([]);

      // 创建一个唯一的缓存键，基于 row 的关键属性
      const cacheKey = `${row.paymentId}_${row.come}_${row.orderType}_${row.courseId}`;

      // 检查缓存中是否已有数据
      if (selectOptionsCache[cacheKey]) {
        options.value = selectOptionsCache[cacheKey];
      } else if (editProps?.fetchOptions) {
        // 如果缓存中没有，则获取数据并存储到缓存
        editProps.fetchOptions(row).then((res: any) => {
          options.value = res;
          // 存储到缓存
          selectOptionsCache[cacheKey] = res;
        });
      }

      return h(SelectDropdownRender, {
        value,
        ...editProps,
        options,
        'onUpdate:value': updateValue,
      });
    }
    default: {
      return formatFieldValue(column, row);
    }
  }
};

// 处理卡片点击
const handleCardClick = (row: any) => {
  gridEvents.value?.cardClick?.(row);
};

// 初始化
async function init() {
  await nextTick();
  if (props.api?.mount) {
    props.api.mount();
  }
}

onMounted(() => {
  init();
});

onUnmounted(() => {
  if (props.api?.unmount) {
    props.api.unmount();
  }
});
</script>

<template>
  <div :class="cn('h-full overflow-auto rounded-md', className)">
    <div :class="cn('rounded-md bg-card', gridClass)">
      <!-- 加载状态 -->
      <VbenLoading v-if="gridOptions?.loading" :spinning="true" />

      <!-- 卡片列表 -->
      <div v-else-if="listData.length > 0" :style="gridStyle">
        <Card
          v-for="(item, index) in listData"
          :key="item[titleFieldName]"
          :class="gridOptions?.cardClass"
          :style="cardStyle(item)"
          @click="handleCardClick(item)"
        >
          <!-- 自定义标题 -->
          <template #title v-if="gridOptions?.showTitle">
            <div class="custom-card-title" :title="item[titleFieldName]">
              {{ item[titleFieldName] }}
            </div>
          </template>
          <!-- 卡片右上角额外内容 -->
          <template #extra v-if="$slots['card-extra']">
            <slot name="card-extra" :row="item" :index="index"></slot>
          </template>

          <div class="card-content" :style="cardContentStyle">
            <div
              v-for="column in gridOptions?.columns"
              :key="column?.field || ''"
              class="card-field"
              :style="cardFieldStyle(column)"
              v-show="
                !column?.show ||
                (typeof column.show === 'function' ? column.show(item) : column.show)
              "
            >
              <!-- 自定义插槽 -->
              <div v-if="column?.slots?.default" class="field-item">
                <span class="field-title">{{ column?.title }}:</span>
                <span class="field-value field-edit">
                  <slot
                    :name="column.slots.default"
                    :row="item"
                    :field="column?.field || ''"
                    :value="item[column?.field || '']"
                    :index="index"
                  ></slot>
                </span>
              </div>
              <!-- 编辑渲染组件 -->
              <div v-else-if="column?.editRender" class="field-item">
                <span class="field-title">{{ column?.title }}:</span>
                <span class="field-value field-edit">
                  <component :is="renderEditComponent(column, item)" />
                </span>
              </div>
              <!-- 默认显示 -->
              <div v-else class="field-item">
                <span class="field-title">{{ column?.title }}:</span>
                <span class="field-value">{{ formatFieldValue(column, item) }}</span>
              </div>
            </div>
          </div>

          <!-- 卡片底部操作区域 -->
          <template #actions v-if="$slots['card-actions']">
            <slot name="card-actions" :row="item"></slot>
          </template>
        </Card>
      </div>

      <!-- 空状态 -->
      <div v-else class="flex flex-col items-center justify-center py-10">
        <Empty :description="gridOptions?.emptyText || '暂无数据'" />
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.card-content {
  .card-field {
    .field-item {
      display: flex;
      align-items: center;
      flex-wrap: nowrap;

      .field-title {
        flex-shrink: 0;
        margin-right: 8px;
        font-weight: 500;
        color: rgba(0, 0, 0, 0.85);
        white-space: nowrap;
      }

      .field-value {
        flex: 1;
        min-width: 0;
        word-break: break-all;
        color: rgba(0, 0, 0, 0.65);
        overflow: hidden;
        text-overflow: ellipsis;

        &.field-edit {
          display: flex;
          align-items: center;

          :deep(.ant-input),
          :deep(.ant-picker),
          :deep(.ant-select) {
            width: 100%;
          }
        }
      }
    }
  }
}

.pagination-container {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

:deep(.ant-card) {
  display: flex;
  flex-direction: column;
  width: 100%; // 确保卡片不超出容器宽度
  min-width: 0; // 防止内容撑开

  .ant-card-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 12px !important;
    min-width: 0; // 防止内容撑开
  }

  .card-content {
    overflow-y: auto;
    min-width: 0; // 防止内容撑开
  }

  .ant-card-head {
    min-height: auto;
    padding: 0 12px;
    border-bottom: 1px solid #f0f0f0;
    min-width: 0; // 防止内容撑开
    height: auto; // 允许头部高度自适应
    display: flex; // 使用flex布局

    .ant-card-head-wrapper {
      align-items: flex-start; // 顶部对齐
      width: 100%;
    }

    .ant-card-head-title {
      padding: 8px 0;
      width: 100%;
      height: auto; // 允许标题高度自适应
      white-space: normal; // 允许换行
      word-wrap: break-word;
      word-break: break-all;
    }

    .ant-card-extra {
      padding: 8px 0; // 给extra区域添加与标题相同的内边距
    }
  }
}

.custom-card-title {
  word-wrap: break-word;
  word-break: break-all;
  width: 100%;
  height: auto;
  white-space: normal; // 允许换行
  line-height: 1.5;
}
</style>
