<template>
  <div class="py-4">
    <!-- <p v-if="item.type !== QUESTION_TYPE_TEXT" class="survey-title">{{ item.number }} {{ item.config.desc }}</p>
    <div v-else-if="item.isHtml" class="survey-title" v-html="item.config.desc"></div>
    <p v-else class="survey-title">{{ item.config.desc }}</p> -->
    <!-- 临时选项 -->
    <!-- 常规显示 -->
    <template v-if="item.type === QUESTION_TYPE_TEMP_CHECK">
      <div class="text-left">
        <p class="survey-desc">{{ item.remark }}</p>
        <template v-if="props.child">
          <transition name="slide">
            <div class="text-right padding-top-10">
              <el-button
                color="#4B72F6"
                class="i-h-34px confirm-input-btn"
                @click="check(item, true)"
                >是</el-button
              >

              <el-button
                class="i-h-34px confirm-input-btn"
                @click="check(item, false)"
                >否</el-button
              >
            </div>
          </transition>
        </template>
      </div>
    </template>
    <div class="pb-3" v-if="item.config?.desc || item?.title" :border="false">
      <div class="text-gray-500 whitespace-pre-wrap">
        {{ item.config?.desc || item?.title }}
      </div>
      <div v-if="item.remark" class="text-xs text-gray-500 whitespace-pre-wrap">
        {{ item.remark }}
      </div>
    </div>
    <template v-if="item.type === QUESTION_TYPE_INPUT">
      <el-input
        v-model="item.value"
        :disabled="!!item.disabled"
        placeholder="请输入"
        :type="fieldTypeFormat(item.config?.rule)"
        autocomplete="false"
        border
        @blur="reply(item)"
      />
    </template>
    <template v-else-if="item.type === QUESTION_TYPE_DATE">
      <!-- <EditDatetimeCell v-model:value="item.value" :type="item.config.type" :placeholder="item?.config?.desc" @confirm="reply(item)" /> -->
      <el-date-picker
        v-model="item.value"
        :disabled="!!item.disabled"
        :type="dateType(item.config.type || QUESTION_TYPE_DATE)"
        :value-format="dateTypeFormat(item.config.type)"
        :editable="false"
        :placeholder="item?.config?.desc"
        :validate-event="false"
        :append-to-body="false"
        @change="reply(item)"
      />
    </template>
    <template v-else-if="item.type === QUESTION_TYPE_RADIO">
      <div class="p-4">
        <el-radio-group
          v-model="item.value"
          :disabled="!!item.disabled"
          direction="horizontal"
          @change="reply(item)"
        >
          <el-radio
            v-for="(child, idx) in item.choices"
            :key="idx"
            :label="idx"
            >{{ child.label }}</el-radio
          >
        </el-radio-group>
      </div>
      <template v-if="item.value || item.value === 0">
        <el-input
          v-for="(inputChild, inputIdx) in item.choices?.filter((v: any, k: number) => v.isInput && item.value === k)"
          v-model="inputChild.extra"
          :key="inputIdx"
          :label="inputChild.label"
          :placeholder="inputChild.inputPlaceholder || '请输入'"
          class="mb-2"
          :disabled="!!item.disabled"
          @blur="reply(item)"
        >
          <template #prepend>{{ inputChild.label }}</template>
        </el-input>
      </template>
    </template>
    <template v-else-if="item.type === QUESTION_TYPE_CHECKBOX">
      <div class="p-4" :border="false">
        <div class="checkbox-list">
          <el-button
            v-for="(child, idx) in item.choices"
            :key="idx"
            round
            class="checkbox-item mb-2"
            :type="item?.value?.includes(idx) ? 'primary' : 'default'"
            @click="changeCheckboxItem(item, idx)"
            >{{ child.label }}</el-button
          >
        </div>
      </div>
      <template v-if="item.value && Array.isArray(item.value)">
        <el-input
          v-for="(inputChild, inputIdx) in item.choices?.filter((v: any, k: number) => v.isInput && item.value.includes(k))"
          :key="inputIdx"
          v-model="inputChild.extra"
          :label="inputChild.label"
          :placeholder="inputChild.inputPlaceholder || '请输入'"
          class="mb-2"
          :disabled="!!item.disabled"
          @blur="reply(item)"
        >
          <template #prepend>{{ inputChild.label }}</template>
        </el-input>
      </template>
    </template>
    <template v-else-if="item.type === QUESTION_TYPE_MATRIX">
      <div class="p-4" :border="false">
        <div class="survey-matrix-container">
          <table class="survey-matrix">
            <tr>
              <th />
              <th v-for="(subTh, subThIdx) in item.columns" :key="subThIdx">
                {{ subTh.label }}
              </th>
            </tr>
            <tr v-for="(row, rowIdx) in item.rows" :key="rowIdx">
              <td>{{ row.label }}</td>
              <td
                v-for="(col, colIdx) in item.columns"
                :key="colIdx"
                @click="checkMatrix(item, rowIdx, colIdx)"
              >
                <div
                  v-if="item.matrix[rowIdx][colIdx]"
                  class="flex items-center justify-center"
                >
                  <CircleCheckFilled class="text-lg text-blue-700" />
                </div>
                <div v-else class="h-4" />
              </td>
            </tr>
          </table>
        </div>
      </div>
    </template>
    <!-- 组合题 -->
    <template v-else-if="item.type === QUESTION_TYPE_GROUP">
      <!-- 常规显示 -->
      <div class="text-left">
        <template v-if="props.child">
          <transition name="slide">
            <div>
              <!-- <p class="survey-desc">{{ item.config.desc }}</p> -->
              <div v-for="(sub, subIdx) in item.children" :key="subIdx">
                <QuestionItem
                  v-model:info="item.children[subIdx]"
                  :child="true"
                  class="w-100"
                  @skip="skip"
                  @back="back"
                  @check-matrix="checkMatrix"
                  @reply="reply"
                />
              </div>
            </div>
          </transition>
        </template>
      </div>
    </template>
    <template v-else-if="item.type === QUESTION_TYPE_MEDICINE">
      <!-- 常规显示 -->
      <div class="text-left">
        <template v-if="props.child">
          <transition name="slide">
            <div ref="selectRef">
              <el-select
                v-if="!item.config.showInput"
                v-model="item.value"
                filterable
                placeholder="请选择或输入搜索"
                @hook:mounted="cancelReadOnly"
                @visible-change="cancelReadOnly"
              >
                <el-option
                  v-for="(searchItem, searchIdx) in item.searchList"
                  :key="searchIdx"
                  :label="searchItem.name"
                  :value="searchItem.name"
                />
              </el-select>
              <div v-if="item.config?.isInput">
                <el-button
                  v-if="!item.config.showInput"
                  class="mt-4"
                  type="primary"
                  link
                  @click="
                    item.value = '';
                    item.config.showInput = true;
                  "
                  >没有找到对应的药品？</el-button
                >
                <template v-else>
                  <el-input
                    v-model="item.value"
                    class="mt-4"
                    placeholder="请输入药品名称"
                    clearable
                  />
                  <el-button
                    class="mt-4"
                    type="primary"
                    link
                    @click="
                      item.value = '';
                      item.config.showInput = false;
                    "
                    >重新选择</el-button
                  >
                </template>
              </div>
            </div>
          </transition>
        </template>
      </div>
    </template>
    <template v-else-if="item.type === QUESTION_TYPE_DISEASE">
      <!-- 常规显示 -->
      <div class="text-left">
        <template v-if="props.child">
          <transition name="slide">
            <div ref="selectRef">
              <el-select
                v-if="!item.config.showInput"
                v-model="item.value"
                placeholder="请选择或输入搜索"
                filterable
                @hook:mounted="cancelReadOnly"
                @visible-change="cancelReadOnly"
              >
                <el-option
                  v-for="(searchItem, searchIdx) in item.searchList"
                  :key="searchIdx"
                  :label="searchItem.name"
                  :value="searchItem.name"
                />
              </el-select>
              <div v-if="item.config?.isInput">
                <el-button
                  v-if="!item.config.showInput"
                  class="mt-4"
                  type="primary"
                  link
                  @click="
                    item.value = '';
                    item.config.showInput = true;
                  "
                  >没有找到对应的疾病？</el-button
                >
                <template v-else>
                  <el-input
                    v-model="item.value"
                    class="mt-4"
                    placeholder="请输入疾病名称"
                    clearable
                  />
                  <el-button
                    class="mt-4"
                    type="primary"
                    link
                    @click="
                      item.value = '';
                      item.config.showInput = false;
                    "
                    >重新选择</el-button
                  >
                </template>
              </div>
            </div>
          </transition>
        </template>
      </div>
    </template>
    <template v-else-if="item.type === QUESTION_TYPE_UPLOAD">
      <UploadImage
        v-model:url="item.value"
        :type="item.config.fileType"
        :size-limit="item.config.fileSizeLimit || 0"
      />
    </template>

    <!-- 下拉题 -->
    <template v-else-if="item.type === QUESTION_TYPE_SELECT">
      <!-- 常规显示 -->
      <div
        class="flex text-left items-center hover:bg-gray-50 border-0 border-b border-gray-200 border-solid cursor-pointer"
      >
        <template v-if="props.child">
          <div class="flex-1 p-4" @click="openSelect">
            <div is-link>
              <span class="text-gray-600">{{
                item.value && item.value?.length
                  ? item.value?.map(v => v.value).join()
                  : "请选择"
              }}</span>
            </div>
          </div>
          <arrow-right class="h-4" />
        </template>
      </div>
      <el-dialog v-model="selectVisible" :title="item.title">
        <div v-if="selectChecked.length" class="p-4">
          <p>已选择：</p>
          <div
            v-for="(checkItem, checkIdx) in selectChecked"
            :key="checkIdx"
            class="inline-flex items-center bg-gray-100 rounded-full text-gray-600 text-sm p-1 px-3 m-1"
          >
            <span>{{ checkItem.properties.name }}</span>

            <close
              class="ml-2 cursor-pointer w-4"
              @click="selectChecked.splice(checkIdx, 1)"
            />
          </div>
        </div>
        <div class="flex p-4">
          <el-input
            type="primary"
            link
            v-model="selectKeyword"
            class="mr-4"
            clearable
            placeholder="请输入后搜索"
            @input="throttleSearch"
            @keyup.enter="searchSelectOptions"
          />
          <el-button type="primary" @click="searchSelectOptions"
            >搜索</el-button
          >
        </div>
        <div v-if="item.config.isAppendNull" class="px-4 text-sm text-gray-500">
          未搜索到？可填入后直接保存
        </div>
        <div class="max-h-[50vh] overflow-y-auto grid grid-cols-2">
          <div
            v-for="(selectItem, selectIndex) in selectOptions"
            :key="selectIndex"
            class="cursor-pointer border-b border-solid border-gray-100 py-2 px-4 flex"
            :class="{
              'font-bold text-blue-700 bg-blue-50 rounded': selectChecked.find(
                v => v.id == selectItem.id
              )
            }"
            @click="selectItemChange(selectItem)"
          >
            <span>{{ selectItem.properties?.name }}</span>
            <Check
              v-if="selectChecked.find(v => v.id == selectItem.id)"
              class="w-4"
            />
          </div>
          <el-empty v-if="!selectOptions.length" description="暂无数据" />
        </div>
        <template #footer>
          <el-button class="flex-1" @click="selectVisible = false"
            >取消</el-button
          >
          <el-button type="primary" class="flex-1" @click="saveSelect"
            >保存</el-button
          >
        </template>
      </el-dialog>
    </template>
    <slot />
  </div>
