<template>
  <div class="budget-source-field">
    <!-- 提交用隐藏字段 -->
    <input :name="fieldName" type="hidden" :value="normalizedValue" />

    <!-- 当前展示文本（有值时展示） -->
    <span v-if="hasValue && displayText" class="budget-source-label" :title="displayText">
      {{ displayText }}
    </span>
    <span
      v-else-if="hasValue"
      class="budget-source-label budget-source-label--muted"
      :title="normalizedValue"
    >
      ID: {{ normalizedValue }}
    </span>

    <el-button type="primary" size="small" @click="openDialog">选取</el-button>
    <el-button v-if="hasValue" size="small" @click="clearValue">清除</el-button>

    <el-dialog
      title="选择预算来源"
      :visible.sync="dialogVisible"
      width="720px"
      :close-on-click-modal="false"
      append-to-body
      @open="onDialogOpen"
      @close="onDialogClose"
    >
      <div style="margin-bottom: 12px">
        <el-select
          v-model="yearId"
          placeholder="请选择年份"
          filterable
          style="width: 100%"
          :loading="yearLoading"
          @change="onYearChange"
        >
          <el-option
            v-for="y in yearOptions"
            :key="String(y.value)"
            :label="y.label"
            :value="y.value"
          />
        </el-select>
      </div>

      <div v-loading="treeLoading" style="max-height: 420px; overflow: auto">
        <div v-if="departmentTree.length" class="tree-block">
          <div class="tree-title">部门预算</div>
          <el-tree
            :data="departmentTree"
            node-key="id"
            :props="treeProps"
            highlight-current
            default-expand-all
            :expand-on-click-node="false"
            :current-node-key="pendingId"
            @node-click="onNodeClick"
          />
        </div>

        <div v-if="projectTree.length" class="tree-block" style="margin-top: 16px">
          <div class="tree-title">自有账户</div>
          <el-tree
            :data="projectTree"
            node-key="id"
            :props="treeProps"
            highlight-current
            default-expand-all
            :expand-on-click-node="false"
            :current-node-key="pendingId"
            @node-click="onNodeClick"
          />
        </div>

        <div
          v-if="!treeLoading && departmentTree.length === 0 && projectTree.length === 0"
          style="text-align: center; color: #909399; padding: 32px 0"
        >
          暂无数据
        </div>
      </div>

      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" :disabled="!pendingId" @click="confirmPick">
          确定
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import request from "@/utils/request";
import { getBudgetYearOptions, getBudgetDataTree } from "@/api/flow";

export default {
  name: "BudgetSourcePickerField",
  props: {
    fieldName: { type: String, required: true },
    value: { type: [String, Number], default: "" },
    display: { type: String, default: "" },
  },
  data() {
    return {
      dialogVisible: false,
      yearLoading: false,
      treeLoading: false,
      yearOptions: [],
      yearId: null,
      treeData: [],
      pendingId: null,
    };
  },
  computed: {
    normalizedValue() {
      return this.value === null || this.value === undefined ? "" : String(this.value);
    },
    hasValue() {
      return this.normalizedValue !== "";
    },
    displayText() {
      // 可写且有值时：只展示后端返回的 `{字段名}_display`
      // 不再回退到原始 id，避免出现 “1年” 这种展示
      return this.hasValue ? (this.display || "") : "";
    },
    treeProps() {
      return {
        children: "children",
        label: "name",
        disabled: (data) => !data?.is_leaf,
      };
    },
    departmentTree() {
      return (this.treeData || []).filter((n) => n?.budget_type !== "project");
    },
    projectTree() {
      return (this.treeData || []).filter((n) => n?.budget_type === "project");
    },
  },
  methods: {
    openDialog() {
      this.dialogVisible = true;
    },
    onDialogOpen() {
      this.pendingId = null;
      this.ensureInit();
    },
    onDialogClose() {
      this.pendingId = null;
    },
    async ensureInit() {
      if (!this.yearOptions || this.yearOptions.length === 0) {
        await this.loadYearOptions();
      }

      if (!this.yearId && this.yearOptions.length > 0) {
        // 尝试根据当前 value 反查 year_id（可选），否则默认第一项
        const fromValue = await this.tryResolveYearIdByValue();
        this.yearId = fromValue || this.yearOptions[0].value;
      }

      if (this.yearId) {
        await this.loadTree(this.yearId);
      }
    },
    async loadYearOptions() {
      this.yearLoading = true;
      try {
        const res = await getBudgetYearOptions(false);
        const arr = Array.isArray(res) ? res : [];
        this.yearOptions = arr.map((y) => ({
          value: y.value,
          label: y.label || (y.year ? `${y.year}年` : `${y.value}年`),
          year: y.year,
        }));
      } finally {
        this.yearLoading = false;
      }
    },
    async tryResolveYearIdByValue() {
      if (!this.hasValue) return null;
      try {
        const detail = await request({
          method: "get",
          url: `/api/budget/budget-data/${this.normalizedValue}`,
          isLoading: false,
        });
        const yearId = detail?.year_id ?? null;
        return yearId;
      } catch (e) {
        return null;
      }
    },
    async loadTree(yearId) {
      if (!yearId) return;
      this.treeLoading = true;
      try {
        const res = await getBudgetDataTree({ year_id: yearId }, false);
        this.treeData = Array.isArray(res) ? res : [];
      } finally {
        this.treeLoading = false;
      }
    },
    async onYearChange(val) {
      this.pendingId = null;
      this.treeData = [];
      await this.loadTree(val);
    },
    onNodeClick(node) {
      if (!node || !node.is_leaf) return;
      this.pendingId = node.id;
    },
    findPathNames(tree, id, path = []) {
      if (!Array.isArray(tree)) return null;
      for (const n of tree) {
        const nextPath = [...path, n];
        if (String(n.id) === String(id)) return nextPath;
        if (n.children && n.children.length) {
          const found = this.findPathNames(n.children, id, nextPath);
          if (found) return found;
        }
      }
      return null;
    },
    getYearLabel() {
      const opt = (this.yearOptions || []).find(
        (y) => String(y.value) === String(this.yearId)
      );
      return opt?.label || (this.yearId ? `${this.yearId}年` : "");
    },
    confirmPick() {
      if (!this.pendingId) return;
      const nodes = this.findPathNames(this.treeData, this.pendingId) || [];
      const names = nodes.map((n) => n?.name).filter(Boolean);
      const leaf = nodes[nodes.length - 1];
      const typeText =
        leaf?.budget_type === "project"
          ? "自有账户"
          : leaf?.budget_type === "department"
            ? "部门预算"
            : leaf?.budget_type
              ? String(leaf.budget_type)
              : "";
      const yearLabel = this.getYearLabel();
      const display = [yearLabel, typeText, ...names].filter(Boolean).join(" / ");

      // 更新主值与展示值（展示值用于只读/回显）
      this.$emit("input", String(this.pendingId));
      this.$emit("update:display", display);

      this.dialogVisible = false;
      this.pendingId = null;
    },
    clearValue() {
      this.$emit("input", "");
      this.$emit("update:display", "");
    },
  },
};
</script>

<style scoped>
.budget-source-field {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.budget-source-label {
  color: #606266;
  font-size: 14px;
  flex: 1;
  min-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.budget-source-label--muted {
  color: #909399;
}

.tree-title {
  font-size: 14px;
  font-weight: 600;
  color: #606266;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid #e4e7ed;
}
</style>


