<template>
  <view class="page">
    <scroll-view scroll-y class="page-scroll">
      <common-hero title="团员档案管理" :use-image-bg="true"></common-hero>

      <view class="section-card">
        <view class="section-head">
          <view class="section-title">基础信息表单</view>
        </view>

        <view class="field-list">
          <view v-for="field in fields" :key="field.key" class="field-item">
            <view class="field-label">
              {{ field.label }}
              <text v-if="field.required" class="field-required">*</text>
            </view>

            <view
              v-if="field.key === 'gender'"
              class="field-picker"
              @tap="openGenderPicker(field)"
            >
              <text :class="getFieldDisplayValue(field) ? 'field-value' : 'field-placeholder'">
                {{ getFieldDisplayValue(field) || field.placeholder }}
              </text>
            </view>

            <picker
              v-else-if="field.key === 'nation'"
              mode="selector"
              :range="nationLabels"
              :value="nationIndex"
              :disabled="!nationOptions.length"
              @change="handleNationChange"
            >
              <view class="field-picker" :class="{ 'field-picker--disabled': !nationOptions.length }">
                <text :class="getFieldDisplayValue(field) ? 'field-value' : 'field-placeholder'">
                  {{ getFieldDisplayValue(field) || (nationOptions.length ? field.placeholder : '民族加载中') }}
                </text>
              </view>
            </picker>

            <view
              v-else-if="field.key === 'politics'"
              class="field-picker"
              @tap="openPoliticsPicker()"
            >
              <text :class="getFieldDisplayValue(field) ? 'field-value' : 'field-placeholder'">
                {{ getFieldDisplayValue(field) || field.placeholder }}
              </text>
            </view>

            <view
              v-else-if="field.key === 'leaguePosition'"
              class="field-picker"
              @tap="openLeaguePositionPicker(field)"
            >
              <text :class="getFieldDisplayValue(field) ? 'field-value' : 'field-placeholder'">
                {{ getFieldDisplayValue(field) || field.placeholder }}
              </text>
            </view>

            <view
              v-else-if="field.key === 'collegeId'"
              class="field-picker"
              @tap="openCollegePicker()"
            >
              <text :class="getFieldDisplayValue(field) ? 'field-value' : 'field-placeholder'">
                {{ getFieldDisplayValue(field) || field.placeholder }}
              </text>
            </view>

            <view
              v-else-if="field.key === 'classId'"
              class="field-picker"
              @tap="openClassPicker()"
            >
              <text :class="getFieldDisplayValue(field) ? 'field-value' : 'field-placeholder'">
                {{ getFieldDisplayValue(field) || field.placeholder }}
              </text>
            </view>

            <view
              v-else-if="field.key === 'branchOrganizationId'"
              class="field-picker"
              @tap="openOrganizationPicker()"
            >
              <text :class="getFieldDisplayValue(field) ? 'field-value' : 'field-placeholder'">
                {{ getFieldDisplayValue(field) || field.placeholder }}
              </text>
            </view>

            <view
              v-else-if="field.key === 'archiveInCurrentOrg'"
              class="field-picker"
              @tap="openArchiveInOrgPicker(field)"
            >
              <text :class="getFieldDisplayValue(field) ? 'field-value' : 'field-placeholder'">
                {{ getFieldDisplayValue(field) || field.placeholder }}
              </text>
            </view>

            <view
              v-else-if="field.key === 'joinMonth'"
              class="field-picker"
              @tap="openJoinMonthPicker(field)"
            >
              <text :class="getFieldDisplayValue(field) ? 'field-value' : 'field-placeholder'">
                {{ getFieldDisplayValue(field) || field.placeholder }}
              </text>
            </view>

            <picker
              v-else-if="field.type === 'select'"
              mode="selector"
              :range="field.options"
              :value="getSelectIndex(field)"
              @change="handleSelectChange(field, $event)"
            >
              <view class="field-picker">
                <text :class="getFieldDisplayValue(field) ? 'field-value' : 'field-placeholder'">
                  {{ getFieldDisplayValue(field) || field.placeholder }}
                </text>
              </view>
            </picker>

            <view v-else-if="field.type === 'readonly' || field.key === 'phone'"
                  class="field-picker field-picker--readonly">
              <text :class="getFieldDisplayValue(field) ? 'field-value' : 'field-placeholder'">
                {{ getFieldDisplayValue(field) || field.placeholder }}
              </text>
            </view>

            <uv-input
              v-else
              class="field-native-input"
              :type="field.type === 'phone' ? 'number' : 'text'"
              :value="formData[field.key]"
              :placeholder="field.placeholder"
              placeholder-style="color: #c0c4cc;"
              :maxlength="-1"
              border="none"
              @input="handleTextInput(field, $event)"
            />
          </view>
        </view>
      </view>

      <view class="action-card">
        <button class="ghost-btn" @click="saveDraft">保存草稿</button>
        <button class="primary-btn" @click="submitForm">提交档案</button>
      </view>
    </scroll-view>

    <view v-if="searchPickerVisible" class="option-mask" @tap="closeSearchPicker">
      <view class="option-popup" @tap.stop>
        <view class="option-popup-head">
          <view class="option-popup-btn" @tap="closeSearchPicker">取消</view>
          <view class="option-popup-title">{{ searchPickerTitle }}</view>
          <view class="option-popup-btn option-popup-btn--primary" @tap="confirmSearchPicker">确定</view>
        </view>

        <uv-input
          :value="searchPickerKeyword"
          class="option-search"
          :placeholder="`搜索${searchPickerTitle}`"
          border="none"
          @input="handleSearchPickerInput"
        />

        <view v-if="filteredSearchPickerOptions.length" class="option-picker-wrap">
          <picker-view class="option-picker-view" :value="[searchPickerIndex]" @change="handleSearchPickerChange">
            <picker-view-column>
              <view v-for="item in filteredSearchPickerOptions" :key="`${searchPickerMode}-${item.value}`"
                    class="option-picker-item">
                {{ item.label }}
              </view>
            </picker-view-column>
          </picker-view>
        </view>
        <view v-else class="option-empty">没有匹配的选项</view>
      </view>
    </view>

    <uv-picker
      ref="genderPicker"
      title="选择性别"
      :columns="genderPickerColumns"
      :defaultIndex="[genderPickerIndex]"
      keyName="text"
      @close="closeGenderPicker"
      @cancel="closeGenderPicker"
      @confirm="confirmGenderPicker"
    ></uv-picker>

    <uv-picker
      ref="leaguePositionPicker"
      title="选择团内职务"
      :columns="leaguePositionPickerColumns"
      :defaultIndex="[leaguePositionPickerIndex]"
      keyName="text"
      @close="closeLeaguePositionPicker"
      @cancel="closeLeaguePositionPicker"
      @confirm="confirmLeaguePositionPicker"
    ></uv-picker>

    <uv-picker
      ref="organizationPicker"
      title="选择所属团支部"
      :columns="organizationPickerColumns"
      :defaultIndex="organizationPickerIndexs"
      keyName="text"
      @change="handleOrganizationPickerChange"
      @close="closeOrganizationPicker"
      @cancel="closeOrganizationPicker"
      @confirm="confirmOrganizationPicker"
    ></uv-picker>

    <uv-picker
      ref="archiveInOrgPicker"
      title="选择团籍是否在本组织"
      :columns="archiveInOrgPickerColumns"
      :defaultIndex="[archiveInOrgPickerIndex]"
      keyName="text"
      @close="closeArchiveInOrgPicker"
      @cancel="closeArchiveInOrgPicker"
      @confirm="confirmArchiveInOrgPicker"
    ></uv-picker>

    <uv-picker
      ref="joinMonthPicker"
      title="选择入团年月"
      :columns="joinMonthPickerColumns"
      :defaultIndex="joinMonthPickerIndexs"
      keyName="text"
      @change="handleJoinMonthPickerChange"
      @close="closeJoinMonthPicker"
      @cancel="closeJoinMonthPicker"
      @confirm="confirmJoinMonthPicker"
    ></uv-picker>
  </view>
