<script setup>
import {
  computed,
  nextTick,
  onMounted,
  ref,
  reactive,
  defineExpose,
  watch,
} from "vue";
import { useDataDictStore } from "@/store/modules/dataDict";
import {
  selectedDeptsEmployee,
  getRuiHenProjectInfoPage,
  getDevicesByDepts,
  getRuiHenTaskDetail1,
} from "@/api/ruihen";
import { specifiedSimpleDepts } from "@/api";
import { getDeptId } from "@/utils/auth";
import DaTree from "@/components/da-tree/index.vue";

const props = defineProps({
  type: {
    type: String,
    default: "create",
  },
  id: {
    type: Number,
    default: null,
  },
});

const dictStore = useDataDictStore();

const isReadonly = computed(() => props.type === "detail");

const createInitialForm = () => ({
  id: "",
  projectId: undefined,
  wellName: "",
  location: "",
  technique: undefined,
  workloadDesign: undefined,
  workloadUnit: undefined,
  deptIds: [],
  deviceIds: [],
  responsiblePerson: undefined,
  remark: "",
});

const formRef = ref(null);
const form = ref(createInitialForm());

const rules = reactive({
  projectId: {
    rules: [{ required: true, errorMessage: "请选择合同" }],
  },
  wellName: {
    rules: [{ required: true, errorMessage: "请输入井号" }],
  },
  location: {
    rules: [{ required: true, errorMessage: "请输入施工地点" }],
  },
  technique: {
    rules: [{ required: true, errorMessage: "请选择施工工艺" }],
  },
  workloadDesign: {
    rules: [{ required: true, errorMessage: "请输入设计工作量" }],
  },
  workloadUnit: {
    rules: [{ required: true, errorMessage: "请选择工作量单位" }],
  },
  deptIds: {
    rules: [{ required: true, errorMessage: "请选择施工队伍" }],
  },
  deviceIds: {
    rules: [{ required: true, errorMessage: "请选择施工设备" }],
  },
  responsiblePerson: {
    rules: [{ required: true, errorMessage: "请选择责任人" }],
  },
});

const validate = async () => {
  return await formRef.value?.validate();
};

const buildSubmitData = () => {
  return {
    ...(form.value.id ? { id: form.value.id } : {}),
    projectId: form.value.projectId,
    wellName: form.value.wellName,
    location: form.value.location,
    technique: form.value.technique,
    workloadDesign: form.value.workloadDesign,
    workloadUnit: form.value.workloadUnit,
    deptIds: form.value.deptIds,
    deviceIds: form.value.deviceIds,
    responsiblePerson: [form.value.responsiblePerson],
    remark: form.value.remark,
    platformWell: "0",
  };
};

const defaultProps = computed(() => (label) => ({
  inputBorder: false,
  clearable: false,
  placeholder: isReadonly.value ? " " : `请输入${label}`,
  style: {
    "text-align": "right",
  },
  styles: {
    disableColor: "#fff",
  },
}));

const contractPopup = ref(null);
const contractPaging = ref(null);
const contractList = ref([]);
const contractSearchValue = ref("");
const contractTempProjectId = ref("");
const selectedContractLabel = ref("");

const contractSearchInputStyles = reactive({
  backgroundColor: "#f5f5f5",
  color: "#333",
});

const contractDisplayText = computed(() => {
  if (!form.value.projectId) return "";

  const currentContract = contractList.value.find(
    (item) => String(item.id) === String(form.value.projectId)
  );

  return selectedContractLabel.value || currentContract?.contractName || "";
});

const syncSelectedContractLabel = (list = []) => {
  if (!form.value.projectId) return;

  const currentContract = list.find(
    (item) => String(item.id) === String(form.value.projectId)
  );

  if (currentContract?.contractName) {
    selectedContractLabel.value = currentContract.contractName;
  }
};

const queryContractList = async (pageNo, pageSize) => {
  try {
    const res = await getRuiHenProjectInfoPage({
      deptId: getDeptId(),
      pageNo,
      pageSize,
      ...(contractSearchValue.value
        ? { contractName: contractSearchValue.value }
        : {}),
    });

    const list = res?.data?.list || [];
    const total = res?.data?.total || 0;

    syncSelectedContractLabel(list);
    contractPaging.value?.completeByTotal(list, total);
  } catch (error) {
    contractPaging.value?.complete(false);
  }
};

