<!--
  组件开发示例代码
  展示项目中组件的编写规范和最佳实践
-->

<script lang="ts" setup>
/**
 * 组件Props接口定义
 */
interface Props {
  /** 标题文本 */
  title: string;
  /** 是否显示（用于 v-model） */
  modelValue: boolean;
  /** 大小尺寸 */
  size?: 'large' | 'medium' | 'small';
  /** 用户信息 */
  userInfo?: {
    id: number;
    name: string;
    avatar?: string;
  } | null;
  /** 是否显示操作按钮 */
  showActions?: boolean;
  /** 自定义类名 */
  customClass?: string;
}

/**
 * 组件Emits接口定义
 */
interface Emits {
  /** 更新显示状态 */
  (e: 'update:modelValue', value: boolean): void;
  /** 点击确认按钮 */
  (e: 'confirm', data: any): void;
  /** 点击取消按钮 */
  (e: 'cancel'): void;
  /** 点击删除按钮 */
  (e: 'delete', id: number): void;
}

/**
 * Props默认值设置
 * 使用 withDefaults 提供默认值
 */
const props = withDefaults(defineProps<Props>(), {
  size: 'medium',
  userInfo: null,
  showActions: true,
  customClass: '',
});

/**
 * Emits定义
 * 使用 defineEmits 定义组件事件
 */
const emit = defineEmits<Emits>();

/**
 * 组件内部状态
 */

// 内部数据
const internalData = ref({
  inputValue: '',
  selectedValue: '',
});

// 是否禁用
const disabled = ref(false);

/**
 * 计算属性
 */

// 根据 size 计算类名
const sizeClass = computed(() => {
  const sizeMap = {
    large: 'size-large',
    medium: 'size-medium',
    small: 'size-small',
  };
  return sizeMap[props.size];
});

// 组件类名
const componentClass = computed(() => {
  return ['user-card', props.customClass, sizeClass.value].filter(Boolean);
});

/**
 * 方法定义
 */

// ✅ 关闭弹窗
/**
 * 关闭弹窗
 */
const handleClose = () => {
  emit('update:modelValue', false);
};

// ✅ 点击遮罩关闭
/**
 * 点击遮罩关闭弹窗
 * @param e 事件对象
 */
const handleMaskClick = (e: MouseEvent) => {
  // 阻止事件冒泡
  e.stopPropagation();
  handleClose();
};

// ✅ 阻止内容区域点击
/**
 * 阻止内容区域点击事件冒泡
 * @param e 事件对象
 */
const handleContentClick = (e: MouseEvent) => {
  e.stopPropagation();
};

// ✅ 确认操作
/**
 * 点击确认按钮
 */
const handleConfirm = () => {
  const result = {
    inputValue: internalData.value.inputValue,
    selectedValue: internalData.value.selectedValue,
    userInfo: props.userInfo,
  };
  emit('confirm', result);
};

// ✅ 取消操作
/**
 * 点击取消按钮
 */
const handleCancel = () => {
  emit('cancel');
  handleClose();
};

// ✅ 删除用户
/**
 * 点击删除按钮
 * @param id 用户ID
 */
const handleDelete = (id: number) => {
  uni.showModal({
    title: '确认删除',
    content: '确定要删除该用户吗？',
    success: (res) => {
      if (res.confirm) {
        emit('delete', id);
      }
    },
  });
};

// ✅ 输入处理
/**
 * 处理输入框输入
 * @param value 输入值
 */
const handleInput = (value: string) => {
  internalData.value.inputValue = value;
};

// ✅ 选择处理
/**
 * 处理选择器变化
 * @param value 选中值
 */
const handleSelectChange = (value: string) => {
  internalData.value.selectedValue = value;
};

// ✅ 获取用户头像
/**
 * 获取用户头像地址
 * @returns 头像地址
 */
const getUserAvatar = () => {
  if (props.userInfo?.avatar) {
    return props.userInfo.avatar;
  }
  return '/static/default-avatar.png';
};

// ✅ 格式化用户信息
/**
 * 格式化显示用户信息
 * @returns 用户信息字符串
 */
const formatUserInfo = () => {
  if (!props.userInfo) {
    return '未选择用户';
  }
  return `${props.userInfo.name} (#${props.userInfo.id})`;
};

/**
 * Watch监听
 */

// 监听 modelValue 变化，重置表单
watch(
  () => props.modelValue,
  (newValue) => {
    if (newValue) {
      // 弹窗打开时重置表单
      internalData.value.inputValue = '';
      internalData.value.selectedValue = '';
    }
  }
);
</script>

