<script lang="tsx">
import { ref, defineComponent, computed } from 'vue';
import { Input, Dropdown, Menu } from 'ant-design-vue';
import type { MenuProps } from 'ant-design-vue';

import type { VNode } from 'vue';
import SvgIcon from '@/components/svg-icon/index.vue';
import TextoverTips from '@/components/text-over-tips/index.vue';

// 定义对话项类型
interface ConversationItem {
  key: string;
  label: string | VNode;
  icon?: string | VNode;
  disabled?: boolean;
  [key: string]: any;
}

const DEFAULT_MENU_CONFIG = [
  {
    label: '置顶',
    key: 'pin',
    icon: () => <SvgIcon name="svg-pushpin" size={14} class="color-#737478 hover:color-#6D4CFE" />,
  },
  {
    label: '重命名',
    key: 'rename',
    icon: <icon-edit size={14} class="color-#737478" />,
  },
  {
    label: '删除',
    key: 'delete',
    icon: <icon-delete size={14} class="color-#F64B31" />,
    status: 'danger',
  },
] as ConversationItem[];

export default defineComponent({
  name: 'Conversations',
  props: {
    dataSource: {
      type: Array as () => ConversationItem[],
      default: () => [],
    },
    activeKey: {
      type: String,
      default: '',
    },
    defaultActiveKey: {
      type: String,
      default: '',
    },
    menu: {
      type: Array as () => ConversationItem[],
      default: () => DEFAULT_MENU_CONFIG,
    },
  },
  emits: ['activeChange', 'menuClick', 'update:dataSource', 'update:modelValue', 'rename'],
  setup(props, { emit, expose }) {
    const activeKey = ref(props.activeKey || props.defaultActiveKey || '');
    const localDataSource = ref<ConversationItem[]>([]);
    const inputRef = ref(null);
    const menuConfigs = ref<ConversationItem[]>(props.menu ?? DEFAULT_MENU_CONFIG);

    // 处理选中变更
    const handleActiveChange = (item: ConversationItem) => {
      const { value } = item;
      activeKey.value = value;
      emit('update:modelValue', value);
      emit('activeChange', item);
    };
    const onMenuItemClick = ({ menuInfo, item }) => {
      const { key } = menuInfo;
      emit('menuClick', menuInfo);

      switch (key) {
        case 'rename':
          item.editing = true;
          nextTick(() => {
            inputRef.value.focus();
          });
          break;
      }
    };

    const changeItems = () => {
      emit('update:dataSource', localDataSource.value);
    };

    watch(
      () => props.dataSource,
      (newItems) => {
        if (newItems) {
          localDataSource.value = cloneDeep(newItems);
        }
      },
      { deep: true, immediate: true },
    );

    const renderItems = () => {
      return localDataSource.value.map((item, index) => (
        <div
          class={`group flex justify-between cursor-pointer items-center p-8px h-40px rounded-8px hover:bg-#F2F3F5 ${
            activeKey.value === item.key ? 'bg-#F2F3F5' : ''
          }`}
          onClick={() => handleActiveChange(item)}
        >
          {item.editing ? (
            <Input
              ref={inputRef}
              v-model:value={item.label}
              onBlur={() => {
                item.editing = false;
                changeItems();
                emit('rename', item);
              }}
              onPressEnter={() => {
                item.editing = false;
              }}
              class="flex-1"
            />
          ) : (
            <TextoverTips context={item.label} class="flex-1" placement="bottom" />
          )}
          <Dropdown
            class="p-0"
            overlayClassName="xt-conversations-dropdown"
            placement="bottomRight"
            v-slots={{
              overlay: () => (
                <Menu onClick={(menuInfo: MenuProps) => onMenuItemClick({ menuInfo, item })}>
                  {menuConfigs.value.map((menuItem) => (
                    <Menu.Item key={menuItem.key} icon={menuItem.icon} class={`${menuItem.status || ''}`}>
                      {menuItem.label}
                    </Menu.Item>
                  ))}
                </Menu>
              ),
            }}
          >
            <icon-more size={16} class="color-#737478 cursor-pointer ml-8px opacity-0 group-hover:opacity-100" />
          </Dropdown>
        </div>
      ));
    };

    return () => <div className="xt-conversations-container">{renderItems()}</div>;
  },
});
</script>

<style scoped lang="scss">
@import './style.scss';
</style>
<style lang="scss">
.xt-conversations-dropdown {
  .ant-dropdown-menu {
    padding: 4px 0;
    .ant-dropdown-menu-item {
      padding: 0 12px;
      min-width: 124px;
      height: 36px;
      display: flex;
      align-items: center;
      &:hover {
        background: var(--BG-200, #f2f3f5);
      }
      &.danger {
        color: var(--RED-600, #f64b31);
      }
    }
  }
}
</style>