</template>

<script setup lang="ts">
import {
  defineProps,
  defineEmits,
  PropType,
  computed,
  ref,
  onMounted,
  nextTick
} from "vue";
import { formatAge, request, throttle } from "@/utils";
import QuestionItem from "./QuestionItem.vue";

import {
  CircleCheckFilled,
  Check,
  Close,
  ArrowRight
} from "@element-plus/icons-vue";
import {
  QUESTION_TYPE_TEMP_CHECK,
  QUESTION_TYPE_ANSWER,
  QUESTION_TYPE_INPUT,
  QUESTION_TYPE_TEXT,
  QUESTION_TYPE_CHECKBOX,
  QUESTION_TYPE_RADIO,
  QUESTION_TYPE_RATING_SCALE,
  QUESTION_TYPE_RATING,
  QUESTION_TYPE_DATE,
  QUESTION_TYPE_MATRIX,
  QUESTION_TYPE_COMBINATION,
  QUESTION_TYPE_DISEASE,
  QUESTION_TYPE_MEDICINE,
  QUESTION_TYPE_GROUP,
  QUESTION_TYPE_UPLOAD,
  QUESTION_TYPE_SELECT
} from "@/enums/question";
import UploadImage from "@/components/UploadImage.vue";
import { ElMessage, DatePickType } from "element-plus";

