<template>
  <section class="g-issue-list-box">
    <panel :blank="false">
      <template #header>
        <div class="g-issue-list-box-header">
          <span v-if="showCheckbox" class="g-issue-list-box-checkbox">
            <d-checkbox :half-checked="allCheckedHalf" v-model="allChecked" @change="onCheckChange" />
          </span>
          <slot name="header-left">
            <div class="g-issue-list-box-header-left">
              <div v-for="(item, index) in statusItems" :key="index" class="g-issue-list-box-status">
                <span v-if="item.icon" class="g-issue-list-box-status-icon">
                  <d-icon :name="item.icon" :size="item.size || size" :style="{ color: item.color }"></d-icon>
                </span>
                <span class="g-issue-list-box-status-title" :style="{ color: item.color, fontWeight: item.color ? 'bold' : '' }">
                  {{ item.title }}
                </span>
                <custom-tag v-if="item.count" border-color="transparent" bg-color="#EAEAEA" color="#606060">
                  {{ item.count }}
                </custom-tag>
              </div>
            </div>
          </slot>
        </div>
      </template>
      <template #headerRight>
        <slot name="header-right">
          右边插槽
        </slot>
      </template>
      <slot name="content">
        <div class="g-issue-list-box-content">
          <div v-for="(item, index) in localData"
               :key="`${item.id}_${index}`"
               class="g-issue-list-box-item"
               :class="{ 'is-last': index === localData.length - 1 }"
          >
            <span v-if="showCheckbox" class="g-issue-list-box-checkbox"><d-checkbox v-model="checkedList[index]" /></span>
            <slot :data="item" :index="index">
              列表内容插槽
            </slot>
          </div>
        </div>
      </slot>
    </panel>
  </section>
</template>

<script lang="ts">
export default {
  name: 'issue-list-box'
};
</script>

<script setup lang="ts">
import { ref, watch, nextTick } from 'vue';
import Panel from '@/components/Panel/index.vue';
import CustomTag from '@/components/CustomTag/index.vue';

const props = withDefaults(defineProps<{
  data: Record<string, any>[];
  showCheckbox?: boolean;
  size?: string;
  statusItems?: { icon?: string; count?: number; title: string; size?: string; color?: string; }[]
}>(), {
  data: () => [],
  showCheckbox: true,
  size: '18px',
  statusItems: () => []
});

const emits = defineEmits<{(e: 'change', data: Record<string, any>[]): void
}>();

const allChecked = ref<boolean>(false);
const allCheckedHalf = ref<boolean>(false);
const checkedList = ref<boolean[]>([]);

const localData = ref<Record<string, any>[]>([...props.data]);

watch(() => props.data, (val) => {
  if (JSON.stringify(val) !== JSON.stringify(localData.value)) {
    checkedList.value = [];
  }
  localData.value = [...val];
}, {
  deep: true,
  flush: 'post'
});

watch(() => allChecked.value, (val, oldValue) => {
  if (val === oldValue) return false;
  if (val) {
    nextTick(() => {
      setChecked(true);
    });
  } else {
    nextTick(() => {
      setChecked(false);
    });
  }
});

watch(() => checkedList.value, (val, oldValue) => {
  if (JSON.parse(JSON.stringify(val)) === JSON.parse(JSON.stringify(oldValue))) return false;
  handlerData(val);
  if ((checkedList.value).filter(item => item).length === localData.value.length) {
    allChecked.value = true;
  } else if (checkedList.value.length === 0 || checkedList.value.filter(item => !item).length === localData.value.length) {
    allChecked.value = false;
  } else {
    allCheckedHalf.value = true;
  }
}, {
  deep: true
});

const setChecked = (enable: boolean) => {
  if (!enable) {
    checkedList.value = [];
    allCheckedHalf.value = false;
    return false;
  }
  allCheckedHalf.value = false;
  const arr = [];
  localData.value.forEach((item, index) => {
    arr[index] = true;
  });
  checkedList.value = [...arr];
};

const onCheckChange = (val) => {
  if (val) allCheckedHalf.value = false;
};

const handlerData = (val) => {
  const arr = [];
  val.forEach((item, index) => {
    if (item) arr.push(index);
  });
  const data = localData.value.filter((item, index) => {
    return arr.includes(index);
  });
  emits('change', data);
};
</script>

<style scoped lang="scss">
$g-issue-list-box-border-color: #D3D3D3;
$g-issue-list-box-color: #606060;
.g-issue-list-box {
  &-header {
    display: flex;
    align-items: center;
  }
  &-checkbox {
    margin-right: 16px;
  }
  &-content {
    height: auto;
  }
  &-item {
    display: flex;
    align-items: center;
    padding: 32px 16px 16px 16px;
    border-bottom: 1px solid $g-issue-list-box-border-color;
    &.is-last {
      border-bottom: none;
    }
  }
  &-header-left {
    display: flex;
    align-items: center;
  }
  &-status {
    display: flex;
    align-items: center;
    margin-right: 32px;
    color: $g-issue-list-box-color;
    &:last-of-type {
      margin-right: 0;
    }
  }
  &-status-icon {
    margin-bottom: -4px;
  }
  &-status-title {
    padding: 0 8px 0 16px;
  }
}
</style>
