<template>
  <el-dialog
    :close-on-click-modal="false"
    :visible.sync="addressView"
    append-to-body
    class="modal"
    title="选择城市"
    width="950px"
  >
    <el-row :gutter="24" type="flex">
      <el-col :xl="24" :lg="24" :md="24" :sm="24" :xs="24" class="item">
        <div class="check-btn">
          <el-checkbox :value="iSselect" @change="onSelectAll">全选</el-checkbox>
          <div class="empty" @click="empty">清空</div>
        </div>
      </el-col>
    </el-row>

    <el-row :gutter="24" v-loading="loading">
      <el-col
        :xl="6" :lg="6" :md="6" :sm="8" :xs="6"
        class="item"
        v-for="(item, index) in cityList"
        :key="'p-' + item.cityId"
      >
        <div class="province-wrap" v-if="item.level == 1">
          <div class="province-row">
            <el-checkbox
              :value="item.checked"
              :indeterminate="item.indeterminate"
              :disabled="item.disabled"
              @change="(val) => onProvinceChange(index, val)"
              :class="{ 'disabled-checkbox': item.disabled }"
            >{{ item.cityName }}</el-checkbox>
            <span
              v-if="item.children && item.children.length"
              class="expand-btn"
              @click.stop="toggleExpand(index)"
            >{{ activeCity === index ? '收起' : '展开' }}</span>
          </div>

          <div class="city-panel" v-show="activeCity === index">
            <div class="checkBox">
              <el-checkbox
                v-for="(subitem, subindex) in item.children"
                :key="'c-' + subitem.cityId"
                class="itemn"
                :value="subitem.checked"
                :disabled="subitem.disabled"
                @change="(val) => onCityChange(index, subindex, val)"
                :class="{ 'disabled-checkbox': subitem.disabled }"
              >{{ subitem.cityName }}</el-checkbox>
            </div>
          </div>
        </div>
      </el-col>
    </el-row>

    <div slot="footer">
      <el-button @click="close">取消</el-button>
      <el-button type="primary" @click="confirm">确定</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { getAllList } from '@/api/hisStore/city'

