// 从 'ant-design-vue' 库中解构导入 Tag 组件（Ant Design Vue 是一个常用的 Vue UI 组件库，Tag 组件通常用于展示标签样式的元素）。
import { Tag } from 'ant-design-vue';
// 从导入的 Tag 组件中进一步解构出 CheckableTag 组件，从名称推测它可能是一个支持可勾选功能的标签组件，用于实现类似选项可以被选中或取消选中的交互效果。
const { CheckableTag } = Tag;

export default {
  // 定义组件的名称为 'TagSelectOption'，在 Vue 开发中，组件名称有助于在调试、组件注册以及父子组件通信等场景下进行识别和使用。
  name: 'TagSelectOption',
  props: {
    // 定义 prefixCls 属性，类型为字符串，用于设置组件的类名前缀，默认值是 'ant-pro-tag-select-option'。通过这个前缀可以方便地对组件添加自定义样式，外部传入不同的前缀可以改变样式应用的类名基础，便于样式定制和主题切换等操作，使得该组件在样式方面具有更好的可扩展性和个性化定制能力。
    prefixCls: {
      type: String,
      default: 'ant-pro-tag-select-option'
    },
    // 定义 value 属性，类型可以是字符串、数字或者对象，用于表示该选项组件对应的唯一值，这个值在整个选项集合中应该是唯一的，方便用于识别、比较以及后续的选中状态关联等操作，默认值为空字符串，表示如果外部没有传入具体值，则使用空字符串作为默认的标识值。
    value: {
      type: [String, Number, Object],
      default: ''
    },
    // 定义 checked 属性，类型为布尔值，用于接收外部传入的该选项初始选中状态，默认值为 false，即默认情况下该选项是未被选中的，外部可以通过传入 true 来设置该选项初始为选中状态，便于在不同使用场景下控制选项的初始展示情况。
    checked: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      // 定义 localChecked 属性，用于在组件内部记录当前选项的选中状态，初始值通过判断传入的 checked 属性值来确定，如果 checked 有值（为 true 或者 false）则使用该值，否则初始化为 false，这样可以保证组件内部状态与外部传入的初始状态保持一致，同时方便后续在组件内部对选中状态进行管理和更新操作。
      localChecked: this.checked || false
    }
  },
  watch: {
    // 监听 checked 属性的变化，当 checked 属性的值发生改变时（可能是外部传入新的值来更新选项的选中状态），将组件内部记录选中状态的 localChecked 属性更新为新的 checked 属性值，确保组件内部状态与外部传入的选中状态保持同步，便于后续基于这个状态进行渲染和相关逻辑处理。
    'checked' (val) {
      this.localChecked = val;
    },
    // 监听 '$parent.items' 的变化，这里 '$parent' 表示当前组件的父组件实例，'items' 可能是父组件中用于存储所有选项相关信息（比如各选项的选中状态等数据）的一个对象。使用 deep: true 表示进行深度监听，即当 '$parent.items' 对象内部的任何属性发生变化时，都会触发这个监听器的 handler 函数。
    '$parent.items': {
      handler: function (val) {
        // 当 '$parent.items' 发生变化时，先判断当前组件的 value 属性是否存在（即当前选项有对应的唯一标识值），并且 '$parent.items' 对象中是否包含以当前选项 value 值为键的属性（即判断父组件中是否有记录当前选项的相关信息），如果满足这两个条件，则将组件内部记录选中状态的 localChecked 属性更新为 '$parent.items' 中对应键的值（也就是获取父组件中记录的当前选项的选中状态来更新组件内部状态），保持组件内部状态与父组件中管理的选项选中状态信息一致。
        this.value && val.hasOwnProperty(this.value) && (this.localChecked = val[this.value]);
      },
      deep: true
    }
  },
  render () {
    // 从组件实例中解构出 $slots 和 value 属性，$slots 用于获取组件的插槽内容（例如在使用该组件时，通过默认插槽传入的自定义文本、图标等内容），value 属性则是前面定义的用于标识该选项的唯一值，后续会在渲染等操作中使用到它们。
    const { $slots, value } = this;
    const onChange = (checked) => {
      // 定义一个名为 onChange 的函数，当选项的选中状态发生改变时会调用这个函数。在函数内部，通过 $emit 触发 'change' 事件，并将包含当前选项 value 值和新的选中状态（checked）的对象传递出去，这样父组件可以监听这个 'change' 事件来获取选项选中状态的变化情况，进而进行相应的数据更新、逻辑处理等操作，实现了组件与父组件之间关于选项选中状态变更的通信机制。
      this.$emit('change', { value, checked });
    };
    return (
      // 使用 CheckableTag 组件进行渲染，这是从 Ant Design Vue 的 Tag 组件中解构出来的可勾选标签组件。
      // 设置 key 属性为当前选项的 value 值，用于在 Vue 的虚拟 DOM 渲染机制中帮助识别和区分不同的选项组件，提高渲染效率和准确性（尤其在列表渲染等场景下很重要）。
      // 通过 vModel 指令绑定组件内部记录的选中状态 localChecked，实现数据的双向绑定效果，使得外部传入的选中状态可以控制组件的展示，同时组件内部状态的改变也能反馈到外部。
      // 绑定 onChange 事件为前面定义的 onChange 函数，当用户点击勾选或取消勾选该标签选项时，会触发这个函数来通知父组件选项选中状态的变化。
      // 在 CheckableTag 组件内部渲染默认插槽内容（$slots.default），这样在使用该组件时，用户可以通过默认插槽传入自定义的文本、图标等内容来丰富标签选项的展示效果。
      <CheckableTag key={value} vModel={this.localChecked} onChange={onChange}>
        {$slots.default}
      </CheckableTag>
    )
  }
}
