<template>
  <!-- 
    整页表单的分片表单
    v 1.0
    2021-05-12
    Lufthafen
  -->
  <a-form-model
    :label-col="labelCol"
    :model="form"
    :rules="rules"
    :wrapper-col="wrapperCol"
    ref="form"
  >
    <a-spin :spinning="loading">
      <a-icon slot="indicator" spin type="loading" />
      <a-row :gutter="16" type="flex">
        <a-col :span="12">
          <a-form-model-item class="ant-row-flex" label="项目名称" prop="projectName">
            <a-input placeholder="请输入项目名称" v-model="form.projectName" />
          </a-form-model-item>
        </a-col>
        <a-col :span="12">
          <a-form-model-item class="ant-row-flex" label="幢名称" prop="buildingName">
            <a-input placeholder="请输入幢名称" v-model="form.buildingName" />
          </a-form-model-item>
        </a-col>
        <a-col :span="24">
          <a-form-model-item class="ant-row-flex" label="坐落地址" prop="address">
            <a-input placeholder="请输入坐落地址" v-model="form.address" />
          </a-form-model-item>
        </a-col>
        <a-col :span="24">
          <a-form-model-item class="ant-row-flex" label="土地性质" prop="natureLand">
            <a-radio-group button-style="solid" v-model="form.natureLand">
              <a-radio-button
                :key="item.code"
                :value="item.code"
                v-for="item in codes.natureLand"
              >{{ item.value }}</a-radio-button>
            </a-radio-group>
          </a-form-model-item>
        </a-col>
        <a-col :span="24">
          <a-form-model-item class="ant-row-flex mb-none" label="地理坐标">
            <a-row :gutter="16">
              <a-col :span="12">
                <a-form-model-item prop="axisX">
                  <a-input
                    class="yo-input-prefix-2"
                    disabled
                    placeholder="请在地图上选择坐标"
                    prefix="经度"
                    v-model="form.axisX"
                  />
                </a-form-model-item>
              </a-col>
              <a-col :span="12">
                <a-form-model-item prop="axisY">
                  <a-input
                    class="yo-input-prefix-2"
                    disabled
                    placeholder="请在地图上选择坐标"
                    prefix="纬度"
                    v-model="form.axisY"
                  />
                </a-form-model-item>
              </a-col>
            </a-row>
          </a-form-model-item>
          <a-form-model-item :colon="false" :label="true" class="ant-row-flex">
            <div class="yo-map-container">
              <div class="yo-map--search">
                <a-input-search allow-clear placeholder="请输入关键字" ref="map-search" />
              </div>
              <div class="h-500" ref="map"></div>
            </div>
          </a-form-model-item>
        </a-col>
        <a-col :span="24">
          <a-form-model-item class="ant-row-flex" label="结构类型" prop="structureType">
            <a-radio-group button-style="solid" placeholder="请选择结构类型" v-model="form.structureType">
              <a-radio-button
                :key="item.code"
                :value="item.code"
                v-for="item in codes.houseStructureType"
              >{{ item.value }}</a-radio-button>
            </a-radio-group>
          </a-form-model-item>
        </a-col>
        <a-col :span="12">
          <a-form-model-item class="ant-row-flex" label="抗震等级" prop="aseismicGrade">
            <a-radio-group button-style="solid" v-model="form.aseismicGrade">
              <a-radio-button
                :key="item.code"
                :value="item.code"
                v-for="item in codes.houseSseismicGrade"
              >{{ item.value }}</a-radio-button>
            </a-radio-group>
          </a-form-model-item>
        </a-col>
        <a-col :span="12">
          <a-form-model-item class="ant-row-flex" label="基础情况" prop="baseInfo">
            <a-radio-group button-style="solid" v-model="form.baseInfo">
              <a-radio-button
                :key="item.code"
                :value="item.code"
                v-for="item in codes.houseBaseInfo"
              >{{ item.value }}</a-radio-button>
            </a-radio-group>
          </a-form-model-item>
        </a-col>
        <a-col :span="24">
          <a-form-model-item class="ant-row-flex" label="外墙保温材料" prop="insulationMaterial">
            <a-checkbox-group v-model="form.insulationMaterial">
              <a-checkbox
                :key="item.code"
                :value="item.code"
                class="mb-xs"
                v-for="item in codes.houseInsulationMaterial"
              >{{ item.value }}</a-checkbox>
              <a-input
                class="w-300"
                placeholder="请输入其他外墙保温材料"
                v-if="form.insulationMaterial && form.insulationMaterial.indexOf(codes.houseInsulationMaterial[codes.houseInsulationMaterial.length - 1].code) >= 0"
                v-model="form.keepWarmMaterialRest"
              />
            </a-checkbox-group>
          </a-form-model-item>
        </a-col>
        <a-col :span="24">
          <a-form-model-item class="ant-row-flex" label="外墙墙体材料" prop="wallMaterial">
            <a-checkbox-group v-model="form.wallMaterial">
              <a-checkbox
                :key="item.code"
                :value="item.code"
                class="mb-xs"
                v-for="item in codes.houseWallMaterial"
              >{{ item.value }}</a-checkbox>
            </a-checkbox-group>
          </a-form-model-item>
        </a-col>
        <a-col :span="24">
          <a-form-model-item class="ant-row-flex" prop="fireproofGrade">
            <span slot="label">
              外墙外保温材料
              <br />防火等级
            </span>
            <a-radio-group button-style="solid" v-model="form.fireproofGrade">
              <a-radio-button
                :key="item.code"
                :value="item.code"
                v-for="item in codes.houseFireproofGrade"
              >{{ item.value }}</a-radio-button>
            </a-radio-group>
          </a-form-model-item>
        </a-col>
        <a-col :span="24">
          <a-form-model-item class="ant-row-flex" label="建筑幕墙" prop="curtainWall">
            <a-radio-group button-style="solid" v-model="form.curtainWall">
              <a-radio-button
                :key="item.code"
                :value="item.code"
                v-for="item in codes.houseBuildingCurtainWall"
              >{{ item.value }}</a-radio-button>
            </a-radio-group>
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="有无外墙面砖" prop="faceBrick">
            <a-switch v-model="form.faceBrick" />
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="有无外墙粉刷" prop="whiteWash">
            <a-switch v-model="form.whiteWash" />
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="有无外墙涂料" prop="coating">
            <a-switch v-model="form.coating" />
          </a-form-model-item>
        </a-col>
        <a-col :span="24">
          <a-form-model-item class="ant-row-flex" label="电梯" prop="elevator">
            <a-radio-group button-style="solid" v-model="form.elevator">
              <a-radio-button
                :key="item.code"
                :value="item.code"
                v-for="item in codes.houseElevator"
              >{{ item.value }}</a-radio-button>
            </a-radio-group>
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="竣工日期" prop="completedDate">
            <a-date-picker class="w-100-p" placeholder="请选择竣工日期" v-model="form.completedDate" />
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="设计使用年限" prop="useYear">
            <a-row type="flex">
              <a-col flex="1">
                <a-input-number
                  :min="0"
                  class="w-100-p"
                  placeholder="请输入设计使用年限"
                  v-model="form.useYear"
                />
              </a-col>
              <a-col>
                <span class="yo-addon">年</span>
              </a-col>
            </a-row>
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="总建筑面积" prop="areaCount">
            <a-row type="flex">
              <a-col flex="1">
                <a-input-number
                  :min="0"
                  class="w-100-p"
                  placeholder="请输入总建筑面积"
                  v-model="form.areaCount"
                />
              </a-col>
              <a-col>
                <span class="yo-addon">m²</span>
              </a-col>
            </a-row>
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="总户数" prop="households">
            <a-row type="flex">
              <a-col flex="1">
                <a-input-number
                  :min="0"
                  :step="1"
                  class="w-100-p"
                  placeholder="请输入总户数"
                  v-model="form.households"
                />
              </a-col>
              <a-col>
                <span class="yo-addon">户</span>
              </a-col>
            </a-row>
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="房屋单元数" prop="units">
            <a-row type="flex">
              <a-col flex="1">
                <a-input-number
                  :min="0"
                  :step="1"
                  class="w-100-p"
                  placeholder="请输入房屋单元数"
                  v-model="form.units"
                />
              </a-col>
              <a-col>
                <span class="yo-addon">单元</span>
              </a-col>
            </a-row>
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="每层每单元户数" prop="unitHouseholds">
            <a-row type="flex">
              <a-col flex="1">
                <a-input-number
                  :min="0"
                  :step="1"
                  class="w-100-p"
                  placeholder="请输入每层每单元户数"
                  v-model="form.unitHouseholds"
                />
              </a-col>
              <a-col>
                <span class="yo-addon">户</span>
              </a-col>
            </a-row>
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="建设单位" prop="buildingUnit">
            <a-input placeholder="请输入建设单位" v-model="form.buildingUnit" />
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="建设单位联系人" prop="buildingUnitUser">
            <a-input placeholder="请输入建设单位联系人" v-model="form.buildingUnitUser" />
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="建设单位联系电话" prop="buildingUnitTel">
            <a-input placeholder="请输入建设单位联系电话" v-model="form.buildingUnitTel" />
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="设计单位" prop="desingerUnit">
            <a-input placeholder="请输入设计单位" v-model="form.desingerUnit" />
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="施工单位" prop="constructionUnit">
            <a-input placeholder="请输入施工单位" v-model="form.constructionUnit" />
          </a-form-model-item>
        </a-col>
        <a-col :span="8">
          <a-form-model-item class="ant-row-flex" label="监理单位" prop="monitorUnit">
            <a-input placeholder="请输入监理单位" v-model="form.monitorUnit" />
          </a-form-model-item>
        </a-col>
        <a-col :span="24">
          <a-form-model-item class="ant-row-flex ant-form-inline mb-none" label="建筑层数">
            <a-form-model-item :colon="false" class="ant-row-flex" label="地上" prop="landLevelCount">
              <a-row type="flex">
                <a-col flex="1">
                  <a-input-number
                    :min="0"
                    :step="1"
                    class="w-100-p"
                    placeholder="请输入地上层"
                    v-model="form.landLevelCount"
                  />
                </a-col>
                <a-col>
                  <span class="yo-addon">层</span>
                </a-col>
              </a-row>
            </a-form-model-item>
            <a-form-model-item
              :colon="false"
              class="ant-row-flex"
              label="地下"
              prop="undergroundLevelCount"
            >
              <a-row type="flex">
                <a-col flex="1">
                  <a-input-number
                    :min="0"
                    :step="1"
                    class="w-100-p"
                    placeholder="请输入地下层"
                    v-model="form.undergroundLevelCount"
                  />
                </a-col>
                <a-col>
                  <span class="yo-addon">层</span>
                </a-col>
              </a-row>
            </a-form-model-item>
            <a-form-model-item :colon="false" class="ant-row-flex" label="总共" prop="levelCount">
              <a-row type="flex">
                <a-col flex="1">
                  <a-input-number
                    :min="0"
                    :step="1"
                    class="w-100-p"
                    disabled
                    placeholder="请输入总层数"
                    v-model="form.levelCount"
                  />
                </a-col>
                <a-col>
                  <span class="yo-addon">层</span>
                </a-col>
              </a-row>
            </a-form-model-item>
          </a-form-model-item>
          <a-form-model-item class="ant-row-flex ant-form-inline" label="其中">
            <a-form-model-item class="ant-row-flex">
              <a-row type="flex">
                <a-col>
                  <span class="yo-addon">地上第</span>
                </a-col>
                <a-col flex="1">
                  <a-form-model-item class="mr-none" prop="landBusiness1">
                    <a-input-number
                      :min="0"
                      :step="1"
                      placeholder="几"
                      v-model="form.landBusiness1"
                    />
                  </a-form-model-item>
                </a-col>
                <a-col>
                  <span class="yo-addon">层，至</span>
                </a-col>
                <a-col flex="1">
                  <a-form-model-item class="mr-none" prop="landBusiness2">
                    <a-input-number
                      :min="0"
                      :step="1"
                      placeholder="几"
                      v-model="form.landBusiness2"
                    />
                  </a-form-model-item>
                </a-col>
                <a-col>
                  <span class="yo-addon">层为商业用房</span>
                </a-col>
              </a-row>
            </a-form-model-item>
            <a-form-model-item class="ant-row-flex">
              <a-row type="flex">
                <a-col>
                  <span class="yo-addon">地上</span>
                </a-col>
                <a-col flex="1">
                  <a-form-model-item class="mr-none" prop="landBikeshed1">
                    <a-input-number
                      :min="0"
                      :step="1"
                      placeholder="几"
                      v-model="form.landBikeshed1"
                    />
                  </a-form-model-item>
                </a-col>
                <a-col>
                  <span class="yo-addon">层为车棚层</span>
                </a-col>
              </a-row>
            </a-form-model-item>
            <a-form-model-item class="ant-row-flex">
              <a-row type="flex">
                <a-col>
                  <span class="yo-addon">地上第</span>
                </a-col>
                <a-col flex="1">
                  <a-form-model-item class="mr-none" prop="landResidence1">
                    <a-input-number
                      :min="0"
                      :step="1"
                      placeholder="几"
                      v-model="form.landResidence1"
                    />
                  </a-form-model-item>
                </a-col>
                <a-col>
                  <span class="yo-addon">层，至</span>
                </a-col>
                <a-col flex="1">
                  <a-form-model-item class="mr-none" prop="landResidence2">
                    <a-input-number
                      :min="0"
                      :step="1"
                      placeholder="几"
                      v-model="form.landResidence2"
                    />
                  </a-form-model-item>
                </a-col>
                <a-col>
                  <span class="yo-addon">层为住宅</span>
                </a-col>
              </a-row>
            </a-form-model-item>
          </a-form-model-item>
        </a-col>
      </a-row>
    </a-spin>
  </a-form-model>
