<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
  name: "ModelTableModule",
});
</script>

<script setup lang="ts">
import Icon from "@/components/Module/Icon/index.vue";
import ModuleCard from "@/views/dataManage/index/components/Card/ModuleCard.vue";
import { ref, unref, computed, reactive, onMounted, h } from "vue";
import {
  Space,
  Button,
  Table,
  Input,
  Switch,
  message,
  Popover,
  Upload,
  Tooltip,
  Modal,
  Tag,
} from "ant-design-vue";
// import { EyeOutlined } from ''
import dayjs from "dayjs";
import { router } from "@/router/index.ts";
import UpdateModal from "@/views/setting/model/index/components/Modal/UpdateModal.vue";

interface PropsType {
  base: Record<string, any>;
  pageRef: HTMLElement;
}

const props = withDefaults(defineProps<PropsType>(), {
  base: () => {
    return {};
  },
  pageRef: () => {
    return {};
  },
});

interface TableOptions {
  selectedRowKeys: string[];
  loading: boolean;
  list: Array<Record<string, any>>;
  total: number;
  pageParams: {
    page: number;
    size: number;
  };
}

// 表头
const columns = [
  {
    title: "模型名称",
    dataIndex: "name",
    width: "300px",
  },

  {
    title: "python环境激活脚本",
    dataIndex: "script",
    maxWidth: 800,
    ellipsis: true,
  },
  {
    title: "配置文件",
    dataIndex: "config_files",
    maxWidth: 800,
    ellipsis: true,
  },
  {
    title: "预训练权重集",
    dataIndex: "pretrained_weights",
    maxWidth: 800,
    ellipsis: true,
  },
  {
    title: "已训练权重集",
    dataIndex: "tasks",
    maxWidth: 800,
    ellipsis: true,
  },

  {
    title: "操作",
    dataIndex: "operate",
    width: "140px",
  },
];

const loading = computed(() => {
  return (
    props.base.requestMap.listRequest.loading.value ||
    props.base.requestMap.addRequest.loading.value ||
    props.base.requestMap.updateRequest.loading.value ||
    props.base.requestMap.deleteRequest.loading.value
  );
});

// 表格配置项
const state = reactive<TableOptions>({
  loading: false, // 是否在请求
  selectedRowKeys: [], // 选中的数据
  list: props.base.state.modelList, // 列表
  total: props.base.state.modelList.value.length, // 总数
  pageParams: {
    //分页
    page: 1,
    size: 10,
  },
});

const showList = computed(() => {
  console.log("props.task.state.modelList", props.base.state.modelList);
  const { page, size } = state.pageParams;
  const start = (page - 1) * size;
  const end = page * size;
  const listSlice = state.list.slice(start, end);
  return listSlice;
});

// 表格选中配置
const rowSelection = {
  selectedRowKeys: state.selectedRowKeys,
  onSelect: (record: Record<string, any>, selected: boolean) => {
    const { id } = record;
    console.log("record", record);
    const i = state.selectedRowKeys.indexOf(id);
    if (i >= 0) {
      state.selectedRowKeys.splice(i, 1);
    } else {
      state.selectedRowKeys.push(id);
    }
    console.log("selectIds", state.selectedRowKeys);
    // console.log("state.selectedRowKeys", state.selectedRowKeys);
  },
  onSelectAll: (selected: boolean) => {
    if (selected) {
      state.selectedRowKeys = state.list.map((item: Record<string, any>) => item.id);
    } else {
      state.selectedRowKeys = [];
    }
    console.log("selectIds", state.selectedRowKeys);
  },
};

// 操作区
const operateList = [
  {
    name: "添加模型",
    icon: "plus",
    key: "add",
    customClass: "custom-btn",
  },
];

const updateModalRef = ref();

// 导出
const onAdd = () => {
  updateModalRef.value.onOpen();
};

const showDetailModal = (info: Record<string, any>) => {
  updateModalRef.value.onOpen("detail", info);
};

// 操作区点击
const onMenuSelect = (item: Record<string, any>) => {
  console.log("item", item);
  const eventMap: Record<string, (...args: any[]) => any> = {
    add: onAdd,
  };
  if (eventMap[item.key]) {
    eventMap[item.key]();
  }
};

// 获取列表
const getList = async () => {
  props.base.api.getList();
};

// 显示删除弹出层
const onShowDelete = async (info: Record<string, any>) => {
  console.log("info", info);
  const res = await props.base.api.onShowModelDelete(info.id);
  if (res?.code == 200) {
    getList();
  }
};

// 分页
const onPageChange = async (options: Record<string, any>) => {
  const { current, pageSize } = options;
  state.pageParams.page = current;
  state.pageParams.size = pageSize;
  // await getList();
};

const navigator = (options: Record<string, any>) => {
  const { path, params } = options;
  router.push({
    path,
    query: params,
  });
};