</template>

<script>
import CommonHero from '../../components/common-hero/common-hero.vue'
import {
  getCurrentTyglForm,
  getCurrentUser,
  getUserProfile,
  listClasses,
  listColleges,
  listDictData,
  listOrganizations,
  saveTyglForm,
  updateTyglForm
} from './service'

const STORAGE_KEY = 'tygl_member_archive_draft'
const POLITICS_DICT_ID = 172
const NATION_DICT_ID = 173
const LEAGUE_POSITION_DICT_ID = 174

const FALLBACK_NATION_OPTIONS = [
  '汉族', '蒙古族', '回族', '藏族', '维吾尔族', '苗族', '彝族', '壮族', '布依族', '朝鲜族',
  '满族', '侗族', '瑶族', '白族', '土家族', '哈尼族', '哈萨克族', '傣族', '黎族', '傈僳族',
  '佤族', '畲族', '高山族', '拉祜族', '水族', '东乡族', '纳西族', '景颇族', '柯尔克孜族', '土族',
  '达斡尔族', '仫佬族', '羌族', '布朗族', '撒拉族', '毛南族', '仡佬族', '锡伯族', '阿昌族', '普米族',
  '塔吉克族', '怒族', '乌孜别克族', '俄罗斯族', '鄂温克族', '德昂族', '保安族', '裕固族', '京族', '塔塔尔族',
  '独龙族', '鄂伦春族', '赫哲族', '门巴族', '珞巴族', '基诺族'
]
const FALLBACK_POLITICS_OPTIONS = ['中共党员', '中共预备党员', '共青团员', '群众', '民盟盟员', '民建会员', '其他']
const FALLBACK_LEAGUE_POSITION_OPTIONS = [
  '普通团员',
  '团支部书记',
  '团支部副书记',
  '组织委员',
  '宣传委员',
  '纪检委员',
  '学习委员',
  '文体委员',
  '班级团支书',
  '院级团学干部',
  '校级团学干部',
  '其他'
]

