<template>
  <div class="area-select-container">
    <!-- 区域选择器 -->
    <el-cascader
      v-model="areaValue"
      :options="areaTree"
      :props="cascaderProps"
      filterable
      clearable
      placeholder="请选择中国区域"
      collapse-tags
      @change="handleAreaChange"
      v-if="isAreaTreeReady"
      style="width: 100%; margin-bottom: 8px;"
    />
    
    <!-- 详细地址输入框 -->
    <el-input
      v-model="detailAddress"
      placeholder="请输入详细地址（如：XX街道XX小区XX号楼）"
      @input="handleDetailChange"
      style="width: 100%;"
    />
  </div>
</template>

<script>
import areaData from './data.js'
import { formatAreaTextEnhanced } from './index.js'

export default {
  name: 'ChinaAreaSelectWithDetail',
  props: {
    // 外部传入的组合值：格式为「[标准地址](自定义地址)」
    value: {
      type: String,
      default: ''
    },
    // 配置绑定值类型：code（行政区划代码）/ name（区域名称）
    keyType: {
      type: String,
      default: 'code',
      validator: val => ['code', 'name'].includes(val)
    },
    // 是否只选择到市级（省/市），默认选到区级（省/市/区）
    onlyCityLevel: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      areaTree: [],
      // 特殊区域代码（直辖市+港澳特别行政区）
      specialAreaCodes: ['110000', '120000', '310000', '500000', '810000', '820000'],
      isAreaTreeReady: false,
      // 区域选择器的内部值（数组格式，存储code）
      areaValue: [],
      // 详细地址输入值
      detailAddress: '',
      cascaderProps: {
        value: 'code',
        label: 'name',
        children: 'children',
        checkStrictly: false,
        expandTrigger: 'click',
        multiple: false,
        leaf: node => !node.children
      }
    }
  },
  watch: {
    // 监听外部传入的value，自动拆分并回显
    value: {
      immediate: true,
      handler(val) {
        this.parseCombineValue(val)
      }
    }
  },
  computed: {
    // 组合值：对外输出「[标准地址](自定义地址)」格式
    combineValue() {
      // 1. 转换区域值为标准字符串（code/name格式）
      let standardAddress = ''
      if (this.areaValue.length) {
        standardAddress = this.keyType === 'name' 
          ? this.convertCodeToName(this.areaValue).join('/')
          : this.areaValue.join('/')
      }
      // 2. 组合最终格式：[标准地址](自定义地址)
      if (!standardAddress && !this.detailAddress) return ''
      if (standardAddress && !this.detailAddress) return `[${standardAddress}]()`
      if (!standardAddress && this.detailAddress) return `[()](${this.detailAddress})`
      return `[${standardAddress}](${this.detailAddress})`
    }
  },
  created() {
    this.$nextTick(() => {
      this.buildAreaTree()
    })
  },
  methods: {
    /**
     * 正则解析组合值：提取[标准地址]和(自定义地址)部分
     * @param {String} val - 外部传入的「[标准地址](自定义地址)」格式值
     */
    parseCombineValue(val) {
      const formattedAddress = formatAreaTextEnhanced(val)
      this.areaValue = formattedAddress.standard.split('/').filter(Boolean)
      this.detailAddress = formattedAddress.custom.trim()
    },

    /**
     * 构建树形结构：兼容直辖市+港澳特别行政区的两级结构
     */
    buildAreaTree() {
      const tree = {};
      
      // 第一步：初始化所有省级节点（非叶子节点，带children）
      Object.keys(areaData).forEach(code => {
        if (code.endsWith('0000') && !tree[code]) {
          tree[code] = {
            code: code,
            name: areaData[code],
            children: [] // 省级节点是父节点，保留children
          };
        }
      });
      
      // 第二步：遍历所有非省级节点，构建层级
      Object.entries(areaData).forEach(([code, name]) => {
        if (code.length !== 6) return;
        const provinceCode = code.substring(0, 2) + '0000';
        
        // 跳过省级节点（已初始化）
        if (code === provinceCode) return;
        
        // 判断是否为特殊区域（直辖市/港澳）
        const isSpecialArea = this.specialAreaCodes.includes(provinceCode);
        
        // 1. 特殊区域处理：区级直接挂载到省级，且区级是叶子节点（无children）
        if (isSpecialArea) {
          if (tree[provinceCode]) {
            tree[provinceCode].children.push({ code, name });
          }
        } 
        // 2. 普通省份处理：省→市→区三级
        else {
          const cityCode = code.substring(0, 4) + '00';
          const provinceNode = tree[provinceCode];
          
          if (!provinceNode) return;
          
          // 2.1 初始化市级节点（非叶子节点，带children）
          if (!provinceNode.children.some(item => item.code === cityCode)) {
            provinceNode.children.push({
              code: cityCode,
              name: areaData[cityCode] || '',
              children: [] // 市级节点是父节点，保留children
            });
          }
          
          // 2.2 挂载区级节点（叶子节点，无children）
          if (code !== cityCode) {
            const cityNode = provinceNode.children.find(item => item.code === cityCode);
            if (cityNode) {
              cityNode.children.push({ code, name });
            }
          }
        }
      });
      
      // 第三步：格式化树形结构，过滤空节点
      this.areaTree = Object.values(tree)
        .filter(province => province.name && province.children.length > 0)
        .map(province => {
          province.children = province.children.filter(city => city.name);
          return province;
        });
      
      // 标记数据就绪，渲染组件
      this.isAreaTreeReady = true;
    },

    /**
     * code转name（容错处理）
     */
    convertCodeToName(codeArr) {
      if (!Array.isArray(codeArr) || !codeArr.length) return [];
      return codeArr.map(code => areaData[code] || '').filter(Boolean);
    },

    /**
     * name转code（容错处理）
     */
    convertNameToCode(nameArr) {
      if (!Array.isArray(nameArr) || !nameArr.length) return [];
      const nameToCodeMap = Object.fromEntries(
        Object.entries(areaData).map(([code, name]) => [name, code])
      );
      return nameArr.map(name => nameToCodeMap[name] || '').filter(Boolean);
    },

    /**
     * 区域选择器变化回调
     */
    handleAreaChange() {
      this.$emit('input', this.combineValue)
      this.$emit('change', this.combineValue, {
        standard: this.keyType === 'name' ? this.convertCodeToName(this.areaValue).join('/') : this.areaValue.join('/'),
        custom: this.detailAddress
      })
    },

    /**
     * 详细地址变化回调
     */
    handleDetailChange() {
      this.$emit('input', this.combineValue)
      this.$emit('change', this.combineValue, {
        standard: this.keyType === 'name' ? this.convertCodeToName(this.areaValue).join('/') : this.areaValue.join('/'),
        custom: this.detailAddress
      })
    }
  }
}
</script>

<style scoped>
.area-select-container {
  width: 100%;
}
</style>