// 开启编辑的索引
const editIndex = ref(-1);
const editText = ref("");

const onUpdateEditText = (e: Record<string, any>) => {
  editText.value = e.target.value;
};

// 设置编辑的索引
const onSetEditIndex = (number: number) => {
  editIndex.value = number;
  if (number == -1) {
    editText.value = "";
  } else {
    const useData = state.list[number];
    const useText = useData.name || "";
    editText.value = useText;
  }
};

// 是否在编辑保存中
const editLoading = ref<boolean>(false);

// 更新数据
const onUpdate = async (info: Record<string, any>) => {
  const params = {
    id: info.id,
    name: info.name,
  };
  console.log("info", info);
  const res = await props.base.api.updateModel(params);
  props.base.api.getList();
  if (res?.code == 200) {
    message.success("修改成功");
  }
  console.log("res", res);
  // editLoading.value = true;
  // await sleep(1000);
  // editLoading.value = false;
  // console.log("updateFinish");
};

// 状态切换
const onStatusChange = (checked: boolean | string | number, e: Event) => {
  console.log("onStatusChange", e);
};

// 完成编辑
const afterEdit = async (info: Record<string, any>) => {
  await onUpdate(info);
  onSetEditIndex(-1);
};

const uploadingList = ref<boolean[]>([])

const showUploading = computed(() => {
  const { page, size } = state.pageParams;
  const start = (page - 1) * size;
  const end = page * size;
  const listSlice = uploadingList.value.slice(start, end);
  return listSlice;
})

// 上传预训练
const onUploadPretrained = (info: Record<string, any>) => {
  const { file, row, index } = info;

  const formData = new FormData()
  formData.append("file", file);
  formData.append("modelId", row.id);
  uploadingList.value[index] = true
  props.base.api.importPretrainedForModel(formData).finally(() => {
    uploadingList.value[index] = false
  }).then(() => {
    getList();
  })

  return false;
};



const onShowPretrainedDelete = async (info: Record<string, any>) => {
  const { row, path } = info
  const params = {
    modelId: row.id,
    path: path
  }
  const res = await props.base.api.onShowPretrainedDelete(params);
  if (res?.code == 200) {
    getList();
  }
};

// 初始化
const init = () => {};

onMounted(() => {
  init();
});

const prefix = "model-manage";
</script>