</template>
<script>
/* 表单内容默认值 */
const defaultForm = {
  /* ... */
  address: '',
  axisX: '',
  axisY: '',

  curtainWall: '1',
  faceBrick: true,
  whiteWash: true,
  coating: true,
};

export default {
  props: ['param', 'frame'],

  data() {
    return {
      labelCol: { flex: '150px' },
      wrapperCol: { flex: '1' },

      /** 表单数据 */
      form: {},
      /** 验证格式 */
      rules: {
        /* ... */
        projectName: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
        buildingName: [{ required: true, message: '请输入幢名称', trigger: 'blur' }],
        address: [{ required: true, message: '请输入坐落地址', trigger: 'blur' }],
        natureLand: [{ required: true, message: '请选择土地性质', trigger: 'blur' }],
        axisX: [{ required: true, message: '请在地图上选择坐标', trigger: 'blur' }],
        axisY: [{ required: true, message: '请在地图上选择坐标', trigger: 'blur' }],
        structureType: [{ required: true, message: '请选择结构类型', trigger: 'blur' }],
        aseismicGrade: [{ required: true, message: '请选择抗震等级', trigger: 'blur' }],
        baseInfo: [{ required: true, message: '请选择基础情况', trigger: 'blur' }],
        curtainWall: [{ required: true, message: '请选择建筑幕墙', trigger: 'blur' }],
        elevator: [{ required: true, message: '请选择电梯', trigger: 'blur' }],
        completedDate: [{ required: true, message: '请选择竣工日期', trigger: 'blur' }],
        useYear: [{ required: true, message: '请输入设计使用年限', trigger: 'blur' }],
        areaCount: [{ required: true, message: '请输入总建筑面积', trigger: 'blur' }],
        households: [{ required: true, message: '请输入总户数', trigger: 'blur' }],
        units: [{ required: true, message: '请输入房屋单元数', trigger: 'blur' }],
        unitHouseholds: [{ required: true, message: '请输入每层每单元户数', trigger: 'blur' }],
        buildingUnit: [{ required: true, message: '请输入建设单位', trigger: 'blur' }],
        buildingUnitUser: [{ required: true, message: '请输入建设单位联系人', trigger: 'blur' }],
        buildingUnitTel: [{ required: true, message: '请输入建设单位联系电话', trigger: 'blur' }],
        desingerUnit: [{ required: true, message: '请输入设计单位', trigger: 'blur' }],
        constructionUnit: [{ required: true, message: '请输入施工单位', trigger: 'blur' }],
        landLevelCount: [{ required: true, message: '请输入地上层', trigger: 'blur' }],
        undergroundLevelCount: [{ required: true, message: '请输入地下层', trigger: 'blur' }],
      },

      /** 加载异步数据状态 */
      loading: false,

      /** 其他成员属性 */
      /* ... */
      codes: {
        natureLand: [],
        houseStructureType: [],
        houseSseismicGrade: [],
        houseBaseInfo: [],
        houseInsulationMaterial: [],
        houseWallMaterial: [],
        houseFireproofGrade: [],
        houseBuildingCurtainWall: [],
        houseElevator: [],
      },
    };
  },

  watch: {
    'form.insulationMaterial'(value, oldValue) {
      // 选中"无"时全不选,反之取消选择"无"
      if (value.indexOf('0') >= 0 && oldValue.indexOf('0') === -1) {
        this.form.insulationMaterial = ['0'];
      } else if (value.indexOf('0') >= 0 && value.length > 1) {
        this.form.insulationMaterial.splice(value.indexOf('0'), 1);
      }
    },

    'form.curtainWall'(value) {
      this.frame.onTogglePane(!!+value, 'curtainWall');
    },
    'form.faceBrick'(value) {
      this.frame.onTogglePane(value, 'faceBrick');
    },
    'form.whiteWash'(value) {
      this.frame.onTogglePane(value, 'whiteWash');
    },
    'form.coating'(value) {
      this.frame.onTogglePane(value, 'coating');
    },
  },

  async created() {
    await this.onInit();
    this.onFillData();
  },

  mounted() {
    this.onMapInit();
  },

  beforeDestroy() {
    if (this.map) this.map.destroy();
  },

  methods: {
    /**
     * 必要的方法
     * 在打开编辑页时允许填充数据
     */
    onFillData() {
      /** 将默认数据覆盖到form */
      const record = this.param && this.param.record;

      this.form = this.$_.cloneDeep({
        ...defaultForm,
        ...record,
        /** 在此处添加其他默认数据转换 */
        /* ... */
      });
    },

    /**
     * 必要方法
     * 验证表单并获取表单数据
     */
    onGetData() {
      return new Promise((reslove, reject) => {
        this.$refs.form.validate((valid) => {
          if (valid) {
            const record = this.$_.cloneDeep(this.form);

            /** 验证通过后可以对数据进行转换得到想要提交的格式 */
            /* ... */

            reslove(record);
          } else {
            reject();
          }
        });
      });
    },

    /**
     * 必要的方法
     * 在外部窗口进行保存时调用表单验证
     */
    onValidate(callback) {
      this.$refs.form.validate(callback);
    },

    /**
     * 必要的方法
     * 在外部窗口关闭或重置时对表单验证进行初始化
     */
    onResetFields() {
      setTimeout(() => {
        this.$refs.form.resetFields();

        /** 在这里可以初始化当前组件中其他属性 */
        /* ... */
      }, 300);
    },

    /**
     * 必要方法
     * 加载当前表单中所需要的异步数据
     */
    async onInit() {
      this.loading = true;
      /** 可以在这里await获取一些异步数据 */
      /* ... */
      await this.onLoadCodes();
      this.loading = false;
    },

    /** 当前组件的其他方法 */
    /* ... */
    onLoadCodes() {
      return this.$api
        .sysDictTypeDropDowns({
          code: [
            'dic_nature_land',
            'dic_house_structure_type',
            'dic_house_aseismic_grade',
            'dic_house_base_info',
            'dic_house_insulation_material',
            'dic_house_wall_material',
            'dic_house_fireproof_grade',
            'dic_house_building_curtain_wall',
            'dic_house_elevator',
          ],
        })
        .then(
          ({
            data: {
              dic_nature_land,
              dic_house_structure_type,
              dic_house_aseismic_grade,
              dic_house_base_info,
              dic_house_insulation_material,
              dic_house_wall_material,
              dic_house_fireproof_grade,
              dic_house_building_curtain_wall,
              dic_house_elevator,
            },
          }) => {
            this.codes = {
              natureLand: dic_nature_land,
              houseStructureType: dic_house_structure_type,
              houseSseismicGrade: dic_house_aseismic_grade,
              houseBaseInfo: dic_house_base_info,
              houseInsulationMaterial: dic_house_insulation_material,
              houseWallMaterial: dic_house_wall_material,
              houseFireproofGrade: dic_house_fireproof_grade,
              houseBuildingCurtainWall: dic_house_building_curtain_wall,
              houseElevator: dic_house_elevator,
            };
          }
        );
    },

    onMapInit() {
      const city = '宁波市';

      const district = new AMap.DistrictSearch({
        subdistrict: 0,
        extensions: 'all',
        level: 'city',
      });

      district.search(city, (status, result) => {
        const bounds = result.districtList[0].boundaries;
        const mask = [];
        for (let i = 0; i < bounds.length; i += 1) {
          mask.push([bounds[i]]);
        }

        // 挂载map到this,但不监听
        this.map = new AMap.Map(this.$refs.map, { city, viewMode: '3D', mask });

        const geocoder = new AMap.Geocoder({ city });

        let marker;
        const setMarker = (position) => {
          if (marker) {
            marker.setPosition(position);
          } else {
            marker = new AMap.Marker({
              map: this.map,
              icon: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
              position,
              offset: new AMap.Pixel(-13, -30),
            });
          }

          geocoder.getAddress(position, (status, result) => {
            if (status === 'complete' && result.regeocode) {
              this.onSetPosition(result.regeocode.formattedAddress, position);
            } else {
              console.error('根据经纬度查询地址失败');
            }
          });
        };

        this.map.on('click', (e) => {
          setMarker(e.lnglat);
        });

        const auto = new AMap.AutoComplete({
          input: this.$refs['map-search'].$el.querySelector('input'),
          city,
          citylimit: true,
        });

        const placeSearch = new AMap.PlaceSearch({
          city,
          citylimit: true,
          pageSize: 1,
        });

        auto.on('select', ({ poi: { name: keywords, adcode } }) => {
          this.map.clearMap();
          marker = null;
          placeSearch.search(keywords, (status, result) => {
            const {
              poiList: { pois },
            } = result;
            pois.forEach((p) => {
              setMarker(p.location);
            });

            this.map.setFitView();
          });
        });

        for (let i = 0; i < bounds.length; i += 1) {
          new AMap.Polyline({
            path: bounds[i],
            strokeColor: '#ccc',
            strokeWeight: 4,
            map: this.map,
          });
        }
      });
    },

    onSetPosition(address, { lng, lat }) {
      Object.assign(this.form, {
        address,
        axisX: lng.toString(),
        axisY: lat.toString(),
      });
    },
  },
};
</script>