export default {
  name: 'CityZm',
  props: {
    type: {
      type: Number,
      default: 0
    },
    selectedCities: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      iSselect: false,
      addressView: false,
      cityList: [],
      activeCity: -1,
      loading: false
    }
  },
  methods: {
    /** 点击展开/收起市级列表（不用 hover，即时响应） */
    toggleExpand(index) {
      this.activeCity = this.activeCity === index ? -1 : index
    },

    getCityList() {
      this.loading = true
      this.activeCity = -1
      this.iSselect = false
      getAllList().then(res => {
        this.loading = false
        const data = res.data || []
        const provinces = data.filter(item => item.level === 1)

        provinces.forEach(province => {
          const cities = data.filter(
            sub => sub.parentId === province.cityId && sub.level === 2
          )
          cities.forEach(city => {
            const counties = data.filter(
              county => county.parentId === city.cityId && county.level === 3
            )
            this.$set(city, 'children', counties)
            this.$set(city, 'checked', false)
            this.$set(city, 'disabled', false)
            counties.forEach(county => {
              this.$set(county, 'checked', false)
              this.$set(county, 'disabled', false)
            })
          })
          this.$set(province, 'children', cities)
          this.$set(province, 'checked', false)
          this.$set(province, 'indeterminate', false)
          this.$set(province, 'disabled', false)
          this.$set(province, 'count', 0)
          this.markSelectedCities(province)
        })

        this.cityList = provinces
      })
    },

    /** 已选城市禁用（外部传入 selectedCities） */
    markSelectedCities(province) {
      if (!this.selectedCities || this.selectedCities.length === 0) return

      const selectedProvince = this.selectedCities.find(city => {
        if (city.cityId === province.cityId) {
          return !city.children || city.children.length === 0
        }
        return false
      })

      if (selectedProvince) {
        this.$set(province, 'disabled', true)
        ;(province.children || []).forEach((city, cityIndex) => {
          this.$set(province.children[cityIndex], 'disabled', true)
          ;(city.children || []).forEach((county, countyIndex) => {
            this.$set(province.children[cityIndex].children[countyIndex], 'disabled', true)
          })
        })
        return
      }

      const selectedCityMap = new Map()
      this.selectedCities.forEach(selectedCity => {
        if (selectedCity.cityId === province.cityId && selectedCity.children && selectedCity.children.length > 0) {
          selectedCity.children.forEach(child => {
            if (!selectedCityMap.has(child.cityId)) {
              selectedCityMap.set(child.cityId, new Set())
            }
            if (child.children && child.children.length > 0) {
              child.children.forEach(county => {
                selectedCityMap.get(child.cityId).add(county.cityId)
              })
            }
          })
        }
      })

      if (selectedCityMap.size === 0) return

      const allCitiesSelected =
        province.children &&
        province.children.length > 0 &&
        province.children.every(city => selectedCityMap.has(city.cityId))

      if (allCitiesSelected) {
        this.$set(province, 'disabled', true)
      }

      ;(province.children || []).forEach((city, cityIndex) => {
        if (!selectedCityMap.has(city.cityId)) return

        let citySelectedWhole = false
        this.selectedCities.forEach(selectedCity => {
          if (selectedCity.cityId === province.cityId && selectedCity.children) {
            const foundCity = selectedCity.children.find(c => c.cityId === city.cityId)
            if (foundCity && (!foundCity.children || foundCity.children.length === 0)) {
              citySelectedWhole = true
            }
          }
        })

        const selectedCountyIds = selectedCityMap.get(city.cityId)
        if (citySelectedWhole || !city.children || city.children.length === 0 || selectedCountyIds.size === 0) {
          this.$set(province.children[cityIndex], 'disabled', true)
          ;(city.children || []).forEach((_, countyIndex) => {
            this.$set(province.children[cityIndex].children[countyIndex], 'disabled', true)
          })
          return
        }

        const allCountiesSelected = city.children.every(county => selectedCountyIds.has(county.cityId))
        if (allCountiesSelected) {
          this.$set(province.children[cityIndex], 'disabled', true)
        }
        city.children.forEach((county, countyIndex) => {
          if (selectedCountyIds.has(county.cityId)) {
            this.$set(province.children[cityIndex].children[countyIndex], 'disabled', true)
          }
        })
      })
    },

    /** 根据市级勾选情况，回写省的 checked / indeterminate */
    syncProvinceState(index) {
      const province = this.cityList[index]
      if (!province) return
      const enabledCities = (province.children || []).filter(c => !c.disabled)
      const checkedCount = enabledCities.filter(c => c.checked === true).length
      const total = enabledCities.length

      this.$set(province, 'count', checkedCount)
      if (total === 0) {
        this.$set(province, 'checked', false)
        this.$set(province, 'indeterminate', false)
        return
      }
      // 全选：省勾选；部分：半选；全不选：不勾选
      this.$set(province, 'checked', checkedCount === total)
      this.$set(province, 'indeterminate', checkedCount > 0 && checkedCount < total)
      if (checkedCount === 0) {
        this.iSselect = false
      }
      this.syncSelectAllFlag()
    },

    syncSelectAllFlag() {
      const enabledProvinces = this.cityList.filter(p => !p.disabled)
      this.iSselect =
        enabledProvinces.length > 0 &&
        enabledProvinces.every(p => p.checked === true && !p.indeterminate)
    },

    /**
     * 省勾选变化：
     * - true  => 联动选中所有未禁用市
     * - false => 联动取消所有未禁用市
     */
    onProvinceChange(index, val) {
      const province = this.cityList[index]
      if (!province || province.disabled) return

      const checked = val === true
      this.$set(province, 'checked', checked)
      this.$set(province, 'indeterminate', false)

      ;(province.children || []).forEach((city, key) => {
        if (!city.disabled) {
          this.$set(province.children[key], 'checked', checked)
        }
      })

      const enabledCount = (province.children || []).filter(c => !c.disabled).length
      this.$set(province, 'count', checked ? enabledCount : 0)
      if (!checked) {
        this.iSselect = false
      }
      this.syncSelectAllFlag()
      // 勾选省时自动展开，方便确认；取消时不强制收起
      if (checked) {
        this.activeCity = index
      }
      this.$forceUpdate()
    },

    /**
     * 市勾选变化：只改当前市，再回写省状态（不会全选其它市）
     */
    onCityChange(index, subindex, val) {
      const province = this.cityList[index]
      if (!province || !province.children || !province.children[subindex]) return
      const city = province.children[subindex]
      if (city.disabled) return

      this.$set(province.children[subindex], 'checked', val === true)
      this.syncProvinceState(index)
      this.$forceUpdate()
    },

    /** 顶部全选 */
    onSelectAll(val) {
      const checked = val === true
      this.iSselect = checked
      this.cityList.forEach((province, key) => {
        if (province.disabled) return
        this.$set(this.cityList[key], 'checked', checked)
        this.$set(this.cityList[key], 'indeterminate', false)
        ;(province.children || []).forEach((city, k) => {
          if (!city.disabled) {
            this.$set(this.cityList[key].children[k], 'checked', checked)
          }
        })
        const enabledCount = (province.children || []).filter(c => !c.disabled).length
        this.$set(this.cityList[key], 'count', checked ? enabledCount : 0)
      })
      this.$forceUpdate()
    },

    empty() {
      this.cityList.forEach((province, key) => {
        if (province.disabled) return
        this.$set(this.cityList[key], 'checked', false)
        this.$set(this.cityList[key], 'indeterminate', false)
        this.$set(this.cityList[key], 'count', 0)
        ;(province.children || []).forEach((city, k) => {
          if (!city.disabled) {
            this.$set(this.cityList[key].children[k], 'checked', false)
          }
        })
      })
      this.iSselect = false
      this.$forceUpdate()
    },

    confirm() {
      const selectList = []
      this.cityList.forEach(province => {
        if (province.disabled) return

        const selectedCities = []
        ;(province.children || []).forEach(city => {
          if (city.checked === true && !city.disabled) {
            const cityData = { cityId: city.cityId }
            if (city.children && city.children.length > 0) {
              const selectedCounties = city.children
                .filter(county => county.checked === true && !county.disabled)
                .map(county => ({ cityId: county.cityId }))
              if (selectedCounties.length > 0) {
                cityData.children = selectedCounties
              }
            }
            selectedCities.push(cityData)
          }
        })

        const enabledCities = (province.children || []).filter(c => !c.disabled)
        const allSelected =
          province.checked === true &&
          !province.indeterminate &&
          selectedCities.length === enabledCities.length

        if (allSelected || selectedCities.length > 0) {
          selectList.push({
            name: province.cityName,
            cityId: province.cityId,
            // 整省全选：children 空数组；否则带上手选市
            children: allSelected ? [] : selectedCities
          })
        }
      })

      if (selectList.length === 0) {
        return this.$message({
          message: '至少选择一个省份或者城市',
          type: 'error'
        })
      }

      this.$emit('selectCity', selectList, this.type)
      this.addressView = false
      this.cityList = []
      this.activeCity = -1
      this.iSselect = false
    },

    close() {
      this.addressView = false
      this.cityList = []
      this.activeCity = -1
      this.iSselect = false
    }
  }
}
</script>

