<!--
 * vue3的数据响应性
  -->
<script setup lang="ts">
import { ref, unref, reactive, toRaw } from 'vue';
import { useMessage } from 'src/common/hooks';
import { AUTHS } from '../config';

const { info } = useMessage();

const text = ref('夕阳西下');
const refObj = ref({
  name: '张三',
  age: 18,
});
const showTree = ref(false);
const state = reactive({
  name: '李四',
  age: 49,
  childs: {
    name: '李白',
    age: 111,
  },
  nodes: [] as any,
  ticked: [] as any,
});

function onView1() {
  console.log('查看1 =', text);
}

function onView2() {
  console.log('查看2 =', refObj);
}

function onChange() {
  text.value = '改变改变';
  info(unref(text));
}

function onViewState() {
  console.log('state', state);
}
function onToRawState() {
  console.log('toRaw(state) =', toRaw(state));
}

function onViewDefineProperty() {
  let o = {
    name: '张三',
    age: 18,
  };
  myreactive(o, 'name', 'zhang san');
  console.log('o >>>>', o.name);
  o.age = 20;
}

// 响应式函数
function myreactive(obj: any, key: any, value: any) {
  Object.defineProperty(obj, key, {
    get() {
      console.log(`访问了${key}属性`);
      return value;
    },
    set(val) {
      console.log(`将${key}由->${value}->设置成->${val}`);
      if (value !== val) {
        value = val;
      }
    },
  });
}

function onViewEffect() {
  let name = '孙师傅';
  let age = 18;
  let money = 200;
  let res1 = null;
  let res2 = null;
  let dep: any = new Set();

  const effect1 = () => {
    res1 = `${name},今年${age},有${money}元`;
  };
  const effect2 = () => {
    res2 = `刚满${age}岁没多少年的${name},已经拥有了巨额存款${money}元`;
  };

  // 收集依赖
  (function track() {
    dep.add(effect1);
    dep.add(effect2);
  })();
  console.log('dep >>>>', dep);

  // 通知变了进行更新
  function trigger() {
    for (let item of dep) {
      item();
    }
  }

  trigger(); // 第一次执行,初始化
  console.log(res1);
  console.log(res2);

  money = 400;
  age = 40;
  trigger(); // 数据更新

  console.log(res1);
  console.log(res2);
}

function onHandleMap() {
  const myMap = new Map();
  let data = [
    { name: 'fruits', subclass: ['苹果'] },
    { name: 'fruits', subclass: ['香蕉'] },
    { name: 'vegetable', subclass: ['西蓝花'] },
    { name: 'vegetable', subclass: ['芹菜'] },
    { name: 'vegetable', subclass: ['菠菜'] },
    { name: 'meat', subclass: ['猪肉'] },
  ];
  data.map((item: any) => {
    const key = item.name;
    let value = [];
    if (myMap.has(key)) {
      value = myMap.get(key);
    }
    value.push(item);
    myMap.set(key, value);
  });

  let arr = [];
  for (const [key, value] of myMap) {
    arr.push({
      name: key,
      children: value,
    });
  }
  console.log('myMap >>>>', myMap);
  console.log(arr);
}

function onClickHandleAuth() {
  let res = onHandleAuth(AUTHS, 0);
  res.map((item: any) => {
    let children_res = onHandleAuth(item.children, 1);
    item.children = children_res;

    item.children.map((el: any) => {
      el.children = onHandleAuth(el.children, 2);
    });
  });
  console.log('结果 =', res);
  state.nodes = res;
  // showTree.value = !showTree.value;
  showTree.value = true;
}

function onHandleAuth(data: any, index: number) {
  const lang = 'zh-CN';
  let myMap = new Map();
  data.map((item: any) => {
    item[`title_${index}`] = item.i18n[lang].split('/')[index];
    const nameList = item.name.split('/');
    const maxLevel = nameList.length;
    const currentName = nameList[index];
    const lastName = item[`name_${index - 1}`];
    if (lastName) {
      item[`name_${index}`] = `${lastName}/${currentName}`;
    } else {
      item[`name_${index}`] = currentName;
    }
    const key = item[`name_${index}`];

    let value = {
      id: item.id,
      title: item[`title_${index}`],
      name: key,
      children: [] as any,
    };
    if (myMap.has(key)) {
      let child = myMap.get(key).children;
      if (index + 1 < maxLevel) {
        child.push(item);
      }
      value.children = child;
    } else if (index + 1 < maxLevel) {
      value.children.push(item);
    }
    myMap.set(key, value);
  });

  let arr = [];
  for (const value of myMap.values()) {
    arr.push(value);
  }
  // console.log('data >>>>', data);
  // console.log('myMap >>>>', myMap);
  // console.log('arr >>>>', arr);
  return arr;
}

function onTicked() {
  console.log('查看勾选的节点 >>>>', state.ticked);
}
</script>
<template>
  <div class="fit">
    <div class="title">数据响应性</div>
    <div>
      <a href="https://juejin.cn/post/7001999813344493581" target="_blank"
        >参考链接</a
      >
    </div>
    <div class="q-mb-md">
      <q-card>
        <q-card-section>
          <div>
            <q-btn label="查看1" color="primary" @click="onView1" />
            <q-btn label="查看2" color="primary" @click="onView2" />
            <q-btn label="改变数据" color="primary" @click="onChange" />
          </div>
          <div>
            <q-chip square>{{ text }}</q-chip>
          </div>
        </q-card-section>
      </q-card>
    </div>
    <div class="q-mb-md">
      <q-card>
        <q-card-section>
          <q-btn label="查看state" color="primary" @click="onViewState" />
          <q-btn label="toRaw(state)" color="primary" @click="onToRawState" />
        </q-card-section>
      </q-card>
    </div>
    <div class="q-mb-md">
      <q-card>
        <q-card-section>
          <div>
            <q-chip square>Object.defineProperty</q-chip>
          </div>
          <div>
            <q-btn label="查看" color="primary" @click="onViewDefineProperty" />
          </div>
        </q-card-section>
      </q-card>
    </div>

    <div class="q-mb-md">
      <q-card>
        <q-card-section>
          <div>
            <q-btn
              label="订阅与更新简单版"
              color="primary"
              @click="onViewEffect"
            />
          </div>
        </q-card-section>
      </q-card>
    </div>

    <div class="q-mb-md">
      <q-card>
        <q-card-section>
          <div>
            <q-btn
              label="扁平化数据结构转tree"
              color="primary"
              @click="onHandleMap"
            />
            <q-btn
              label="权限扁平化数据结构转tree"
              color="primary"
              @click="onClickHandleAuth"
            />
            <q-btn label="查看勾选的节点" color="primary" @click="onTicked" />
          </div>
          <div>
            <q-tree
              v-if="showTree"
              :nodes="state.nodes"
              node-key="name"
              label-key="title"
              tick-strategy="leaf"
              default-expand-all
              v-model:ticked="state.ticked"
            />
          </div>
        </q-card-section>
      </q-card>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.title {
  font-size: 22px;
  color: #424242;
  margin-bottom: $padding-md;
}
</style>