<template>
  <div :class="prefix">
    <ModuleCard title="模型管理">
      <template #head-extra>
        <Space :size="20">
          <Button
            type="primary"
            v-for="item in operateList"
            :class="item.customClass"
            @click="onMenuSelect(item)"
          >
            <template #icon>
              <Icon :name="item.icon" />
            </template>
            {{ item.name }}
          </Button>
        </Space>
      </template>
      <div>
        <Table
          :loading="loading"
          rowKey="id"
          :dataSource="showList"
          :columns="columns"
          :pagination="{
            showSizeChanger: true,
            total: props.base.state.modelList.value.length,
            pageSize: state.pageParams.size,
            current: state.pageParams.page,
          }"
          @change="onPageChange"
        >
          <template #bodyCell="{ column, text, index, record }">
            <template v-if="['createTime', 'markerTime'].includes(column.dataIndex as string)">
              {{ dayjs(text).format("YYYY-MM-DD HH:mm:ss") }}
            </template>
            <!-- 名称 -->
            <template v-if="column.dataIndex == 'name'">
              <div class="marker-row" v-if="editIndex == index">
                <div class="marker-input">
                  <Input :value="editText" @change="onUpdateEditText" />
                </div>
                <div class="marker-operate">
                  <Space>
                    <Button
                      type="text"
                      @click="
                        afterEdit({
                          ...record,
                          name: editText,
                        })
                      "
                    >
                      <template #icon>
                        <Icon name="correct" style="font-size: 20px" />
                      </template>
                    </Button>
                    <Button type="text" @click="onSetEditIndex(-1)">
                      <template #icon>
                        <Icon name="close" />
                      </template>
                    </Button>
                  </Space>
                </div>
              </div>
              <div class="marker-row" v-else @click="onSetEditIndex(index)">
                <div class="marker-text">{{ record.name || "" }}</div>
              </div>
            </template>
            <!-- python环境激活脚本 -->
            <template v-if="column.dataIndex == 'script'">
              <Popover>
                <template #content>
                  <div v-html="text.replace(/\n/g, '<br/>')"></div>
                </template>
                <div class="marker-row width-limit-800">
                  <div class="marker-text">{{ text }}</div>
                </div>
              </Popover>
            </template>
            <!-- 已训练权重集 -->
            <template v-if="column.dataIndex == 'tasks'">
              <Popover arrow-point-at-center :getPopupContainer="(e: HTMLElement) => props.pageRef">
                <template #content>
                  <div class="wrapper" style="max-height: 600px; overflow: auto;">
                    <div class="index-box" v-for="(item, index) in record.tasks">
                      <div class="index-box-circle">{{ index + 1 }}</div>
                      <div class="index-box-text">{{ item.description }}</div>

                    </div>
                  </div>
                </template>
               {{ record.tasks.map((item: Record<string, any>) => item.description).join(',') }}
              </Popover>
            </template>
            <!-- 配置文件 -->
            <template
              v-if="['config_files'].includes(column.dataIndex as string)"
            >
              <Popover arrow-point-at-center :getPopupContainer="(e: HTMLElement) => props.pageRef">
                <template #content>
                  <div class="wrapper" style="max-height: 600px; overflow: auto;">
                    <div class="index-box" v-for="(item, index) in text.split(',')">
                      <div class="index-box-circle">{{ index + 1 }}</div>
                      <div class="index-box-text">{{ item }}</div>
                    </div>
                  </div>
                </template>
                {{ text }}
              </Popover>
            </template>
            <!-- 预训练权重集 -->
            <template
              v-if="['pretrained_weights'].includes(column.dataIndex as string)"
            >
            <div>
              <Upload
                :multiple="false"
                :before-upload="(e: File, fileList: File[]) => onUploadPretrained({
                  file: e,
                  fileList: fileList,
                  row: record,
                  index: index
                })"
                :disabled="showUploading[index] || false"
                :showUploadList="false"
                :max-count="1"
                style="width: 100%"
                >
                <Button
                  type="primary"
                  size="small"
                  style="display: flex; align-items: center; justify-content: center; aspect-ratio: 1; padding: 0"
                  :loading="showUploading[index] || false">
                  <PlusOutlined v-if="!showUploading[index]"/>
                </Button>
              </Upload>

              <Popover arrow-point-at-center :getPopupContainer="(e: HTMLElement) => props.pageRef" v-if="text.trim().length">
                <template #content>
                  <div class="wrapper" style="max-height: 600px; overflow: auto;">
                    <div class="index-box" v-for="(item, index) in text.split(',').filter(item => item)">
                      <div class="index-box-circle">{{ index + 1 }}</div>
                      <div class="index-box-text">{{ item }}</div>
                      <div class="index-box-danger" @click="onShowPretrainedDelete({
                        row: record,
                        path: item
                      })">
                        <Icon name="delete" />
                      </div>
                    </div>
                  </div>
                </template>
                <Button type="text" size="small">
                  <EyeOutlined />
                </Button>
              </Popover>
            </div>

            </template>
            <!-- 状态 -->
            <template v-if="column.dataIndex === 'status'">
              <Switch
                checked-children="启用"
                un-checked-children="停用"
                v-model:checked="record.status"
                @change="onStatusChange"
              />
              <!-- <Tag :color="statusColorMap[text]">{{ statusMap[text] }}</Tag> -->
            </template>
            <!-- 编辑 -->
            <template v-if="column.dataIndex === 'operate'">
              <Space :size="10">
                <a @click="showDetailModal(record)"> 查看 </a>
                <a class="delete-link" @click="onShowDelete(record)"> 删除 </a>
              </Space>
            </template>
          </template>
        </Table>
      </div>
    </ModuleCard>
  </div>
  <UpdateModal ref="updateModalRef" v-bind="props" @onSuccess="getList" />
</template>

<style lang="scss" scoped>
$prefix: "model-manage";

.#{$prefix} {
  width: 100%;
  height: 100%;
  .custom-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    border-radius: 4px 4px 4px 4px;
    padding: 8px 16px;
  }
  .grey-btn {
    background: #aab5c4;
  }

  .delete-link {
    color: #dd524c;
  }
  :deep(.ant-table-wrapper) {
    .ant-table {
      border-radius: 0;
      background: transparent;
      .ant-table-thead {
        > tr > th {
          border-bottom: none;
          background-color: #fff;
          &::before {
            background-color: #d8d8d8 !important;
          }
        }
        > tr > td {
          border-top: none;
        }
      }
      .ant-table-tbody > tr.ant-table-placeholder:hover > td {
        background-color: transparent;
      }
    }

    .ant-table-container table > thead > tr:first-child > *:first-child {
      border-start-start-radius: 0;
    }
    .ant-table-container table > thead > tr:first-child > *:last-child {
      border-start-end-radius: 0px;
    }
  }
  .marker-row {
    width: 100%;
    // max-width: 800px;
    display: flex;
    align-items: center;
    justify-self: start;
    gap: 10px;
    &:hover {
      .marker-edit {
        display: block;
      }
    }
  }
  .marker-text {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .width-limit-800 {
    // max-width: 100%;
  }
  .custom-btn {
    // display: flex;
    // align-items: center;
    // justify-content: center;
    span {
      line-height: 24px;
    }
  }
}
</style>