<template>
  <!-- ✅ 弹窗容器 -->
  <view
    v-if="modelValue"
    class="user-card-mask"
    @tap="handleMaskClick"
  >
    <view
      :class="componentClass"
      class="user-card"
      @tap="handleContentClick"
    >
      <!-- ✅ 头部标题 -->
      <view class="user-card__header">
        <view class="user-card__title">
          <text class="title-text">{{ title }}</text>
        </view>
        <view class="user-card__close" @tap="handleClose">
          <text class="close-icon">×</text>
        </view>
      </view>

      <!-- ✅ 用户信息展示 -->
      <view class="user-card__content">
        <view class="user-info">
          <image
            class="user-avatar"
            :src="getUserAvatar()"
            mode="aspectFill"
          />
          <view class="user-details">
            <text class="user-name">{{ formatUserInfo() }}</text>
            <text class="user-id" v-if="userInfo">
              ID: {{ userInfo.id }}
            </text>
          </view>
        </view>

        <!-- ✅ 表单输入区域 -->
        <view class="form-area">
          <!-- 输入框 -->
          <view class="form-item">
            <label class="form-label">输入内容：</label>
            <input
              class="form-input"
              v-model="internalData.inputValue"
              placeholder="请输入内容"
              @input="handleInput"
            />
          </view>

          <!-- 选择器 -->
          <view class="form-item">
            <label class="form-label">选择类型：</label>
            <picker
              class="form-picker"
              @change="handleSelectChange"
              :range="['选项1', '选项2', '选项3']"
            >
              <view class="picker-display">
                {{ internalData.selectedValue || '请选择' }}
              </view>
            </picker>
          </view>

          <!-- 禁用状态示例 -->
          <view class="form-item">
            <label class="form-label">禁用状态：</label>
            <view
              class="disabled-input"
              :class="{ 'is-disabled': disabled }"
            >
              {{ disabled ? '已禁用' : '正常状态' }}
            </view>
          </view>
        </view>
      </view>

      <!-- ✅ 底部操作按钮 -->
      <view class="user-card__footer" v-if="showActions">
        <view class="action-buttons">
          <button
            class="btn btn-cancel"
            @tap="handleCancel"
          >
            取消
          </button>
          <button
            class="btn btn-confirm"
            @tap="handleConfirm"
          >
            确认
          </button>
          <button
            class="btn btn-danger"
            v-if="userInfo?.id"
            @tap="handleDelete(userInfo.id)"
          >
            删除
          </button>
        </view>
      </view>
    </view>
  </view>
</template>

<style scoped lang="scss">
/* 遮罩层 */
.user-card-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999;
  padding: 40rpx;
}

/* 卡片主体 */
.user-card {
  background: white;
  border-radius: 16rpx;
  overflow: hidden;
  box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.1);
  max-width: 600rpx;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;

  /* 不同尺寸样式 */
  &.size-large {
    .user-card__header {
      padding: 40rpx;
    }

    .user-card__content {
      padding: 40rpx;
    }

    .user-card__footer {
      padding: 40rpx;
    }
  }

  &.size-medium {
    .user-card__header {
      padding: 32rpx;
    }

    .user-card__content {
      padding: 32rpx;
    }

    .user-card__footer {
      padding: 32rpx;
    }
  }

  &.size-small {
    .user-card__header {
      padding: 24rpx;
    }

    .user-card__content {
      padding: 24rpx;
    }

    .user-card__footer {
      padding: 24rpx;
    }
  }
}

/* 头部 */
.user-card__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1rpx solid #f0f0f0;
  background: linear-gradient(90deg, #f0f8ff, #e6f2ff);

  .user-card__title {
    flex: 1;

    .title-text {
      font-size: 36rpx;
      font-weight: 600;
      color: #333;
    }
  }

  .user-card__close {
    width: 60rpx;
    height: 60rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.05);
    transition: all 0.3s;

    &:active {
      background: rgba(0, 0, 0, 0.1);
      transform: scale(0.95);
    }

    .close-icon {
      font-size: 40rpx;
      color: #666;
      line-height: 1;
    }
  }
}

/* 内容区 */
.user-card__content {
  background: white;
}

/* 用户信息 */
.user-info {
  display: flex;
  align-items: center;
  gap: 20rpx;
  padding: 20rpx;
  background: #f9f9f9;
  border-radius: 8rpx;
  margin-bottom: 20rpx;

  .user-avatar {
    width: 80rpx;
    height: 80rpx;
    border-radius: 50%;
    border: 2rpx solid #e0e0e0;
  }

  .user-details {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8rpx;

    .user-name {
      font-size: 30rpx;
      font-weight: 600;
      color: #333;
    }

    .user-id {
      font-size: 24rpx;
      color: #999;
    }
  }
}

/* 表单区域 */
.form-area {
  display: flex;
  flex-direction: column;
  gap: 20rpx;
}

.form-item {
  display: flex;
  align-items: center;
  gap: 20rpx;

  .form-label {
    min-width: 120rpx;
    font-size: 28rpx;
    color: #666;
  }

  .form-input {
    flex: 1;
    padding: 16rpx 20rpx;
    background: #f5f5f5;
    border-radius: 8rpx;
    font-size: 28rpx;
  }

  .form-picker {
    flex: 1;

    .picker-display {
      padding: 16rpx 20rpx;
      background: #f5f5f5;
      border-radius: 8rpx;
      font-size: 28rpx;
    }
  }

  .disabled-input {
    flex: 1;
    padding: 16rpx 20rpx;
    background: #f5f5f5;
    border-radius: 8rpx;
    font-size: 28rpx;
    color: #999;

    &.is-disabled {
      opacity: 0.6;
    }
  }
}

/* 底部 */
.user-card__footer {
  background: white;
  border-top: 1rpx solid #f0f0f0;
}

.action-buttons {
  display: flex;
  gap: 20rpx;
  justify-content: flex-end;

  .btn {
    padding: 20rpx 40rpx;
    border-radius: 8rpx;
    font-size: 28rpx;
    border: none;
    transition: all 0.3s;

    &:active {
      transform: scale(0.95);
    }

    &.btn-cancel {
      background: #f5f5f5;
      color: #666;
    }

    &.btn-confirm {
      background: #4a90ff;
      color: white;
    }

    &.btn-danger {
      background: #f56c6c;
      color: white;
    }
  }
}
</style>
