<script setup lang="ts">
import { Icon } from '@iconify/vue';
type Node = {
  [key: string]: any;
  selected?: boolean;
  children?: Node[];
};

type Props = {
  level?: number;
  keyTitle?: string;
  keySubtitle?: string;
  decoration?: {
    level?: number;
    bg?: string;
    fg?: string;
    icon?: string;
  }[];
};

const props = defineProps<Props>();

const currentStyle = props.decoration?.find((v) => {
  return v.level === (props.level || 0);
});

const nodes = defineModel<Node[]>('nodes', { required: true });
</script>

<template>
  <div class="tree-container">
    <div v-for="node in nodes" class="tree-item">
      <slot
        v-if="$slots['item']"
        name="item"
        :data="{ node, onclick: () => (node.selected = !node.selected) }"
      />
      <template v-else>
        <label class="row items-center">
          <input
            class="item__checkbox"
            type="checkbox"
            v-model="node.selected"
          />
          <Icon
            v-if="currentStyle?.icon"
            :icon="currentStyle.icon"
            class="item__icon"
          />
          <div class="column">
            <span class="item__title">
              {{ node[keyTitle || 'title'] || 'No Title' }}
            </span>
            <span class="item__subtitle">
              {{ node[keySubtitle || 'subtitle'] || 'No Subtitle' }}
            </span>
          </div>
        </label>
      </template>
      <div class="q-pl-xl">
        <TreeView
          v-if="node.children"
          v-model:nodes="node.children"
          :level="(level || 0) + 1"
          :decoration
        />
      </div>
    </div>
  </div>
</template>

<style lang="css">
.tree-container {
  display: flex;
  flex-direction: column;
  gap: 1rem;

  & .tree-item {
    & .item__checkbox {
      margin-right: 1rem;
    }

    & .item__icon {
      margin-right: 1rem;
    }

    & .item__title {
      font-weight: 600;
      color: var(--brand-1);
    }

    & .item__subtitle {
      font-size: 80%;
      color: hsla(var(--text-mute-2));
    }
  }
}
</style>
