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

<script setup lang="ts">
import ModuleCard from "@/views/dataManage/index/components/Card/ModuleCard.vue";
import {
  Form,
  FormItem,
  Select,
  SelectOption,
  Checkbox,
  CheckboxGroup,
  Row,
  Col,
  Spin,
} from "ant-design-vue";
import BarChat from "@/views/modelReasoning/index/components/Module/BarChat.vue";
import { computed, unref, ref } from "vue";

interface PropsType {
  performance: Record<string, any>;
  reasoning: Record<string, any>;
  // data: Record<string, any>[];
}

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

const form = ref<Record<string, any>>({
  dataSource: null,
  modelId: [],
  checkpointDir: [],
  configFile: null,
});

const sourceOptions = computed(() => {
  return props.reasoning.state.datasetList.value.map((item: Record<string, any>) => {
    return {
      label: item.name,
      value: item.id,
    };
  });
});

// 数据源变更
const onDatasourceChange = async (e: string | any, ...args: any) => {
  console.log("onModelChange", e);
  if (e) {
    await props.performance.api.getModelsByDataset(e);
    form.value.modelId = [];
    weightOptions.value = [];
    form.value.checkpointDir = [];
  }
};

// 取消模型选择
const onModelDeselect = async (e: string | any, ...args: any) => {
  console.log("onModelDeselect", e);
  form.value.modelId = form.value.modelId.filter((item: string) => item != e);
  const i = weightOptions.value.findIndex((item: Record<string, any>) => {
    return item.id == e;
  });

  if (i >= 0) {
    weightOptions.value.splice(i, 1);
  }
};

// 模型变更
const onModelSelect = async (e: string | any, ...args: any) => {
  form.value.modelId.push(e);
  const res = await onGetModelWeightDir(e);
  if (res?.code == 200) {
    const opt = {
      id: e,
      opt: res.data.directories,
    };
    weightOptions.value.push(opt);
  }
};

// 获取对比数据
const getPerformanceData = async (params?: Record<string, any>) => {
  const useParams = params || {
    datasetName: form.value.dataSource,
    modelName: form.value.modelId,
    checkpoint_dir: form.value.checkpointDir,
  };
  const res = await props.performance.api.getPerformance(useParams);
  return res;
};

const modelOptions = computed(() => {
  if (!form.value.dataSource) return [];
  else {
    const { models } = props.performance.state.models.value;
    if (models)
      return models.map((item: Record<string, any>) => {
        return {
          label: item.name,
          value: item.id,
        };
      });
    else return [];
  }
});

/**
 * 权重列表
 * modelId: directories
 * */
const weightOptions = ref<Record<string, any>>([]);

// 获取模型权重
const onGetModelWeightDir = async (modelId: string) => {
  return await props.reasoning.api.getModelWeightOptions(modelId);
};

const dirOptions = computed(() => {
  const modelIds = form.value.modelId;
  if (!modelIds?.length) return [];
  const opts: Record<string, any> = [];
  weightOptions.value
    .filter((item: Record<string, any>) => {
      return modelIds.includes(item.id);
    })
    .forEach((item: Record<string, any>) => {
      item.opt.forEach((opt: Record<string, any>) => {
        opts.push({
          label: opt.description,
          value: opt.id,
          modelId: item.id,
        });
      });
    });
  return opts;
  // if (!form.value.modelId) return [];
  // else {
  //   const { directories } = props.reasoning.state.modelWeightOptions.value;
  //   if (!directories?.length) return [];
  //   const dirs = directories.map((item: Record<string, any>) => {
  //     return {
  //       label: item.description,
  //       value: item.id,
  //     };
  //   });
  //   return dirs;
  // }
});

/**
 * @desc 存储结果 modelId-weightId: performanceData
 * @auth yjc
 * @created 2025-11-06 18:41
 * @since v1.0.0
 */
const performanceData = ref<Record<string, any>>({});

// 权重变化
const onDirChange = async (e: string, opt: Record<string, any>) => {
  console.log("onDirChange", e, opt);
  // const res = await getPerformanceData();
  // if (res?.code == 200) {
  //   props.performance.api.onUpdateChatOptions(res.data?.records || []);
  // }
};