const emits = defineEmits([
  "update:info",
  "skip",
  "back",
  "check",
  "reply",
  "repeat",
  "checkMatrix"
]);
const props = defineProps({
  info: {
    type: Object,
    default: () => {}
  },
  hideList: {
    type: Array as PropType<Array<string>>,
    default: () => []
  },
  repeatAnswer: {
    type: Boolean,
    default: false
  },
  child: {
    type: Boolean,
    default: false
  }
});
// console.log(props.info);

const item = computed({
  get() {
    return props.info;
  },
  set(value) {
    emits("update:info", value);
  }
});

const dateTypeFormat = (type: string) => {
  switch (type) {
    case "year":
      return "YYYY";
    case QUESTION_TYPE_DATE:
      return "YYYY-MM-DD";
    default:
      return "YYYY-MM-DD HH:mm:ss";
  }
};
const dateTypes = [
  "year",
  "month",
  "date",
  "dates",
  "week",
  "datetime",
  "datetimerange",
  "daterange",
  "monthrange"
];
const dateType = (type: DatePickType): DatePickType => {
  if (!dateTypes.includes(type)) {
    return "date";
  }
  return type;
};
const fieldTypeFormat = (rule: string) => {
  switch (rule) {
    case "number":
      return "number";
    case "mobile":
      return "tel";
    default:
      return "text";
  }
};