const fields = [
  {key: 'name', label: '姓名', required: true, type: 'text', placeholder: '请输入姓名'},
  {key: 'gender', label: '性别', type: 'select', placeholder: '请选择性别'},
  {key: 'nation', label: '民族', type: 'search-select', placeholder: '请选择民族'},
  {key: 'politics', label: '政治面貌', required: true, type: 'search-select', placeholder: '请选择政治面貌'},
  {
    key: 'collegeId',
    label: '学院',
    required: true,
    type: 'college',
    placeholder: '请选择学院',
    displayKey: 'collegeName'
  },
  {key: 'classId', label: '班级', required: true, type: 'class', placeholder: '请选择班级', displayKey: 'className'},
  {key: 'phone', label: '手机号码', type: 'readonly', placeholder: '自动读取当前用户手机号'},
  {key: 'leaguePosition', label: '团内职务', type: 'text', placeholder: '请选择团内职务'},
  {
    key: 'branchOrganizationId',
    label: '所属团支部',
    type: 'organization',
    placeholder: '请选择所属团支部',
    displayKey: 'branchOrganizationName'
  },
  {key: 'idCardNo', label: '身份证号', required: true, type: 'text', placeholder: '请输入身份证号'},
  {key: 'birthDate', label: '出生日期', type: 'readonly', placeholder: '将根据身份证号自动读取'},
  {key: 'archiveInCurrentOrg', label: '团籍是否在本组织', type: 'select', options: ['是', '否'], placeholder: '请选择'},
  {key: 'joinMonth', label: '入团年月', type: 'month', placeholder: '请选择入团年月'}
]

const createDefaultFormData = () => ({
  name: '',
  gender: '',
  nation: '',
  politics: '',
  collegeId: '',
  collegeName: '',
  college: '',
  classId: '',
  className: '',
  phone: '',
  leaguePosition: '',
  branchOrganizationId: '',
  branchOrganizationName: '',
  idCardNo: '',
  birthDate: '',
  archiveInCurrentOrg: '',
  joinMonth: ''
})

const normalizeOptions = (list) =>
  (list || []).map((item) => ({
    label: item.label || item,
    value: item.value || item
  }))

