<template>
  <div class="sp-cat-tree">
    <div class="sp-cat-tree__search">
      <Input
        v-model="searchText"
        :placeholder="$t('SEARCH_CATEOGRY_NAME')"
        clearable
        @on-change="onSearch"
      />
    </div>
    <div class="sp-cat-tree__body">
      <Tree
        :data="displayedTreeData"
        :show-checkbox="false"
        :highlight-current="false"
        :render="renderContent"
        :default-expand-all="true"
        :checked-keys.sync="checkedKeys"
      />
    </div>
  </div>
</template>

<script>
import slugify from 'slugify';
import { getShopeeCategoryTreeHome } from '@/api/shopee/client/category';
import { imageUrl } from '@/adapter/shopee/render/utils';

export default {
  name: 'ShopeeCategoryTree',
  data() {
    return {
      fullTreeData: [],
      displayedTreeData: [],
      searchText: '',
      checkedKeys: [],
      matchedKeys: [],
    };
  },
  methods: {
    buildTree(data, is_root) {
      return data.map((node) => ({
        title: node.display_name,
        slug: slugify(node.display_name, {
          lower: true,
          trim: true,
          locale: 'vi',
        }),
        category_id: node.catid,
        key: node.catid,
        image: imageUrl(node.image),
        is_root,
        children: node.children ? this.buildTree(node.children, false) : [],
      }));
    },
    searchTreeForHighlight(nodes, keyword, matches = []) {
      nodes.forEach((node) => {
        if (node.title.toLowerCase().includes(keyword.toLowerCase())) {
          matches.push(node.category_id);
        }
        if (node.children && node.children.length) {
          this.searchTreeForHighlight(node.children, keyword, matches);
        }
      });
      return matches;
    },
    filterTree(nodes, keyword) {
      const filtered = [];
      nodes.forEach((node) => {
        const titleMatch = node.title.toLowerCase().includes(keyword.toLowerCase());
        let childrenFiltered = [];
        if (node.children && node.children.length) {
          childrenFiltered = this.filterTree(node.children, keyword);
        }
        if (titleMatch) {
          filtered.push({ ...node, children: node.children });
        } else if (childrenFiltered.length) {
          filtered.push({ ...node, children: childrenFiltered });
        }
      });
      return filtered;
    },
    onSearch() {
      const keyword = this.searchText.trim();
      if (!keyword) {
        this.matchedKeys = [];
        this.displayedTreeData = this.fullTreeData;
      } else {
        const matches = this.searchTreeForHighlight(this.fullTreeData, keyword, []);
        this.matchedKeys = matches;
        this.displayedTreeData = this.filterTree(this.fullTreeData, keyword);
      }
    },
    renderContent(h, { data }) {
      const { category_id: categoryId, slug } = data;

      const isMatched = this.matchedKeys.includes(categoryId);
      const thumbnail = data.image;

      const spyUrl = this.getRouterUrl(`/shopee/spy/category/${categoryId}`);
      const categoryUrl = `https://shopee.vn/${slug}-cat.${categoryId}`;

      const attrMatch = isMatched ? { color: '#f90', fontWeight: 'bold' } : {};
      return h(
        'div',
        { style: { display: 'flex', alignItems: 'center' } },
        [
          thumbnail
            && h('img', {
              attrs: { src: thumbnail },
              style: {
                width: '24px',
                height: '24px',
                marginRight: '8px',
                borderRadius: '4px',
                objectFit: 'cover',
              },
            }),
          h(
            'a',
            {
              attrs: { href: categoryUrl, target: '_blank' },
              style: { textDecoration: 'none', color: '#515a6e', ...attrMatch },
            },
            data.title,
          ),
          h(
            'a',
            {
              attrs: { href: spyUrl, target: '_blank' },
              style: { marginLeft: '5px' },
            },
            this.$t('SPY_BTN'),
          ),
        ],
      );
    },
  },
  created() {
    const raw = getShopeeCategoryTreeHome();
    this.fullTreeData = this.buildTree(raw, true);
    this.displayedTreeData = this.fullTreeData;
  },
};
</script>

<style lang="scss" scoped>
@import '@/vue/styles/tokens.scss';

.sp-cat-tree {
  display: flex;
  flex-direction: column;
  gap: 12px;

  &__search {
    .ivu-input {
      border-radius: $radius-item;
      border-color: $c-border-input;
      color: $c-text-strong;
      transition: border-color $motion-fast, box-shadow $motion-fast;

      &::placeholder {
        color: $c-text-placeholder;
      }

      &:hover {
        border-color: $c-brand-hover;
      }

      &:focus {
        border-color: $c-brand;
        box-shadow: 0 0 0 2px $c-brand-tint;
      }
    }
  }

  &__body {
    @include card(12px);
    @include scrollbar;

    max-height: 700px;
    overflow-y: auto;
  }

  ::v-deep .ivu-tree {
    ul {
      font-size: 13px;
    }

    li {
      margin: 2px 0;
    }

    .ivu-tree-title {
      display: block;
      padding: 4px 8px;
      border-radius: $radius-item;
      color: $c-text;
      transition: background-color $motion-fast, color $motion-fast;

      &:hover {
        background: $c-surface-alt;
      }
    }

    .ivu-tree-title-selected,
    .ivu-tree-title-selected:hover {
      background: $c-brand-tint;
      color: $c-brand;
    }

    .ivu-tree-arrow {
      color: $c-text-muted;
      transition: color $motion-fast;

      &:hover {
        color: $c-brand;
      }
    }

    a {
      color: $c-text;
      transition: color $motion-fast;

      &:hover {
        color: $c-brand;
      }

      + a {
        color: $c-link;
        font-size: 12px;
        font-weight: 600;

        &:hover {
          color: $c-link-hover;
        }
      }
    }

    img {
      border-radius: $radius-badge;
      background: $c-surface-alt;
      flex-shrink: 0;
    }
  }
}
</style>