const searchContractList = () => {
  contractPaging.value?.reload();
};

const openContractPopup = () => {
  contractSearchValue.value = "";
  contractTempProjectId.value = form.value.projectId
    ? String(form.value.projectId)
    : "";
  contractPopup.value?.open();

  nextTick(() => {
    contractPaging.value?.reload();
  });
};

const closeContractPopup = () => {
  contractPopup.value?.close();
};

const handleContractRadioChange = (event) => {
  contractTempProjectId.value = event.detail.value;
};

const handleContractRowClick = (item) => {
  contractTempProjectId.value = String(item.id);
};

const handleContractConfirm = () => {
  if (!contractTempProjectId.value) {
    uni.showToast({
      title: "请选择合同",
      icon: "none",
    });
    return;
  }

  const currentContract = contractList.value.find(
    (item) => String(item.id) === contractTempProjectId.value
  );
  const fallbackProjectId = Number(contractTempProjectId.value);

  form.value.projectId =
    currentContract?.id ??
    (Number.isNaN(fallbackProjectId)
      ? contractTempProjectId.value
      : fallbackProjectId);
  selectedContractLabel.value =
    currentContract?.contractName || selectedContractLabel.value;

  closeContractPopup();
};

const techniqueOptions = ref([]);
const workloadUnitOptions = ref([]);

const loadDictOptions = async () => {
  if (dictStore.dataDict.length <= 0) {
    await dictStore.loadDataDictList();
  }

  techniqueOptions.value = dictStore
    .getIntDictOptions("rq_iot_project_technology_rh")
    .map((item) => ({
      text: item.label,
      value: item.value,
    }));

  workloadUnitOptions.value = dictStore
    .getIntDictOptions("rq_iot_project_measure_unit")
    .map((item) => ({
      text: item.label,
      value: item.value,
    }));
};

const deptOptions = ref([]);
const treeData = ref([]);
const deptLoading = ref(false);

const handleTree = (data, id, parentId, children) => {
  if (!Array.isArray(data)) {
    console.warn("data must be an array");
    return [];
  }
  const config = {
    id: id || "id",
    parentId: parentId || "parentId",
    childrenList: children || "children",
  };

  const childrenListMap = {};
  const nodeIds = {};
  const tree = [];

  for (const d of data) {
    const parentId = d[config.parentId];
    if (childrenListMap[parentId] == null) {
      childrenListMap[parentId] = [];
    }
    nodeIds[d[config.id]] = d;
    childrenListMap[parentId].push(d);
  }

  for (const d of data) {
    const parentId = d[config.parentId];
    if (nodeIds[parentId] == null) {
      tree.push(d);
    }
  }

  for (const t of tree) {
    adaptToChildrenList(t);
  }

  function adaptToChildrenList(o) {
    if (childrenListMap[o[config.id]] !== null) {
      o[config.childrenList] = childrenListMap[o[config.id]];
    }
    if (o[config.childrenList]) {
      for (const c of o[config.childrenList]) {
        adaptToChildrenList(c);
      }
    }
  }

  return tree;
};

async function loadDeptOptions() {
  deptLoading.value = true;
  try {
    function sortTreeBySort(treeNodes) {
      if (!treeNodes || !Array.isArray(treeNodes)) return treeNodes;
      const sortedNodes = [...treeNodes].sort((a, b) => {
        const sortA = a.sort != null ? a.sort : 999999;
        const sortB = b.sort != null ? b.sort : 999999;
        return sortA - sortB;
      });

      sortedNodes.forEach((node) => {
        node.disabled = node.type !== "3";
        if (node.children && Array.isArray(node.children)) {
          node.children = sortTreeBySort(node.children);
        }
      });
      return sortedNodes;
    }

    const depts = await specifiedSimpleDepts(getDeptId());

    deptOptions.value = depts.data.map((item) => ({
      text: item.name,
      value: item.id,
      raw: item,
    }));
    treeData.value = sortTreeBySort(handleTree(depts.data));
  } catch (error) {
  } finally {
    deptLoading.value = false;
  }
}

const popup = ref();

const openPopup = () => {
  popup.value.open();
};

const selectDeptId = ref("");

function handleTreeChange(values) {
  selectDeptId.value = values;
}

function handleConfirm() {
  form.value.deptIds = [selectDeptId.value];
  popup.value.close();
  loadDeviceOptions();
  loadUserOptions();
}

