import { reactive, Ref, ref } from 'vue';
import { Button, Popover, Checkbox } from 'ant-design-vue';
import { MenuOutlined, FilterTwoTone } from '@ant-design/icons-vue';
import 'ant-design-vue/es/popover/style';
import 'ant-design-vue/es/button/style';
import 'ant-design-vue/es/checkbox/style';
import Draggable from 'vuedraggable';

import './style/index.less';
import {
  getColumnsAOrM,
  getColumnsByTableValue,
  getTableValueExtra,
  insertColumnsAOrM,
  parseExclude
} from './utils';
import TCOLocalStorage, { Table, TableValue } from './tcoLocalStorage';
import { TableColumnsOperate } from '../../types';

/**
 * table headerCell 插槽渲染
 */
const useHeaderCell = ({
  TCOShowIcon,
  TCOPopoverVisible,
  TCOList: _TCOList,
  tableColumnsOperate,
  tcoLocalStorage,
  onSave,
  onReset
}: {
  TCOShowIcon: Record<string, boolean>;
  TCOPopoverVisible: Record<string, boolean>;
  TCOList: Ref<any[]>;
  tableColumnsOperate: Ref<TableColumnsOperate>;
  tcoLocalStorage: TCOLocalStorage;
  onSave?(): void;
  onReset?(): void;
}) => {
  let { initHidden } = tableColumnsOperate.value;
  const { lotId, tableName } = tableColumnsOperate.value;
  initHidden = parseExclude(initHidden);

  let tableValue: TableValue[] =
    tcoLocalStorage.get(lotId, tableName)?.value || [];

  // 根据缓存数据进行排序，输出正确的顺序
  const initTCOList = () => {
    let arr = _TCOList.value;
    // 根据本地缓存数据，输出正确的顺序和展示对应的列
    if (tableValue.length > 0) {
      const columnsByTableValue = getColumnsByTableValue(
        arr,
        tableValue,
        () => true
      );
      const columnsAOrM = getColumnsAOrM(arr, tableValue);
      arr = insertColumnsAOrM(columnsByTableValue, columnsAOrM);
    }
    return arr;
  };
  const TCOList = ref<any[]>(initTCOList());

  // 初始化操作列需要的状态
  const initState = () => {
    let checkedList: string[] = TCOList.value
      .map((item: any) => item.dataIndex + '')
      // [initHidden，没有缓存的场景]排除初始化就需要不选中的项
      .filter(item => !initHidden?.includes(item));

    // 有缓存
    if (tableValue.length > 0) {
      checkedList = tableValue
        .filter(item => item.visible === 1)
        .map(item => item.dataIndex + '');

      // ✨ 有新增/修改的项，直接默认选中
      let columnsAOrM = getColumnsAOrM(_TCOList.value, tableValue);
      // [initHidden，有缓存的场景]排除初始化就需要不选中的项，从上面对比判断出这个项是后面新增的，且还需要判断这个项是否有被加入初始化不展示
      columnsAOrM = columnsAOrM.filter(
        (_: any) => !initHidden!.includes(_.item.dataIndex + '')
      );

      // push 到 checkedList 就表示选中了
      for (const item of columnsAOrM)
        checkedList.push(item.item.dataIndex + '');

      // ✨ 有删除的列，直接移除 checkedList 值
      const TCOListExtra = getTableValueExtra(_TCOList.value, tableValue);
      if (TCOListExtra.length > 0) {
        checkedList = checkedList.filter(
          _ => !TCOListExtra.find(item => item.dataIndex === _)
        );
      }
    }
    return {
      // 是否半选
      indeterminate:
        !!checkedList.length && checkedList.length < TCOList.value.length,
      checkAll: checkedList.length === TCOList.value.length,
      checkedList
    };
  };
  const state = reactive(initState());

  const handleCheckAllChange = (e: any) => {
    Object.assign(state, {
      checkedList: e.target.checked
        ? TCOList.value.map((item: any) => item.dataIndex + '')
        : [],
      indeterminate: false
    });
  };

  const handleCheckListChange = (val: any[]) => {
    const options = TCOList.value.map((item: any) => item.dataIndex + '');
    state.indeterminate = !!val.length && val.length < options.length;
    state.checkAll = val.length === options.length;
    state.checkedList = val;
  };

  // const handleDragEnd = () => {};

  const handleSave = (dataIndex: string) => {
    const res: TableValue[] = TCOList.value.map((item: any) => ({
      dataIndex: item.dataIndex + '',
      visible: +state.checkedList.includes(item.dataIndex + '')
    }));
    const { lotId = '', tableName = '' } = tableColumnsOperate.value;
    tcoLocalStorage.set(lotId, tableName, res);

    TCOPopoverVisible[dataIndex] = TCOShowIcon[dataIndex] = false;
    // 等弹框关闭之后再执行
    setTimeout(() => {
      onSave?.();
    }, 300);
  };

  /**
   * 重置
   */
  const handleReset = (dataIndex: string) => {
    tcoLocalStorage.reset(lotId, tableName);
    TCOPopoverVisible[dataIndex] = TCOShowIcon[dataIndex] = false;
    tableValue = tcoLocalStorage.get(lotId, tableName)?.value || [];
    TCOList.value = initTCOList();
    Object.assign(state, initState());

    // 等弹框关闭之后再执行
    setTimeout(() => {
      onReset?.();
    }, 300);
  };

  return ({ column }: any) => {
    const slots = {
      default: () => (
        <FilterTwoTone
          class={`table-columns-operate__trigger-icon absolute top-1/2 -translate-y-1/2 cursor-pointer font-[12px] text-[#bfbfbf] ${
            !column.sorter ? 'right-[8px]' : 'right-[4px]'
          } ${
            TCOShowIcon[column.dataIndex] === true ? 'opacity-100' : 'opacity-0'
          }`}
        />
      ),
      content: () => (
        <div class="max-h-[520px] flex flex-col">
          <div class="flex-1 overflow-y-auto">
            <div class="table-columns-operate__list-group-item">
              <Checkbox
                v-model:checked={state.checkAll}
                indeterminate={state.indeterminate}
                onChange={handleCheckAllChange}
              >
                全选
              </Checkbox>
            </div>
            <Checkbox.Group
              class="w-full"
              value={state.checkedList}
              onChange={handleCheckListChange}
            >
              <Draggable
                v-model={TCOList.value}
                // @ts-ignore
                handle=".handle"
                item-key="dataIndex"
                class="table-columns-operate__list-group"
                ghost-class="ghost"
                // onEnd={handleDragEnd}
                v-slots={{
                  item: ({ element }: any) => {
                    return (
                      <div class="table-columns-operate__list-group-item flex items-center justify-between">
                        <Checkbox
                          key={element.dataIndex + ''}
                          value={element.dataIndex + ''}
                        >
                          <div class="max-w-[100px] break-words">
                            {element.title}
                          </div>
                        </Checkbox>
                        <MenuOutlined class="handle cursor-move" />
                      </div>
                    );
                  }
                }}
              />
            </Checkbox.Group>
          </div>
          <div class="flex justify-end border-t border-0  border-solid border-[#f0f0f0] -mx-[16px] mt-[12px] pt-[4px] px-[16px] pb-[4px]">
            <div>
              <Button
                size="small"
                onClick={() => handleReset(column.dataIndex)}
              >
                重置
              </Button>
              <Button
                type="primary"
                size="small"
                class="ml-[12px]"
                onClick={() => handleSave(column.dataIndex)}
              >
                确定
              </Button>
            </div>
          </div>
        </div>
      )
    };

    const handleVisibleChange = (vis: boolean, dataIndex: string) => {
      TCOPopoverVisible[dataIndex] = vis;
      if (vis === false) TCOShowIcon[dataIndex] = false;
    };
    // return (
    //   <>
    //     {column.title}
    //     <Popover
    //       visible={TCOPopoverVisible[column.dataIndex]}
    //       overlayClassName="table-columns-operate-popover"
    //       placement="bottomRight"
    //       arrowPointAtCenter
    //       onVisibleChange={(vis: boolean) =>
    //         handleVisibleChange(vis, column.dataIndex)
    //       }
    //       title={tableColumnsOperate.value?.popoverTitle || '报表列筛选'}
    //       v-slots={slots}
    //     />
    //   </>
    // );

    return (
      <Popover
        visible={TCOPopoverVisible[column.dataIndex]}
        overlayClassName="table-columns-operate-popover"
        placement="bottomRight"
        arrowPointAtCenter
        onVisibleChange={(vis: boolean) =>
          handleVisibleChange(vis, column.dataIndex)
        }
        title={tableColumnsOperate.value?.popoverTitle || '报表列筛选'}
        v-slots={slots}
      />
    );
  };
};
export default useHeaderCell;