export default {
  components: {
    CommonHero
  },
  data() {
    return {
      fields,
      formId: null,
      formData: createDefaultFormData(),
      draftSavedAt: '',
      nationOptions: normalizeOptions(FALLBACK_NATION_OPTIONS),
      politicsOptions: normalizeOptions(FALLBACK_POLITICS_OPTIONS),
      leaguePositionOptions: normalizeOptions(FALLBACK_LEAGUE_POSITION_OPTIONS),
      collegeOptions: [],
      classOptions: [],
      organizationTree: [],
      organizationOptions: [],
      organizationPickerColumns: [],
      organizationPickerIndexs: [],
      archiveInOrgFieldKey: 'archiveInCurrentOrg',
      archiveInOrgPickerColumns: [[
        {text: '是', value: '是'},
        {text: '否', value: '否'}
      ]],
      joinMonthFieldKey: 'joinMonth',
      joinMonthPickerColumns: [],
      joinMonthPickerIndexs: [],
      searchPickerVisible: false,
      searchPickerTitle: '',
      searchPickerMode: '',
      searchPickerKeyword: '',
      searchPickerOptions: [],
      searchPickerIndex: 0,
      searchPickerTempOption: null,
      genderFieldKey: 'gender',
      genderPickerColumns: [[
        {text: '男', value: '男'},
        {text: '女', value: '女'}
      ]],
      leaguePositionFieldKey: 'leaguePosition',
      leaguePositionPickerColumns: [normalizeOptions(FALLBACK_LEAGUE_POSITION_OPTIONS).map((item) => ({
        text: item.label,
        value: item.value
      }))]
    }
  },
  computed: {
    nationLabels() {
      return this.nationOptions.map((item) => item.label)
    },
    nationIndex() {
      const index = this.nationOptions.findIndex((item) => item.value === this.formData.nation)
      return index > -1 ? index : 0
    },
    filteredSearchPickerOptions() {
      const keyword = String(this.searchPickerKeyword || '').trim().toLowerCase()
      if (!keyword) {
        return this.searchPickerOptions
      }
      return this.searchPickerOptions.filter((item) => String(item.label || '').toLowerCase().indexOf(keyword) > -1)
    },
    genderPickerIndex() {
      const options = (this.genderPickerColumns[0] || []).map((item) => item.value)
      const index = options.indexOf(this.formData[this.genderFieldKey])
      return index > -1 ? index : 0
    },
    leaguePositionPickerIndex() {
      const options = (this.leaguePositionPickerColumns[0] || []).map((item) => item.value)
      const index = options.indexOf(this.formData[this.leaguePositionFieldKey])
      return index > -1 ? index : 0
    },
    archiveInOrgPickerIndex() {
      const options = (this.archiveInOrgPickerColumns[0] || []).map((item) => item.value)
      const index = options.indexOf(this.formData[this.archiveInOrgFieldKey])
      return index > -1 ? index : 0
    }
  },
  watch: {
    'formData.idCardNo'() {
      this.syncBirthDateFromIdCard()
    }
  },
  onLoad() {
    this.restoreDraft()
    this.fillCurrentUserPhone()
    this.loadFormOptions()
    this.loadCurrentTyglForm()
    this.syncBirthDateFromIdCard()
    const joinMonthPickerState = this.buildJoinMonthPickerState(this.formData.joinMonth)
    this.joinMonthPickerColumns = joinMonthPickerState.columns
    this.joinMonthPickerIndexs = joinMonthPickerState.indexs
  },
  methods: {
    async loadCurrentTyglForm() {
      try {
        const result = await getCurrentTyglForm()
        if (!result || !result.id) {
          return
        }
        this.formId = result.id
        this.formData = {
          ...this.formData,
          ...result,
          collegeName: result.collegeName || result.college || this.formData.collegeName,
          college: result.college || result.collegeName || this.formData.college,
          className: result.className || this.formData.className
        }
        this.syncBirthDateFromIdCard()
        const joinMonthPickerState = this.buildJoinMonthPickerState(this.formData.joinMonth)
        this.joinMonthPickerColumns = joinMonthPickerState.columns
        this.joinMonthPickerIndexs = joinMonthPickerState.indexs
        if (this.formData.collegeId) {
          await this.loadClassOptions(this.formData.collegeId)
        }
      } catch (error) {
      }
    },
    buildSubmitPayload() {
      return {
        ...(this.formId ? {id: this.formId} : {}),
        name: this.formData.name,
        gender: this.formData.gender,
        nation: this.formData.nation,
        college: this.formData.collegeName || this.formData.college,
        className: this.formData.className,
        politics: this.formData.politics,
        phone: this.formData.phone,
        leaguePosition: this.formData.leaguePosition,
        branchOrganizationId: this.formData.branchOrganizationId || null,
        branchOrganizationName: this.formData.branchOrganizationName,
        idCardNo: this.formData.idCardNo,
        birthDate: this.formData.birthDate,
        archiveInCurrentOrg: this.formData.archiveInCurrentOrg,
        joinMonth: this.formData.joinMonth
      }
    },
    buildJoinMonthPickerState(currentValue) {
      const currentDate = new Date()
      const currentYear = currentDate.getFullYear()
      const years = []
      for (let year = 2000; year <= currentYear + 1; year += 1) {
        years.push({
          text: `${year}年`,
          value: String(year)
        })
      }
      const months = []
      for (let month = 1; month <= 12; month += 1) {
        months.push({
          text: `${String(month).padStart(2, '0')}月`,
          value: String(month).padStart(2, '0')
        })
      }
      let yearIndex = years.length - 1
      let monthIndex = 0
      const normalizedValue = String(currentValue || '').trim()
      if (/^\d{4}-\d{2}$/.test(normalizedValue)) {
        const [yearValue, monthValue] = normalizedValue.split('-')
        const nextYearIndex = years.findIndex((item) => item.value === yearValue)
        const nextMonthIndex = months.findIndex((item) => item.value === monthValue)
        yearIndex = nextYearIndex > -1 ? nextYearIndex : yearIndex
        monthIndex = nextMonthIndex > -1 ? nextMonthIndex : monthIndex
      }
      return {
        columns: [years, months],
        indexs: [yearIndex, monthIndex]
      }
    },
    async fillCurrentUserPhone() {
      const tokenUser = getCurrentUser()
      if (tokenUser && tokenUser.phone) {
        this.formData.phone = tokenUser.phone
      }
      try {
        const profile = await getUserProfile()
        if (profile && profile.phone) {
          this.formData.phone = profile.phone
        }
      } catch (error) {
      }
    },
    showToast(title) {
      uni.showToast({
        title,
        icon: 'none'
      })
    },
    getFieldDisplayValue(field) {
      if (field.displayKey) {
        return this.formData[field.displayKey]
      }
      return this.formData[field.key]
    },
    async loadFormOptions() {
      try {
        const [politicsList, nationList, leaguePositionList, organizationList, collegeList] = await Promise.all([
          listDictData({dictId: POLITICS_DICT_ID}).catch(() => []),
          listDictData({dictId: NATION_DICT_ID}).catch(() => []),
          listDictData({dictId: LEAGUE_POSITION_DICT_ID}).catch(() => []),
          listOrganizations().catch(() => []),
          listColleges().catch(() => [])
        ])

        if (Array.isArray(politicsList) && politicsList.length) {
          this.politicsOptions = normalizeOptions(
            politicsList
              .filter((item) => item && item.dictDataName)
              .map((item) => ({label: item.dictDataName, value: item.dictDataName}))
          )
        }
        if (Array.isArray(nationList) && nationList.length) {
          this.nationOptions = normalizeOptions(
            nationList
              .filter((item) => item && item.dictDataName)
              .map((item) => ({label: item.dictDataName, value: item.dictDataName}))
          )
        }
        if (Array.isArray(leaguePositionList) && leaguePositionList.length) {
          this.leaguePositionOptions = normalizeOptions(
            leaguePositionList
              .filter((item) => item && item.dictDataName)
              .map((item) => ({label: item.dictDataName, value: item.dictDataName}))
          )
          this.leaguePositionPickerColumns = [this.leaguePositionOptions.map((item) => ({
            text: item.label,
            value: item.value
          }))]
        }
        if (Array.isArray(organizationList) && organizationList.length) {
          this.organizationTree = this.normalizeOrganizationTree(organizationList)
          this.organizationOptions = this.flattenOrganizations(organizationList)
          const organizationPickerState = this.buildOrganizationPickerState(
            this.findOrganizationPathByValue(this.organizationTree, this.formData.branchOrganizationId) || []
          )
          this.organizationPickerColumns = organizationPickerState.columns
          this.organizationPickerIndexs = organizationPickerState.indexs
        }
        if (Array.isArray(collegeList) && collegeList.length) {
          this.collegeOptions = this.normalizeCollegeOptions(collegeList)
          if (this.formData.collegeId) {
            await this.loadClassOptions(this.formData.collegeId)
          }
        }
      } catch (error) {
        console.warn('tygl options load failed', error)
      }
    },
    normalizeCollegeOptions(list) {
      return (Array.isArray(list) ? list : [])
        .map((item) => ({
          label: item.collegeName || item.name || item.label || '',
          value: Number(item.collegeId || item.id || item.value || 0) || String(item.collegeId || item.id || item.value || ''),
          rawLabel: item.collegeName || item.name || item.label || ''
        }))
        .filter((item) => item.label && item.value !== '')
    },
    normalizeClassOptions(list) {
      return (Array.isArray(list) ? list : [])
        .map((item) => ({
          label: item.className || item.name || item.label || '',
          value: Number(item.classId || item.id || item.value || 0) || String(item.classId || item.id || item.value || ''),
          rawLabel: item.className || item.name || item.label || ''
        }))
        .filter((item) => item.label && item.value !== '')
    },
    normalizeOrganizationTree(list) {
      return (Array.isArray(list) ? list : []).map((item) => ({
        text: item.organizationName || item.name || item.label || '',
        value: Number(item.organizationId || item.id || item.value || 0) || String(item.organizationId || item.id || item.value || ''),
        rawLabel: item.organizationName || item.name || item.label || '',
        children: this.normalizeOrganizationTree(item.children || [])
      })).filter((item) => item.text && item.value !== '')
    },
    async loadClassOptions(collegeId) {
      if (!collegeId) {
        this.classOptions = []
        return
      }
      try {
        const classList = await listClasses({collegeId})
        this.classOptions = this.normalizeClassOptions(classList)
      } catch (error) {
        this.classOptions = []
      }
    },
    flattenOrganizations(list) {
      const source = Array.isArray(list) ? list : []
      const hasChildren = source.some((item) => Array.isArray(item.children) && item.children.length)
      if (hasChildren) {
        return this.flattenOrganizationTree(source)
      }
      const map = {}
      source.forEach((item) => {
        map[item.organizationId] = {
          ...item,
          children: []
        }
      })
      const roots = []
      source.forEach((item) => {
        const current = map[item.organizationId]
        const parentId = Number(item.parentId || 0)
        if (parentId && map[parentId]) {
          map[parentId].children.push(current)
        } else {
          roots.push(current)
        }
      })
      return this.flattenOrganizationTree(roots)
    },
    flattenOrganizationTree(list, parentPath = '') {
      const result = []
      ;(list || []).forEach((item) => {
        const currentName = item.organizationName || ''
        const label = parentPath ? `${parentPath} / ${currentName}` : currentName
        if (item.organizationId) {
          result.push({
            label,
            value: Number(item.organizationId),
            rawLabel: currentName
          })
        }
        if (Array.isArray(item.children) && item.children.length) {
          result.push(...this.flattenOrganizationTree(item.children, label))
        }
      })
      return result
    },
    restoreDraft() {
      const draft = uni.getStorageSync(STORAGE_KEY)
      if (!draft || !draft.formData) {
        return
      }
      this.formData = {
        ...createDefaultFormData(),
        ...draft.formData
      }
      if (!this.formData.collegeName && this.formData.college) {
        this.formData.collegeName = this.formData.college
      }
      this.draftSavedAt = draft.savedAt || ''
    },
    handleSelectChange(field, event) {
      const index = Number(event.detail.value)
      this.formData[field.key] = field.options[index] || ''
    },
    handleDateChange(field, event) {
      this.formData[field.key] = event.detail.value
    },
    handleTextInput(field, event) {
      const value = typeof event === 'string' ? event : (event.detail && event.detail.value) || ''
      this.formData[field.key] = value || ''
    },
    openGenderPicker(field) {
      this.genderFieldKey = field.key
      this.$nextTick(() => {
        this.$refs.genderPicker && this.$refs.genderPicker.open()
      })
    },
    closeGenderPicker() {
      return
    },
    confirmGenderPicker(event) {
      const value = (((event || {}).value || [])[0] || {}).value || ''
      this.formData[this.genderFieldKey] = value
      this.closeGenderPicker()
    },
    openLeaguePositionPicker(field) {
      this.leaguePositionFieldKey = field.key
      this.$nextTick(() => {
        this.$refs.leaguePositionPicker && this.$refs.leaguePositionPicker.open()
      })
    },
    closeLeaguePositionPicker() {
      return
    },
    confirmLeaguePositionPicker(event) {
      const value = (((event || {}).value || [])[0] || {}).value || ''
      this.formData[this.leaguePositionFieldKey] = value
      this.closeLeaguePositionPicker()
    },
    openArchiveInOrgPicker(field) {
      this.archiveInOrgFieldKey = field.key
      this.$nextTick(() => {
        this.$refs.archiveInOrgPicker && this.$refs.archiveInOrgPicker.open()
      })
    },
    closeArchiveInOrgPicker() {
      return
    },
    confirmArchiveInOrgPicker(event) {
      const value = (((event || {}).value || [])[0] || {}).value || ''
      this.formData[this.archiveInOrgFieldKey] = value
      this.closeArchiveInOrgPicker()
    },
    openJoinMonthPicker(field) {
      this.joinMonthFieldKey = field.key
      const pickerState = this.buildJoinMonthPickerState(this.formData[this.joinMonthFieldKey])
      this.joinMonthPickerColumns = pickerState.columns
      this.joinMonthPickerIndexs = pickerState.indexs
      this.$nextTick(() => {
        this.$refs.joinMonthPicker && this.$refs.joinMonthPicker.open()
      })
    },
    closeJoinMonthPicker() {
      return
    },
    handleJoinMonthPickerChange(event) {
      this.joinMonthPickerIndexs = (event && event.indexs) || this.joinMonthPickerIndexs
    },
    confirmJoinMonthPicker(event) {
      const values = (event && event.value) || []
      const yearValue = (values[0] && values[0].value) || ''
      const monthValue = (values[1] && values[1].value) || ''
      if (yearValue && monthValue) {
        this.formData[this.joinMonthFieldKey] = `${yearValue}-${monthValue}`
      }
      this.joinMonthPickerIndexs = (event && event.indexs) || this.joinMonthPickerIndexs
      this.closeJoinMonthPicker()
    },
    handleNationChange(event) {
      const index = Number(event.detail.value)
      const option = this.nationOptions[index]
      this.formData.nation = (option && option.value) || ''
    },
    openPoliticsPicker() {
      this.openSearchPicker({
        title: '政治面貌',
        mode: 'politics',
        options: this.politicsOptions,
        currentValue: this.formData.politics
      })
    },
    openOrganizationPicker() {
      if (!this.organizationTree.length) {
        this.showToast('暂无团支部数据')
        return
      }
      const pickerState = this.buildOrganizationPickerState(
        this.findOrganizationPathByValue(this.organizationTree, this.formData.branchOrganizationId) || []
      )
      this.organizationPickerColumns = pickerState.columns
      this.organizationPickerIndexs = pickerState.indexs
      this.$nextTick(() => {
        this.$refs.organizationPicker && this.$refs.organizationPicker.open()
      })
    },
    closeOrganizationPicker() {
      return
    },
    handleOrganizationPickerChange(event) {
      const pickerState = this.buildOrganizationPickerState((event && event.indexs) || [])
      this.organizationPickerColumns = pickerState.columns
      this.organizationPickerIndexs = pickerState.indexs
    },
    confirmOrganizationPicker(event) {
      const pickerState = this.buildOrganizationPickerState((event && event.indexs) || this.organizationPickerIndexs || [])
      const pathNodes = pickerState.pathNodes || []
      const selectedNode = pathNodes[pathNodes.length - 1]
      if (!selectedNode) {
        this.closeOrganizationPicker()
        return
      }
      this.formData.branchOrganizationId = selectedNode.value
      this.formData.branchOrganizationName = pathNodes.map((item) => item.rawLabel || item.text).filter(Boolean).join(' / ')
      this.organizationPickerIndexs = pickerState.indexs
      this.closeOrganizationPicker()
    },
    findOrganizationPathByValue(list, targetValue, path = []) {
      const source = Array.isArray(list) ? list : []
      const normalizedTarget = String(targetValue || '')
      for (let index = 0; index < source.length; index += 1) {
        const item = source[index]
        const nextPath = path.concat(index)
        if (String(item.value) === normalizedTarget) {
          return nextPath
        }
        if (Array.isArray(item.children) && item.children.length) {
          const result = this.findOrganizationPathByValue(item.children, targetValue, nextPath)
          if (result) {
            return result
          }
        }
      }
      return null
    },
    buildOrganizationPickerState(indexs = []) {
      const columns = []
      const normalizedIndexs = []
      const pathNodes = []
      let currentList = Array.isArray(this.organizationTree) ? this.organizationTree : []
      let depth = 0
      while (Array.isArray(currentList) && currentList.length) {
        columns.push(currentList.map((item) => ({
          text: item.text,
          value: item.value,
          rawLabel: item.rawLabel
        })))
        let currentIndex = Number(indexs[depth] || 0)
        if (currentIndex < 0 || currentIndex >= currentList.length) {
          currentIndex = 0
        }
        normalizedIndexs.push(currentIndex)
        const currentNode = currentList[currentIndex]
        if (!currentNode) {
          break
        }
        pathNodes.push(currentNode)
        currentList = Array.isArray(currentNode.children) ? currentNode.children : []
        depth += 1
      }
      return {
        columns,
        indexs: normalizedIndexs,
        pathNodes
      }
    },
    openCollegePicker() {
      this.openSearchPicker({
        title: '学院',
        mode: 'college',
        options: this.collegeOptions,
        currentValue: this.formData.collegeId
      })
    },
    openClassPicker() {
      if (!this.formData.collegeId) {
        this.showToast('请先选择学院')
        return
      }
      this.openSearchPicker({
        title: '班级',
        mode: 'class',
        options: this.classOptions,
        currentValue: this.formData.classId
      })
    },
    openSearchPicker({title, mode, options, currentValue}) {
      this.searchPickerTitle = title
      this.searchPickerMode = mode
      this.searchPickerOptions = Array.isArray(options) ? options : []
      this.searchPickerKeyword = ''
      this.searchPickerVisible = true
      this.$nextTick(() => {
        this.syncSearchPickerValue(currentValue)
      })
    },
    closeSearchPicker() {
      this.searchPickerVisible = false
    },
    syncSearchPickerValue(currentValue) {
      const list = this.filteredSearchPickerOptions
      if (!list.length) {
        this.searchPickerIndex = 0
        this.searchPickerTempOption = null
        return
      }
      let index = list.findIndex((item) => item.value === currentValue || item.label === currentValue)
      if (index < 0) {
        index = 0
      }
      this.searchPickerIndex = index
      this.searchPickerTempOption = list[index]
    },
    handleSearchPickerInput(event) {
      const value = typeof event === 'string' ? event : (event.detail && event.detail.value) || ''
      this.searchPickerKeyword = value || ''
      this.$nextTick(() => {
        const currentValue = this.searchPickerTempOption ? this.searchPickerTempOption.value : ''
        this.syncSearchPickerValue(currentValue)
      })
    },
    handleSearchPickerChange(event) {
      const index = Number((event.detail.value || [0])[0] || 0)
      this.searchPickerIndex = index
      this.searchPickerTempOption = this.filteredSearchPickerOptions[index] || null
    },
    async confirmSearchPicker() {
      const option = this.searchPickerTempOption
      if (!option) {
        this.closeSearchPicker()
        return
      }
      if (this.searchPickerMode === 'politics') {
        this.formData.politics = option.value
      } else if (this.searchPickerMode === 'college') {
        const nextCollegeId = option.value
        const nextCollegeName = option.label
        const collegeChanged = String(this.formData.collegeId || '') !== String(nextCollegeId || '')
        this.formData.collegeId = nextCollegeId
        this.formData.collegeName = nextCollegeName
        this.formData.college = nextCollegeName
        if (collegeChanged) {
          this.formData.classId = ''
          this.formData.className = ''
          this.classOptions = []
          await this.loadClassOptions(nextCollegeId)
        }
      } else if (this.searchPickerMode === 'class') {
        this.formData.classId = option.value
        this.formData.className = option.label
      }
      this.closeSearchPicker()
    },
    getSelectIndex(field) {
      const currentValue = this.formData[field.key]
      const index = field.options.indexOf(currentValue)
      return index > -1 ? index : 0
    },
    parseBirthDateFromIdCard(idCardNo) {
      const value = String(idCardNo || '').trim().toUpperCase()
      let rawBirth = ''
      if (/^\d{17}[\dX]$/.test(value)) {
        rawBirth = value.slice(6, 14)
      } else if (/^\d{15}$/.test(value)) {
        rawBirth = `19${value.slice(6, 12)}`
      } else {
        return ''
      }
      const year = rawBirth.slice(0, 4)
      const month = rawBirth.slice(4, 6)
      const day = rawBirth.slice(6, 8)
      const date = new Date(`${year}/${month}/${day}`)
      if (Number.isNaN(date.getTime())) {
        return ''
      }
      return `${year}-${month}-${day}`
    },
    syncBirthDateFromIdCard() {
      this.formData.birthDate = this.parseBirthDateFromIdCard(this.formData.idCardNo)
    },
    validateForm() {
      for (const field of this.fields) {
        if (field.required && !String(this.getFieldDisplayValue(field) || '').trim()) {
          this.showToast(`请完善：${field.label}`)
          return false
        }
      }
      if (this.formData.phone && !/^1\d{10}$/.test(this.formData.phone)) {
        this.showToast('请输入正确的手机号码')
        return false
      }
      if (this.formData.idCardNo && !this.formData.birthDate) {
        this.showToast('身份证号格式不正确，无法识别出生日期')
        return false
      }
      if (this.formData.collegeId && !this.formData.classId) {
        this.showToast('请选择班级')
        return false
      }
      return true
    },
    saveDraft() {
      const savedAt = this.formatNow()
      uni.setStorageSync(STORAGE_KEY, {
        formData: this.formData,
        savedAt
      })
      this.draftSavedAt = savedAt
      uni.showToast({
        title: '草稿已保存',
        icon: 'success'
      })
    },
    async submitForm() {
      if (!this.validateForm()) {
        return
      }
      try {
        const payload = this.buildSubmitPayload()
        const result = this.formId
          ? await updateTyglForm(payload)
          : await saveTyglForm(payload)
        if (!this.formId && result && result.id) {
          this.formId = result.id
        }
        const savedAt = this.formatNow()
        uni.setStorageSync(STORAGE_KEY, {
          formData: this.formData,
          savedAt,
          status: 'submitted'
        })
        this.draftSavedAt = savedAt
        uni.showModal({
          title: '提交成功',
          content: this.formId ? '团员档案已更新。' : '团员档案已创建。',
          showCancel: false
        })
      } catch (error) {
        this.showToast((error && error.message) || '保存失败')
      }
    },
    formatNow() {
      const now = new Date()
      const pad = (value) => String(value).padStart(2, '0')
      return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}`
    }
  }
}
</script>

<style lang="scss" scoped>
.page {
  min-height: 100vh;
  background: rgba(241, 241, 241, 1);
  //radial-gradient(circle at top right, rgba(20, 150, 242, 0.14), transparent 30%),
  //linear-gradient(180deg, #f5fbff 0%, #eef7ff 100%);
}

.page-scroll {
  height: 100vh;
  padding: 0 0 40rpx;
}

.section-card{
  border-radius: 30rpx;
  background: rgba(255, 255, 255, 1);
}

.action-card {
  border-radius: 30rpx;
  //background: rgba(255, 255, 255, 0.94);
  //border: 1rpx solid rgba(20, 150, 242, 0.08);
  //box-shadow: 0 10rpx 28rpx rgba(34, 94, 142, 0.08);
}

.section-card,
.action-card {
  margin-top: 24rpx;
  padding: 26rpx;
  margin-left: 24rpx;
  margin-right: 24rpx;
}

.section-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  margin-bottom: 18rpx;
}

.section-title {
  font-size: 30rpx;
  font-weight: 700;
  color: #1f2329;
}

.field-list {
  display: flex;
  flex-direction: column;
  gap: 22rpx;
}

.field-label {
  margin-bottom: 12rpx;
  font-size: 25rpx;
  font-weight: 600;
  color: #2b3037;
}

.field-required {
  margin-left: 8rpx;
  color: #1496f2;
}

.field-picker {
  width: 100%;
  box-sizing: border-box;
  padding: 22rpx 24rpx;
  border-radius: 22rpx;
  background: #F4FCFF;
  border: 1rpx solid rgba(220,220,220,1);
  font-size: 24rpx;
  color: #2a2e35;
}

.field-picker--readonly {
  background: #f9fafb;
}

:deep(.field-native-input.uv-input) {
  width: 100%;
  height: 88rpx;
  padding: 0 24rpx !important;
  border-radius: 12rpx;
  border: 1px solid #dcdfe6 !important;
  background: #ffffff !important;
  box-sizing: border-box;
}

:deep(.field-native-input.uv-input .uv-input__content__field-wrapper__field) {
  font-size: 28rpx;
  line-height: 88rpx;
  color: #303133;
}

.field-placeholder {
  color: #aa9f98;
}

.field-value {
  color: #2a2e35;
}

.action-card {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18rpx;
}

.option-mask {
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 99;
  display: flex;
  align-items: flex-end;
  background: rgba(15, 23, 42, 0.34);
}

.option-popup {
  width: 100%;
  padding: 24rpx 24rpx calc(24rpx + env(safe-area-inset-bottom));
  border-radius: 32rpx 32rpx 0 0;
  background: #fff;
}

.option-popup-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.option-popup-title {
  font-size: 28rpx;
  font-weight: 700;
  color: #1f2329;
}

.option-popup-btn {
  font-size: 24rpx;
  color: #7c736e;
}

.option-popup-btn--primary {
  color: #1496f2;
  font-weight: 600;
}

:deep(.option-search.uv-input) {
  width: 100%;
  height: 84rpx;
  margin-top: 20rpx;
  padding: 0 24rpx !important;
  border-radius: 22rpx;
  background: #f8f4f1 !important;
  border: 1rpx solid #eadfd7 !important;
}

:deep(.option-search.uv-input .uv-input__content__field-wrapper__field) {
  font-size: 24rpx;
  color: #2a2e35;
}

.option-picker-wrap {
  margin-top: 20rpx;
  border-radius: 24rpx;
  background: #fafcff;
  overflow: hidden;
}

.option-picker-view {
  width: 100%;
  height: 420rpx;
}

.option-picker-item {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 84rpx;
  padding: 0 24rpx;
  font-size: 28rpx;
  color: #2a2e35;
  text-align: center;
}

.option-empty {
  padding: 60rpx 0 40rpx;
  text-align: center;
  font-size: 24rpx;
  color: #aa9f98;
}

.ghost-btn,
.primary-btn {
  height: 88rpx;
  line-height: 88rpx;
  border-radius: 22rpx;
  font-size: 28rpx;
  font-weight: 700;
  margin: 0;
}

.ghost-btn {
  background: #FFA2DA;
  color: #ffffff;
  border: none;
  border-radius: 999px;
}

.primary-btn {
  background: linear-gradient(147.22deg, rgba(0, 180, 255, 1) 37.65%, rgba(88, 206, 255, 1) 80.42%);
  color: #fff;
  border-radius: 999px;
}
</style>