const deviceOptions = ref([]);
const deviceLoading = ref(false);

const loadDeviceOptions = async (init = false) => {
  deviceOptions.value = [];
  if (!init) form.value.deviceIds = [];

  if (!form.value.deptIds || form.value.deptIds.length === 0) {
    return;
  }

  deviceLoading.value = true;
  try {
    const res = await getDevicesByDepts({ deptIds: form.value.deptIds });
    deviceOptions.value = res.data.map((item) => ({
      text: `${item.deviceCode} ${item.deviceName}`,
      value: item.id,
      raw: item,
    }));

    if (!init) {
      form.value.deviceIds = deviceOptions.value.map((item) => item.value);
    }
  } finally {
    deviceLoading.value = false;
  }
};

const userOptions = ref([]);
const userLoading = ref(false);

const loadUserOptions = async (init = false) => {
  userOptions.value = [];
  if (!init) form.value.responsiblePerson = undefined;

  if (!form.value.deptIds || form.value.deptIds.length === 0) {
    return;
  }

  userLoading.value = true;
  try {
    const res = await selectedDeptsEmployee({
      deptIds: form.value.deptIds,
    });
    userOptions.value = res.data.map((item) => ({
      text: item.nickname,
      value: item.id,
      raw: item,
    }));
  } finally {
    userLoading.value = false;
  }
};

const loadDetail = async (id) => {
  if (!id) return;

  const res = await getRuiHenTaskDetail1({ id });

  const data = res.data.list[0] || createInitialForm();

  Object.assign(form.value, {
    id: data.id,
    projectId: data.projectId,
    wellName: data.wellName,
    location: data.location,
    technique: Number(data.technique),
    workloadDesign: data.workloadDesign,
    workloadUnit: Number(data.workloadUnit),
    deptIds: data.deptIds || [],
    deviceIds: data.deviceIds || [],
    responsiblePerson: data.responsiblePerson
      ? data.responsiblePerson[0]
      : undefined,
    remark: data.remark,
  });

  selectedContractLabel.value = data.contractName || "";

  loadDeviceOptions(true);
  loadUserOptions(true);
};

watch(
  () => props.id,
  async (newId) => {
    if (props.type !== "create" && newId) {
      await loadDetail(newId);
    }
  },
  { immediate: true }
);

watch(
  () => form.value.projectId,
  (value) => {
    if (!value) {
      selectedContractLabel.value = "";
      contractTempProjectId.value = "";
    }
  }
);

onMounted(async () => {
  await Promise.all([loadDictOptions(), loadDeptOptions()]);
});

defineExpose({
  form,
  formRef,
  validate,
  buildSubmitData,
});
</script>