const init = () => {
  // console.log(props.info);
  switch (item.value.type) {
    case QUESTION_TYPE_INPUT:
      if (item.value.selectValues?.length) {
        item.value.value = item.value.selectValues[0].value;
      }
      break;
    case QUESTION_TYPE_DISEASE:
    case QUESTION_TYPE_MEDICINE:
      fetchSearchList(item.value.type);
      break;

    case QUESTION_TYPE_SELECT:
      if (item.value.value) {
        selectChecked.value = item.value.value.map(v => {
          return {
            id: v.key,
            properties: {
              name: v.value
            }
          };
        });
      }
      break;
  }
};

const replyLock = ref(false);

const inputType = (rule: string): string => {
  switch (rule) {
    case "number":
      return rule;
    case "phone":
      return "tel";
    default:
      return "text";
  }
};

const changeCheckboxItem = (item: any, idx: number, other?: boolean) => {
  if (!Array.isArray(item.value)) {
    item.value = [idx];
    console.log(item.value);
  } else {
    if (item.choices![idx].mutuallyExclusive) {
      if (!item.value.includes(idx)) {
        item.value = [idx];
      } else {
        item.value = [];
      }
    } else {
      item.value = item.value?.filter(
        (v: number) => !item.choices![v]?.mutuallyExclusive
      );
      if (item.value.includes(idx)) {
        item.value.splice(item.value.indexOf(idx), 1);
      } else {
        item.value = [...new Set([...item.value, idx])];
      }
    }
  }
  reply(item);
};
// 矩阵题选择
const checkMatrix = (item: any, rowIdx: number, colIdx: number) => {
  emits("checkMatrix", item, rowIdx, colIdx);
};

const inputBlur = () => {
  // home.value.scrollTop = home.value.scrollHeight
  window.scrollTo(0, document.querySelector(".home")?.scrollHeight || 0);
};
const skip = (item: any) => {
  item.value = null;
  emits("skip", item);
};
const back = (item: any) => {
  emits("back", item);
};
const check = (item: any, flag: boolean) => {
  emits("check", item, flag);
};

const checkReply = (item: any) => {
  if (item.type === QUESTION_TYPE_MATRIX) {
    return true;
  } else if (item["choices"]?.length) {
    if (
      (!item.value && item.value !== 0) ||
      (Array.isArray(item.value) && !item.value.length)
    ) {
      ElMessage.error("请选择");
      replyLock.value = false;
      return false;
    }
  } else {
    if (!item.value && item.value !== 0) {
      ElMessage.error(
        `请${item.type === QUESTION_TYPE_DATE ? "选择" : "填写内容"}后提交`
      );
      replyLock.value = false;
      return false;
    }
  }
  return true;
};

