<template>
  <Modal
    width="800px"
    title="媒体库"
    :open="visible"
    @ok="okHandler"
    :afterClose="afterClose"
    @cancel="emit('update:visible', false)"
    okText="确定"
    cancelText="取消"
    class="model-table"
  >
    <div>
      <div className="model-header">
        <p class="header-desc">
          已选择数据<span>（ {{ rowSelection.selectedRowKeys.length }} ）</span>
        </p>
        <div class="up-se">
          <span class="upload fun-ctrls">
            <ui-input
              class="input"
              :accept="ft"
              :maxSize="maxSize"
              @update:modelValue="(file: File) => uploadHandler(file)"
              type="file"
            >
              <template v-slot:replace>
                <Button type="primary" ghost>
                  <ui-icon type="add" class="icon" />上传文件
                </Button>
              </template>
            </ui-input>
          </span>
          <Search
            v-if="Object.keys(allData).length"
            className="content-header-search"
            placeholder="输入名称搜索"
            v-model:value="params.name"
            allow-clear
            style="width: 244px"
          />
        </div>
      </div>

      <div class="table-layout">
        <Table
          v-if="Object.keys(allData).length"
          :row-key="(record: Material) => record.id"
          :columns="cloumns"
          :rowSelection="rowSelection"
          :data-source="origin.list"
          :pagination="{ ...origin, current: origin.pageNum }"
          @change="handleTableChange"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'size'">
              {{ getSizeStr(record.size) }}
            </template>
            <template v-else-if="column.key === 'action'">
              <span>
                <a @click="delHandler(record.id)">删除</a>
              </span>
            </template>
          </template>
        </Table>
        <div style="padding: 1px" v-else>
          <Empty
            description="暂无结果"
            :image="Empty.PRESENTED_IMAGE_SIMPLE"
            className="ant-empty ant-empty-normal"
          />
        </div>
      </div>
    </div>
  </Modal>
</template>

<script lang="ts" setup>
import { Modal, Input, Table, Empty, TableProps, Button } from "ant-design-vue";
import { computed, reactive, ref, watch } from "vue";
import { createLoadPack, debounceStack, getSizeStr } from "@/utils";
import type { PagingResult } from "@/api";
import {
  addMaterial,
  delMaterial,
  fetchMaterialGroups,
  fetchMaterialPage,
  Material,
  MaterialGroup,
  MaterialPageProps,
} from "@/api/material";
import Message from "bill/components/message/message.vue";
import { Dialog } from "bill/expose-common";

const props = defineProps<{
  uploadFormat?: string[];
  format?: string[];
  maxSize?: number;
  visible: boolean;
  count?: number;
  afterClose?: () => void;
}>();

const emit = defineEmits<{
  (e: "update:visible", v: boolean): void;
  (e: "selectMaterials", v: Material[]): void;
}>();

const ft = computed(() => {
  const ft = props.uploadFormat || props.format;
  if (!ft) return void 0;
  return ft.map((t) => `.${t}`).join(",");
});

const Search = Input.Search;
const params = reactive({
  pageNum: 1,
  pageSize: 10,
  groupIds: [],
  formats: props.format,
}) as MaterialPageProps;
const origin = ref<PagingResult<Material[]>>({
  list: [],
  pageNum: 1,
  pageSize: 10,
  total: 0,
});
const groups = ref<MaterialGroup[]>([]);
const selectKeys = ref<Material["id"][]>([]);
const allData: Record<Material["id"], Material> = reactive({});

const rowSelection: any = ref({
  selectedRowKeys: selectKeys,
  onChange: (ids: number[]) => {
    const otherPageKeys = selectKeys.value.filter(
      (key) => !origin.value.list.some((item) => key === item.id)
    );
    const newKeys = Array.from(new Set([...otherPageKeys, ...ids]));
    if (typeof props.count !== "number" || props.count >= newKeys.length) {
      selectKeys.value = newKeys;
    } else {
      Message.error(`最多选择${props.count}项`);
    }
  },
  getCheckboxProps: (record: Material) => {
    return {
      disabled:
        (props.format && !props.format.includes(record.format)) ||
        (props.maxSize && record.size > props.maxSize),
    };
  },
});
const cloumns = computed(() => [
  {
    title: "名称",
    dataIndex: "name",
    key: "name",
  },
  {
    width: "100px",
    title: "格式",
    dataIndex: "format",
    key: "format",
  },
  {
    width: "100px",
    title: "大小",
    dataIndex: "size",
    key: "size",
  },
  {
    width: "100px",
    title: "分组",
    dataIndex: "group",
    key: "group",
    filters: groups.value.map((g) => ({
      text: g.name,
      value: g.id,
    })),
  },
  {
    title: "操作",
    key: "action",
  },
]);

const fetchData = createLoadPack(() =>
  Promise.all([fetchMaterialGroups(), fetchMaterialPage(params)])
);
const refresh = debounceStack(
  fetchData,
  ([group, pag]) => {
    groups.value = group;
    origin.value = pag;
    pag.list.forEach((item) => (allData[item.id] = item));
    if (pag.pageNum > 1 && pag.pageNum > Math.ceil(pag.total / pag.pageSize)) {
      params.pageNum = Math.ceil(pag.total / pag.pageSize);
      refresh();
    }
  },
  160
);

const uploadHandler = async (file: File) => {
  await addMaterial(file);
  refresh();
};

watch(params, refresh, { immediate: true, deep: true });

const addHandler = async (file: File) => {
  await addMaterial(file);
  refresh();
};
const delHandler = async (id: Material["id"]) => {
  if (await Dialog.confirm("确定要删除此数据吗？")) {
    await delMaterial(id);
    const ndx = selectKeys.value.indexOf(id);
    console.log(selectKeys.value, id);
    if (~ndx) {
      selectKeys.value.splice(ndx, 1);
    }
    refresh();
  }
};

const okHandler = () => {
  emit(
    "selectMaterials",
    selectKeys.value.map((id) => allData[id])
  );
};
const handleTableChange: TableProps["onChange"] = (pag, filters) => {
  params.pageSize = pag.pageSize!;
  params.pageNum = pag.current!;
  params.groupIds = filters.group as number[];
};
</script>

<style lang="less" scoped>
.model-header {
  display: flex;
  justify-content: space-between;
  padding-bottom: 24px;
  align-items: center;
}

.table-layout {
  max-height: 500px;
  overflow-y: auto;
}
.up-se {
  display: flex;
  align-items: center;

  .upload {
    margin-right: 10px;
    width: 100px;
    // overflow: hidden;
  }
}
</style>

<style lang="less">
.model-header .header-desc {
  margin-bottom: 0;
}

.ant-modal-root .ant-table-tbody > tr > td {
  word-break: break-all;
}

.content-header-search {
  flex: 1;
}
</style>