<template>
  <view class="content">
    <uni-forms
      ref="formRef"
      labelWidth="auto"
      :model="form"
      :rules="rules"
      validateTrigger="submit"
      err-show-type="toast">
      <uni-forms-item label="合同" name="projectId" required>
        <view class="select-with-button">
          <view
            class="popup-select-value"
            :class="{ 'popup-select-placeholder': !contractDisplayText }"
            @click="!isReadonly && openContractPopup()">
            {{ contractDisplayText || "请选择合同" }}
          </view>
          <button
            v-if="!isReadonly"
            class="popup-button"
            type="primary"
            size="mini"
            @click="openContractPopup">
            选择
          </button>
        </view>
      </uni-forms-item>
      <uni-forms-item label="井号" name="wellName" required>
        <uni-easyinput
          v-bind="defaultProps('井号')"
          v-model="form.wellName"
          :disabled="isReadonly" />
      </uni-forms-item>
      <uni-forms-item label="施工地点" name="location" required>
        <uni-easyinput
          v-bind="defaultProps('施工地点')"
          v-model="form.location"
          :disabled="isReadonly" />
      </uni-forms-item>
      <uni-forms-item label="施工工艺" name="technique" required>
        <uni-data-select
          :clear="true"
          align="right"
          placeholder="请选择施工工艺"
          :localdata="techniqueOptions"
          placement="bottom"
          hideRight
          :disabled="isReadonly"
          v-model="form.technique" />
      </uni-forms-item>
      <uni-forms-item label="设计工作量" name="workloadDesign" required>
        <uni-easyinput
          type="number"
          v-bind="defaultProps('设计工作量')"
          v-model.number="form.workloadDesign"
          :disabled="isReadonly" />
      </uni-forms-item>
      <uni-forms-item label="工作量单位" name="workloadUnit" required>
        <uni-data-select
          :clear="true"
          align="right"
          placeholder="请选择工作量单位"
          :localdata="workloadUnitOptions"
          placement="bottom"
          hideRight
          :disabled="isReadonly"
          v-model="form.workloadUnit" />
      </uni-forms-item>
      <uni-forms-item label="施工队伍" name="deptIds" required>
        <view class="select-with-button">
          <uni-data-select
            :clear="true"
            align="right"
            placeholder="请选择施工队伍"
            :localdata="deptOptions"
            placement="bottom"
            hideRight
            :disabled="true"
            multiple
            v-model="form.deptIds" />
          <button
            v-if="!isReadonly"
            class="popup-button"
            type="primary"
            size="mini"
            :disabled="deptLoading"
            @click="openPopup">
            选择
          </button>
        </view>
      </uni-forms-item>
      <uni-forms-item label="施工设备" name="deviceIds" required>
        <uni-data-select
          :clear="true"
          align="right"
          placeholder="请选择施工设备"
          :localdata="deviceOptions"
          placement="top"
          hideRight
          multiple
          :disabled="isReadonly || deviceLoading"
          v-model="form.deviceIds">
          <template #selected="{ selectedItems }">
            <view class="device-selected-box">
              <view v-if="selectedItems.length" class="device-selected-list">
                <view
                  v-for="item in selectedItems"
                  :key="item.value"
                  class="device-selected-item">
                  {{ item.text }}
                </view>
              </view>
              <view v-else class="device-selected-placeholder">
                请选择施工设备
              </view>
            </view>
          </template>
        </uni-data-select>
      </uni-forms-item>
      <uni-forms-item label="责任人" name="responsiblePerson" required>
        <uni-data-select
          :clear="true"
          align="right"
          placeholder="请选择责任人"
          :localdata="userOptions"
          placement="bottom"
          hideRight
          :disabled="isReadonly || userLoading"
          v-model="form.responsiblePerson" />
      </uni-forms-item>
      <uni-forms-item label="备注" name="remark">
        <uni-easyinput
          type="textarea"
          autoHeight
          v-bind="defaultProps('备注')"
          v-model="form.remark"
          :disabled="isReadonly"
          :maxlength="1000" />
      </uni-forms-item>
    </uni-forms>
  </view>

  <uni-popup
    ref="contractPopup"
    type="bottom"
    :is-mask-click="false"
    border-radius="10px 10px 0 0">
    <z-paging
      ref="contractPaging"
      v-model="contractList"
      class="contract-popup-paging"
      style="top: 140px"
      :default-page-size="20"
      @query="queryContractList">
      <template #top>
        <view class="contract-popup-top">
          <view class="contract-popup-header">
            <text class="contract-popup-action" @click="closeContractPopup">
              取消
            </text>
            <text class="contract-popup-title">选择合同</text>
            <text
              class="contract-popup-action primary"
              @click="handleContractConfirm">
              确定
            </text>
          </view>
          <view class="contract-search-row">
            <uni-easyinput
              v-model="contractSearchValue"
              :inputBorder="false"
              :styles="contractSearchInputStyles"
              placeholder="请输入合同名称"
              @confirm="searchContractList" />
            <button
              class="mini-btn contract-search-button"
              type="primary"
              size="mini"
              @click="searchContractList">
              搜索
            </button>
          </view>
        </view>
      </template>

      <radio-group @change="handleContractRadioChange">
        <view class="contract-popup-list">
          <view
            v-for="item in contractList"
            :key="item.id"
            class="contract-popup-item"
            :class="{ active: String(item.id) === contractTempProjectId }"
            @click="handleContractRowClick(item)">
            <view class="contract-popup-item-main">
              <view class="contract-popup-item-name">
                {{ item.contractName || "--" }}
              </view>
              <!-- <view
                v-if="item.projectNo || item.contractCode"
                class="contract-popup-item-desc">
                {{ item.projectNo || item.contractCode }}
              </view> -->
            </view>
            <radio
              :value="String(item.id)"
              :checked="String(item.id) === contractTempProjectId"
              color="#2979ff" />
          </view>
        </view>
      </radio-group>
    </z-paging>
  </uni-popup>

  <uni-popup ref="popup" type="bottom">
    <view class="popup-content">
      <view class="tree">
        <DaTree
          :data="treeData"
          labelField="name"
          valueField="id"
          disabledField="disabled"
          defaultExpandAll
          checkedDisabled
          :defaultCheckedKeys="form.deptIds[0]"
          @change="handleTreeChange"></DaTree>
      </view>
      <button class="mini-btn" type="primary" @click="handleConfirm">
        确定
      </button>
    </view>
  </uni-popup>