// 权重选择
const onDirSelect = async (e: string, opt: Record<string, any>) => {
  console.log("onDirSelect", e, opt);
  const target = dirOptions.value.find((item: Record<string, any>) => {
    return item.value == e;
  });
  console.log("traget", target, e);
  if (target) {
    const modelId = target.modelId;
    const params = {
      datasetName: form.value.dataSource,
      modelName: modelId,
      checkpoint_dir: e,
    };
    const res = await getPerformanceData(params);
    const rawData = {
      model: {},
      weight: target,
      data: {},
    };
    if (res?.code == 200) {
      const model = modelOptions.value.find((item: Record<string, any>) => {
        return item.value == modelId;
      });
      if (model) rawData.model = model;
      rawData.data = res.data;
    }
    performanceData.value[`${modelId}_${e}`] = rawData;
  }
  console.log("performanceData", performanceData.value);
};

// 取消权重选择
const onDirDeselect = (e: string, opt: Record<string, any>) => {
  console.log("onDirDeselect", e, opt);
  const target = dirOptions.value.find((item: Record<string, any>) => {
    return item.value == e;
  });
  console.log("target", target);
  delete performanceData.value[`${target.modelId}_${e}`];
  console.log("showOptions222", showOptions.value);
};

const compareForm = ref<Record<string, any>>({
  eva_batch_top1: true,
  eva_class_top1: true,
  point_acc: true,
});

const loading = computed(() => {
  return (
    props.reasoning.requestMap.datasetListRequest.loading.value ||
    props.performance.requestMap.getPerformanceRequest.loading.value
  );
});

const showOptions = computed(() => {
  const options = JSON.parse(JSON.stringify(props.performance.state.performanceOptions.value));
  console.log("showOptions", options);
  const series = options.series;
  const formData = unref(compareForm);
  const groups = Object.keys(performanceData.value);
  console.log("performanceData", performanceData.value);

  const useGroupData = [];
  groups.map((groupName: string) => {
    const groupData = performanceData.value[groupName];
    const model = groupData.model;
    const weight = groupData.weight;
    const record = {
      ...groupData,
      modelInfo: model,
      weightInfo: weight,
    };
    console.log("record", record);
    const formatData = props.performance.api.createChatOptions(record);
    console.log("formatData", formatData);
    // options.xAxis[0].data.push(xName);
    useGroupData.push(formatData);
  });
  useGroupData.map((item) => {
    const groupName = item.groupName;
    const useSeries = item.series;
    options.xAxis[0].data = [...options.xAxis[0].data, `${groupName}`];
    options.series.forEach((seriesItem: Record<string, any>, index: number) => {
      const target = useSeries.find((grid: Record<string, any>) => {
        return grid.key == seriesItem.key;
      });
      if (!target) return;
      console.log("target", target, seriesItem);
      if (!seriesItem.data) {
        const seriesKeys = Object.keys(target);
        seriesKeys.map((seriesKey: string) => {
          seriesItem[seriesKey] = target[seriesKey];
        });
        seriesItem.data = [];
      }
      if (target) {
        seriesItem.data.push(target.data[0]);
      } else {
        seriesItem.data.push(0);
      }
    });
  });
  console.log("finish", options);
  // console.log("useGroupData", useGroupData);
  // 组：ModelId-weightId: performanceData
  // groups.map((groupKey: string) => {
  //   const series = options.series;
  //   const formData = unref(compareForm);
  //   const showSeries = series.filter((item: Record<string, any>, index: number) => {
  //     console.log("item", item);
  //     const key = item.key;
  //     const show = formData[key];
  //     return show;
  //     // const i = seriesIndexMap[key]
  //   });
  // })
  // options.series = showSeries;

  // performanceData.value

  return options;
});

console.log("showOptions", showOptions);

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

