<template>
  <Popover
    v-model:open="popoverOpen"
    trigger="click"
    placement="bottomRight"
    :overlayClassName="`${prefixCls}__popover`"
    @open-change="handleOpenChange"
  >
    <template #title>
      <div :class="`${prefixCls}__title`">
        <Checkbox :indeterminate="indeterminate" :checked="checkAll" @change="onCheckAllChange">列展示</Checkbox>
      </div>
    </template>
    <template #content>
      <div :class="`${prefixCls}__list`">
        <CheckboxGroup v-model:value="draftCheckedList" :options="columnOptions" />
      </div>
      <div :class="`${prefixCls}__footer`">
        <a-button size="small" @click="handleReset">重置</a-button>
        <a-button size="small" type="primary" @click="handleSave">保存</a-button>
      </div>
    </template>
    <a-tooltip title="列设置">
      <a-button size="small" class="mixing-material-column-setting-btn" @click.stop>
        <Icon icon="ant-design:setting-outlined" />
      </a-button>
    </a-tooltip>
  </Popover>
</template>

<script lang="ts" setup>
  import { computed, ref, type PropType } from 'vue';
  import { Popover, Checkbox } from 'ant-design-vue';
  import type { CheckboxChangeEvent } from 'ant-design-vue/lib/checkbox/interface';
  import { Icon } from '/@/components/Icon';
  import { useMessage } from '/@/hooks/web/useMessage';
  import {
    MIXING_MATERIAL_LOCKED_COLUMN_KEYS,
    getMixingMaterialColumnSettingItems,
    saveMixingMaterialHiddenColumnKeys,
    type MixingMaterialColumnSettingItem,
  } from '../MesXslMixingSpec.data';

  const CheckboxGroup = Checkbox.Group;
  const prefixCls = 'mixing-material-column-setting';
  const { createMessage } = useMessage();

  const props = defineProps({
    hiddenKeys: {
      type: Array as PropType<string[]>,
      default: () => [],
    },
  });

  const emit = defineEmits<{
    (e: 'update:hiddenKeys', value: string[]): void;
    (e: 'change', value: string[]): void;
  }>();

  const popoverOpen = ref(false);
  const columnItems = ref<MixingMaterialColumnSettingItem[]>(getMixingMaterialColumnSettingItems());
  const allKeys = computed(() => columnItems.value.map((item) => item.key));
  const lockableKeys = computed(() => columnItems.value.filter((item) => !item.locked).map((item) => item.key));
  const draftCheckedList = ref<string[]>([]);

  const columnOptions = computed(() =>
    columnItems.value.map((item) => ({
      label: item.title,
      value: item.key,
      disabled: item.locked,
    })),
  );

  const checkAll = computed(() => {
    const keys = lockableKeys.value;
    return keys.length > 0 && keys.every((key) => draftCheckedList.value.includes(key));
  });

  const indeterminate = computed(() => {
    const keys = lockableKeys.value;
    const checkedCount = keys.filter((key) => draftCheckedList.value.includes(key)).length;
    return checkedCount > 0 && checkedCount < keys.length;
  });

  function ensureLockedChecked() {
    const next = new Set(draftCheckedList.value);
    MIXING_MATERIAL_LOCKED_COLUMN_KEYS.forEach((key) => next.add(key));
    draftCheckedList.value = Array.from(next);
  }

  function syncDraftFromHidden(hiddenKeys: string[]) {
    const hiddenSet = new Set(hiddenKeys || []);
    draftCheckedList.value = allKeys.value.filter((key) => !hiddenSet.has(key));
    ensureLockedChecked();
  }

  function buildHiddenKeysFromDraft() {
    ensureLockedChecked();
    return allKeys.value.filter((key) => !draftCheckedList.value.includes(key));
  }

  function handleOpenChange(open: boolean) {
    if (open) {
      syncDraftFromHidden(props.hiddenKeys);
    }
  }

  function onCheckAllChange(e: CheckboxChangeEvent) {
    draftCheckedList.value = e.target.checked ? [...allKeys.value] : [...MIXING_MATERIAL_LOCKED_COLUMN_KEYS];
  }

  function handleReset() {
    draftCheckedList.value = [...allKeys.value];
  }

  function handleSave() {
    const hiddenKeys = buildHiddenKeysFromDraft();
    saveMixingMaterialHiddenColumnKeys(hiddenKeys);
    emit('update:hiddenKeys', hiddenKeys);
    emit('change', hiddenKeys);
    createMessage.success('保存成功');
    popoverOpen.value = false;
  }
</script>

<style lang="less" scoped>
  .mixing-material-column-setting-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding-inline: 8px;
  }
</style>

<style lang="less">
  .mixing-material-column-setting__popover {
    .mixing-material-column-setting__title {
      min-width: 180px;
    }

    .mixing-material-column-setting__list {
      max-height: 320px;
      overflow-y: auto;
      margin-bottom: 8px;

      .ant-checkbox-group {
        display: flex;
        flex-direction: column;
        gap: 4px;
      }

      .ant-checkbox-group-item {
        margin-inline-start: 0;
        white-space: nowrap;
      }
    }

    .mixing-material-column-setting__footer {
      display: flex;
      justify-content: flex-end;
      gap: 8px;
      padding-top: 4px;
      border-top: 1px solid #f0f0f0;
    }
  }
</style>