</template>

<style lang="scss" scoped>
.content {
  background-color: #fff;
  padding: 16px;
  border-radius: 8px;
  box-sizing: border-box;
}

.uni-forms {
  margin-top: 10px;
}

:deep(.uni-forms-item) {
  display: flex;
  align-items: center;
  margin-bottom: 6px;
  border-bottom: 1px dashed #cacccf;
}

:deep(.uni-forms-item__content) {
  text-align: right;
}

:deep(.uni-forms-item__label) {
  height: 44px;
  font-weight: 500;
  font-size: 14px;
  color: #333 !important;
  width: max-content !important;
}

:deep(.uni-select) {
  border: none;
  text-align: right;
  padding-right: 10px;
}

:deep(.uniui-bottom:before) {
  content: "\e6b5" !important;
  font-size: 16px !important;
}

:deep(.uni-easyinput__content-textarea) {
  min-height: inherit;
  margin: 10px;
}

:deep(.uni-textarea-textarea:disabled),
:deep(.uni-input-input:disabled),
:deep(.is-disabled) {
  color: #333 !important;
}

:deep(.uni-select--disabled) {
  background-color: #fff;
}

.select-with-button {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 10px;
  width: 100%;
}

.readonly-input {
  flex: 1;
}

.popup-select-value {
  flex: 1;
  min-height: 32px;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  color: #333;
  font-size: 14px;
  line-height: 1.4;
  text-align: right;
  word-break: break-all;
}

.popup-select-placeholder {
  color: #999;
}

.contract-popup-paging {
  background-color: #fff;
  border-radius: 10px 10px 0 0;
}

.contract-popup-top {
  padding: 16px;
  padding-bottom: 10px;
  background-color: #fff;
}

.contract-popup-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  font-size: 15px;
}

.contract-popup-title {
  font-size: 16px;
  font-weight: 600;
  color: #333;
}

.contract-popup-action {
  color: #666;
}

.contract-popup-action.primary {
  color: #2979ff;
}

.contract-search-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.contract-search-button {
  width: 72px;
  margin: 0;
  flex-shrink: 0;
}

.contract-popup-list {
  padding: 0 16px 16px;
  background-color: #fff;
}

.contract-popup-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px solid #f0f0f0;
}

.contract-popup-item.active {
  color: #2979ff;
}

.contract-popup-item-main {
  flex: 1;
  min-width: 0;
}

.contract-popup-item-name {
  font-size: 14px;
  line-height: 1.5;
  color: inherit;
  word-break: break-all;
}

.contract-popup-item-desc {
  margin-top: 4px;
  font-size: 12px;
  color: #999;
}

.device-selected-box {
  width: 100%;
  min-height: 24px;
  display: flex;
  justify-content: flex-end;
  align-items: center;
}

.device-selected-list {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
}

.device-selected-item {
  max-width: 100%;
  padding: 4px 8px;
  border-radius: 4px;
  background: #f3f5f9;
  color: #333;
  font-size: 12px;
  line-height: 1.4;
  word-break: break-all;
}

.device-selected-placeholder {
  color: #999;
  font-size: 14px;
}

:deep(.popup-button) {
  width: 62px;
  margin: 0;
  flex-shrink: 0;
}

.popup-content {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 15px;
  height: 500px;
  background-color: #fff;
}

.tree {
  flex: 1;
  max-height: 420px;
}

.popup-content button {
  width: 100%;
  height: 44px;
}

:deep(.uni-select__selector-item) {
  padding: 0;
  width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  white-space: nowrap;
  -webkit-overflow-scrolling: touch;

  uni-text {
    padding: 0 10px;
  }
}

:deep(.uni-select__selector-item uni-text),
:deep(.uni-select__selector-item uni-text span) {
  display: inline-block;
  white-space: nowrap;
  min-width: max-content;
}
</style>