<style scoped>
.modal .item {
  position: relative;
  margin-bottom: 16px;
}

.province-wrap {
  position: relative;
}

.province-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.expand-btn {
  font-size: 12px;
  color: #409eff;
  cursor: pointer;
  user-select: none;
  flex-shrink: 0;
}

.expand-btn:hover {
  text-decoration: underline;
}

.city-panel {
  position: relative;
  z-index: 9;
  margin-top: 6px;
  width: 100%;
}

.city-panel .checkBox {
  width: 100%;
  padding: 10px;
  border: 1px solid #eee;
  background-color: #fff;
  max-height: 140px;
  overflow-x: hidden;
  overflow-y: auto;
  box-sizing: border-box;
}

.city-panel .checkBox .itemn {
  margin: 0 12px 8px 0;
}

.empty {
  cursor: pointer;
  margin-left: 10px;
}

.check-btn {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
}

.disabled-checkbox {
  opacity: 0.5;
  cursor: not-allowed !important;
}

.disabled-checkbox ::v-deep  .el-checkbox__input.is-disabled .el-checkbox__inner {
  background-color: #f5f7fa;
  border-color: #e4e7ed;
  cursor: not-allowed;
}

.disabled-checkbox ::v-deep  .el-checkbox__input.is-disabled + .el-checkbox__label {
  color: #c0c4cc;
  cursor: not-allowed;
}
</style>