const fetchSearchList = async (urlType = "disease") => {
  const urls = {
    disease: `/archivesServiceV2/api/extra/disease/list`,
    medicine: `/archivesServiceV2/api/extra/medicine/list`
  };
  const { data } = (await request.get(urls[urlType])) as any;
  const ids = item.value.cacheSearchList.map(v => v.id);
  let list = [
    ...item.value.cacheSearchList,
    ...data.list.filter(v => !ids.includes(v.id))
  ];
  console.log("fetchSearchList", list);

  list = item.value.systemTagIds?.length
    ? list.filter(
        v =>
          !v.systemTags.length ||
          !!v.systemTags?.find(tag => item.value.systemTagIds.includes(tag.id))
      )
    : list;
  console.log("fetchSearchList system", list);
  if (item.value.value && !list?.find(v => v.name == item.value.value)) {
    list = [
      {
        sn: "extra",
        name: item.value.value
      },
      ...list
    ];
  }
  item.value.searchList = list;
};

const reply = (item: any) => {
  emits("reply", item);
};
const repeat = (item: any) => {
  item.showAdd = false;
  emits("repeat", item);
};
const selectRef = ref();
const cancelReadOnly = function (value: boolean) {
  console.log("cancelReadOnly");

  nextTick(() => {
    !value && clearSelectReadOnly();
  });
};
const clearSelectReadOnly = () => {
  const input = selectRef.value?.querySelector(".el-input__inner");
  input?.removeAttribute("readonly");
};
onMounted(() => {
  init();
  nextTick(() => {
    selectRef.value && clearSelectReadOnly();
  });
});

const selectVisible = ref(false);
const selectKeyword = ref();
const selectOptions = ref([]);
const selectChecked = ref([]);
const selectItemChange = selectItem => {
  if (selectChecked.value.find(v => v.id == selectItem.id)) {
    selectChecked.value.splice(
      selectChecked.value.findIndex(v => v == selectItem.id),
      1
    );
  } else {
    if (item.value.config.isMultiple) {
      selectChecked.value.push(selectItem);
    } else {
      selectChecked.value = [selectItem];
    }
  }
};
const searchSelectOptions = async () => {
  const { data } = (await request.get(`/graphService/open/node/paginate`, {
    params: {
      page: 1,
      pageSize: 999,
      tag: item.value.config.sourceTag,
      name: selectKeyword.value
    }
  })) as any;
  selectOptions.value = data.list.sort(
    (a, b) => a.properties?.name?.length - b.properties?.name?.length
  );
  //   .map(v => {
  //   v.matchRate = selectKeyword.value.length / v.properties?.name?.length
  //   return v
  // })
};

const throttleSearch = throttle(searchSelectOptions, 300);
const saveSelect = () => {
  if (
    !selectChecked.value.length &&
    selectKeyword.value &&
    item.value.config.isAppendNull
  ) {
    selectChecked.value.push({
      id: "",
      properties: {
        name: selectKeyword.value
      }
    });
  }
  item.value.value = selectChecked.value.map(v => {
    return {
      key: v.id,
      value: v.properties?.name
    };
  });
  reply(item.value);
  selectVisible.value = false;
  selectOptions.value = [];
  selectKeyword.value = "";
};
const openSelect = () => {
  if (item.value.value) {
    selectChecked.value = item.value.value.map(v => {
      return {
        id: v.key,
        properties: {
          name: v.value
        }
      };
    });
  }
  selectVisible.value = true;
};
</script>

<style lang="scss">
.survey-matrix-container {
  overflow-x: auto;
  padding: 10px 0;
  .survey-matrix {
    font-size: 12px;
    border-collapse: collapse;
    margin: 0 auto;
    min-width: 100%;
    th,
    td {
      border: 1px solid #ccc;
      padding: 8px 10px;
      text-align: center;
    }
    th {
      white-space: nowrap;
    }
    tr {
      td:first-of-type {
        font-weight: bold;
        white-space: nowrap;
      }
    }
  }
}
.confirm-input-btn {
  &:not(:last-of-type) {
    margin-right: 10px;
  }
}
</style>
