<template>
  <view class="card" :class="cardClass" @click="handleClick">
    <!-- 卡片头部 -->
    <view class="card-header" v-if="showHeader">
      <slot name="header">
        <view class="header-content">
          <!-- 标题区域 -->
          <view class="header-title" v-if="title">
            <text class="title-text">{{ title }}</text>
            <text class="subtitle-text" v-if="subtitle">{{ subtitle }}</text>
          </view>
          
          <!-- 额外内容 -->
          <view class="header-extra" v-if="extra || $slots.extra">
            <slot name="extra">
              <text class="extra-text">{{ extra }}</text>
            </slot>
          </view>
        </view>
      </slot>
    </view>
    
    <!-- 卡片主体 -->
    <view class="card-body" :class="bodyClass">
      <slot>
        <view class="default-content" v-if="content">
          {{ content }}
        </view>
      </slot>
    </view>
    
    <!-- 卡片底部 -->
    <view class="card-footer" v-if="showFooter">
      <slot name="footer">
        <view class="footer-content">
          {{ footer }}
        </view>
      </slot>
    </view>
    
    <!-- 加载状态 -->
    <view class="card-loading" v-if="loading">
      <view class="loading-spinner"></view>
      <text class="loading-text">{{ loadingText }}</text>
    </view>
  </view>
</template>

<script>
export default {
  name: 'Card',
  props: {
    // 标题
    title: {
      type: String,
      default: ''
    },
    // 副标题
    subtitle: {
      type: String,
      default: ''
    },
    // 额外内容
    extra: {
      type: String,
      default: ''
    },
    // 主体内容
    content: {
      type: String,
      default: ''
    },
    // 底部内容
    footer: {
      type: String,
      default: ''
    },
    // 卡片类型
    type: {
      type: String,
      default: 'default', // default, primary, success, warning, danger
      validator: (value) => ['default', 'primary', 'success', 'warning', 'danger'].includes(value)
    },
    // 卡片大小
    size: {
      type: String,
      default: 'normal', // large, normal, small
      validator: (value) => ['large', 'normal', 'small'].includes(value)
    },
    // 是否有阴影
    shadow: {
      type: [Boolean, String],
      default: true // true, false, 'always', 'hover', 'never'
    },
    // 是否有边框
    bordered: {
      type: Boolean,
      default: true
    },
    // 是否可点击
    clickable: {
      type: Boolean,
      default: false
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false
    },
    // 是否加载中
    loading: {
      type: Boolean,
      default: false
    },
    // 加载文本
    loadingText: {
      type: String,
      default: '加载中...'
    },
    // 圆角大小
    borderRadius: {
      type: String,
      default: '12rpx'
    },
    // 内边距
    padding: {
      type: String,
      default: '32rpx'
    },
    // 外边距
    margin: {
      type: String,
      default: '0'
    },
    // 背景色
    backgroundColor: {
      type: String,
      default: '#fff'
    },
    // 自定义样式类
    customClass: {
      type: String,
      default: ''
    }
  },
  computed: {
    cardClass() {
      return [
        this.customClass,
        `card-${this.type}`,
        `card-${this.size}`,
        {
          'card-shadow': this.shadow === true || this.shadow === 'always',
          'card-shadow-hover': this.shadow === 'hover',
          'card-bordered': this.bordered,
          'card-clickable': this.clickable,
          'card-disabled': this.disabled,
          'card-loading': this.loading
        }
      ]
    },
    bodyClass() {
      return {
        'body-no-header': !this.showHeader,
        'body-no-footer': !this.showFooter
      }
    },
    showHeader() {
      return this.title || this.subtitle || this.extra || this.$slots.header || this.$slots.extra
    },
    showFooter() {
      return this.footer || this.$slots.footer
    }
  },
  methods: {
    handleClick(e) {
      if (this.disabled || this.loading) return
      this.$emit('click', e)
    }
  }
}
</script>

<style lang="scss" scoped>
.card {
  position: relative;
  background-color: v-bind(backgroundColor);
  border-radius: v-bind(borderRadius);
  margin: v-bind(margin);
  overflow: hidden;
  transition: all 0.3s ease;
  
  // 类型样式
  &.card-primary {
    border-left: 8rpx solid #2e8b57;
  }
  
  &.card-success {
    border-left: 8rpx solid #52c41a;
  }
  
  &.card-warning {
    border-left: 8rpx solid #faad14;
  }
  
  &.card-danger {
    border-left: 8rpx solid #ff4d4f;
  }
  
  // 大小样式
  &.card-large {
    .card-header {
      padding: 40rpx 40rpx 0;
    }
    
    .card-body {
      padding: 32rpx 40rpx;
    }
    
    .card-footer {
      padding: 0 40rpx 40rpx;
    }
    
    .title-text {
      font-size: 36rpx;
    }
  }
  
  &.card-normal {
    .card-header {
      padding: 32rpx 32rpx 0;
    }
    
    .card-body {
      padding: v-bind(padding);
    }
    
    .card-footer {
      padding: 0 32rpx 32rpx;
    }
    
    .title-text {
      font-size: 32rpx;
    }
  }
  
  &.card-small {
    .card-header {
      padding: 24rpx 24rpx 0;
    }
    
    .card-body {
      padding: 20rpx 24rpx;
    }
    
    .card-footer {
      padding: 0 24rpx 24rpx;
    }
    
    .title-text {
      font-size: 28rpx;
    }
  }
  
  // 阴影样式
  &.card-shadow {
    box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
  }
  
  &.card-shadow-hover:hover {
    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.15);
  }
  
  // 边框样式
  &.card-bordered {
    border: 2rpx solid #f0f0f0;
  }
  
  // 可点击样式
  &.card-clickable {
    cursor: pointer;
    
    &:active {
      transform: translateY(2rpx);
      box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
    }
  }
  
  // 禁用样式
  &.card-disabled {
    opacity: 0.6;
    cursor: not-allowed;
    
    &:active {
      transform: none;
    }
  }
  
  // 加载样式
  &.card-loading {
    pointer-events: none;
  }
}

.card-header {
  border-bottom: 2rpx solid #f0f0f0;
}

.header-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 24rpx;
}

.header-title {
  flex: 1;
}

.title-text {
  font-weight: 600;
  color: #333;
  line-height: 1.4;
}

.subtitle-text {
  display: block;
  font-size: 24rpx;
  color: #666;
  margin-top: 8rpx;
  line-height: 1.4;
}

.header-extra {
  margin-left: 24rpx;
}

.extra-text {
  font-size: 24rpx;
  color: #666;
}

.card-body {
  position: relative;
  
  &.body-no-header {
    padding-top: v-bind(padding);
  }
  
  &.body-no-footer {
    padding-bottom: v-bind(padding);
  }
}

.default-content {
  font-size: 28rpx;
  color: #666;
  line-height: 1.6;
}

.card-footer {
  border-top: 2rpx solid #f0f0f0;
  padding-top: 24rpx;
}

.footer-content {
  font-size: 24rpx;
  color: #999;
  text-align: right;
}

.card-loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.8);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 10;
}

.loading-spinner {
  width: 60rpx;
  height: 60rpx;
  border: 4rpx solid #f3f3f3;
  border-top: 4rpx solid #2e8b57;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

.loading-text {
  font-size: 24rpx;
  color: #666;
  margin-top: 16rpx;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
</style>