<template>
  <div :class="prefix">
    <Spin :spinning="loading">
      <ModuleCard title="模型对比" :customClass="`${prefix}-container`">
        <div :class="`${prefix}-wrapper`">
          <div :class="`${prefix}-content`">
            <Form :model="form" ref="formRef" layout="vertical">
              <Row :gutter="[0, 10]">
                <Col :span="24">
                  <FormItem label="数据来源">
                    <Select
                      placeholder="请选择数据来源"
                      v-model:value="form.dataSource"
                      @change="onDatasourceChange"
                    >
                      <SelectOption v-for="item in sourceOptions" :value="item.value">{{
                        item.label
                      }}</SelectOption>
                    </Select>
                  </FormItem>
                </Col>
                <Col :span="24">
                  <FormItem label="模型">
                    <Select
                      placeholder="请选择模型"
                      mode="multiple"
                      :value="form.modelId"
                      @select="onModelSelect"
                      @deselect="onModelDeselect"
                    >
                      <SelectOption v-for="item in modelOptions" :value="item.value">{{
                        item.label
                      }}</SelectOption>
                    </Select>
                  </FormItem>
                </Col>

                <Col :span="24">
                  <FormItem label="权重">
                    <Select
                      mode="multiple"
                      placeholder="请选择权重"
                      :loading="props.reasoning.requestMap.modelWeightOptionsRequest.loading.value"
                      v-model:value="form.checkpointDir"
                      @select="onDirSelect"
                      @deselect="onDirDeselect"
                    >
                      <SelectOption v-for="item in dirOptions" :value="item.value"
                        >{{ item.label }}
                      </SelectOption>
                    </Select>
                  </FormItem>
                </Col>
              </Row>
            </Form>
          </div>
        </div>
        <div :class="`${prefix}-wrapper auto-size`">
          <div :class="`${prefix}-content--performance`">
            <div :class="`${prefix}-form`">
              <div :class="`${prefix}-desc`">选择对比性能</div>
              <Checkbox v-model:checked="compareForm.eva_batch_top1">批平均准确率</Checkbox>
              <Checkbox v-model:checked="compareForm.eva_class_top1">类平均准确率</Checkbox>
              <Checkbox v-model:checked="compareForm.point_acc">点平均准确率</Checkbox>
            </div>
            <div :class="`${prefix}-chat`">
              <BarChat :options="showOptions" />
            </div>
          </div>
        </div>
      </ModuleCard>
    </Spin>
  </div>
</template>

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

.#{$prefix} {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: start;
  justify-content: start;
  flex-direction: column;
  :deep(.ant-spin-nested-loading) {
    width: 100%;
    height: 100%;
    .ant-spin-container {
      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;
  }
  &-container {
    :deep(.module-card-body) {
      display: flex;
      align-items: start;
      justify-content: start;
      flex-direction: column;
    }
  }
  &-wrapper {
    width: 100%;
    margin-bottom: 20px;
    &:last-child {
      margin-bottom: 0;
    }
  }
  &-desc {
    font-family:
      Source Han Sans,
      Source Han Sans;
    font-weight: 350;
    font-size: 12px;
    color: #4b5563;
    line-height: 16px;
    text-align: left;
    font-style: normal;
    text-transform: none;
    margin-bottom: 8px;
  }
  &-content {
    width: 100%;
    &--performance {
      height: 100%;
      display: flex;
      align-items: start;
      justify-content: start;
      gap: 50px;
    }
    :deep(.ant-form-item) {
      margin-bottom: 0;
      .ant-form-item-label {
        padding: 0;
        margin-bottom: 4px;
        label {
          font-family:
            Source Han Sans,
            Source Han Sans;
          font-weight: 350;
          font-size: 12px;
          color: #4b5563;
          line-height: 16px;
          text-align: left;
          font-style: normal;
          text-transform: none;
        }
      }
    }
  }
  &-form {
    width: 140px;
    height: 100%;
    :deep(.ant-checkbox-wrapper) {
      margin-bottom: 13px;
    }
  }
  &-chat {
    height: 100%;
    flex: 1;
  }
  .auto-size {
    flex: 1;
    width: 100%;
    align-self: stretch;
  }
}
</style>
