<template>
  <div class="address" @touchmove.stop>
    <div class="address-box">
      <div class="btns">
        <div class="close" @click="close">取消</div>
        <div class="change" @click="sub">确定</div>
      </div>
      <div class="list-box">
        <div class="select-box"></div>
        <div class="city-item province">
          <ul
            class="list"
            :style="provinceStyle"
            @touchstart="touchStart($event, 'province')"
            @touchmove="touchMove($event, 'province')"
            @touchend="touchEnd($event, 'province')"
          >
            <li
              class="item"
              :class="{ 'z-active': item.val == changeCity.province }"
              v-for="(item, index) in provinceList"
              :key="index"
            >
              {{ item.name }}
            </li>
          </ul>
        </div>
        <div class="city-item city">
          <ul
            class="list"
            :style="cityStyle"
            @touchstart="touchStart($event, 'city')"
            @touchmove="touchMove($event, 'city')"
            @touchend="touchEnd($event, 'city')"
          >
            <li
              class="item"
              :class="{ 'z-active': item.val == changeCity.city }"
              v-for="(item, index) in cityList"
              :key="index"
            >
              {{ item.name }}
            </li>
          </ul>
        </div>
        <div class="city-item area">
          <ul
            class="list"
            :style="areaStyle"
            @touchstart="touchStart($event, 'area')"
            @touchmove="touchMove($event, 'area')"
            @touchend="touchEnd($event, 'area')"
          >
            <li
              class="item"
              :class="{ 'z-active': item.val == changeCity.area }"
              v-for="(item, index) in areaList"
              :key="index"
            >
              {{ item.name }}
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import cityData from './js/city';

export default {
  name: 'cityPicker',
  props: {
    address: {
      default() {
        return '浙江省-杭州市-西湖区';
      }
    }
  },
  data() {
    return {
      cityData: cityData,
      provinceStyle: {
        transform: 'translate3d(0,0,0)'
      },
      cityStyle: {
        transform: 'translate3d(0,0,0)'
      },
      areaStyle: {
        transform: 'translate3d(0,0,0)'
      },
      changeCity: {
        // 对应的城市1d
        province: '',
        city: '',
        area: ''
      },
      pageY: 0,
      translateY: 0
    };
  },
  computed: {
    provinceList() {
      const province = this.cityData[100000];
      const arr = [];
      for (const key in province) {
        if (province[key]) {
          arr.push({
            val: key,
            name: province[key]
          });
        }
      }
      return arr;
    },
    cityList() {
      const city = this.cityData[this.changeCity.province] || {};
      const arr = [];
      for (const key in city) {
        if (city[key]) {
          arr.push({
            val: key,
            name: city[key]
          });
        }
      }
      return arr;
    },
    areaList() {
      const area = this.cityData[this.changeCity.city] || {};
      const arr = [];
      for (const key in area) {
        if (area[key]) {
          arr.push({
            val: key,
            name: area[key]
          });
        }
      }
      return arr;
    }
  },
  watch: {
    cityList() {
      this.cityStyle.transform = 'translate3d(0,0,0)';
      this.changeCity.city = this.cityList[0] ? this.cityList[0].val : 0;
    },
    areaList() {
      this.areaStyle.transform = 'translate3d(0,0,0)';
      this.changeCity.area = this.areaList[0] ? this.areaList[0].val : 0;
    },
    address() {
      this.$nextTick(() => {
        this.initCity();
      });
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.initCity();
    });
  },
  methods: {
    initCity() {
      this.changeCity.province = '';
      this.changeCity.city = '';
      this.changeCity.area = '';
      const address = this.address || '浙江省-杭州市-西湖区';
      const arr = address.split('-');
      for (let i = 0; i < this.provinceList.length; i++) {
        if (this.provinceList[i].name === arr[0]) {
          this.changeCity.province = this.provinceList[i].val;
          this.scrollCity('province');
          break;
        }
      }
      for (let i = 0; i < this.cityList.length; i++) {
        if (this.cityList[i].name === arr[1]) {
          this.changeCity.city = this.cityList[i].val;
          this.scrollCity('city');
          break;
        }
      }
      for (let i = 0; i < this.areaList.length; i++) {
        if (this.areaList[i].name === arr[2]) {
          this.changeCity.area = this.areaList[i].val;
          this.scrollCity('area');
          break;
        }
      }
    },
    scrollCity(type) {
      let y = 0;
      switch (type) {
        case 'province':
          for (let i = 0; i < this.provinceList.length; i++) {
            if (this.provinceList[i].val === this.changeCity.province) {
              y = -(i * 40);
            }
          }
          this.provinceStyle.transform = `translate3d(0,${y}px,0)`;
          break;
        case 'city':
          for (let i = 0; i < this.cityList.length; i++) {
            if (this.cityList[i].val === this.changeCity.city) {
              y = -(i * 40);
            }
          }
          this.cityStyle.transform = `translate3d(0,${y}px,0)`;
          break;
        case 'area':
          for (let i = 0; i < this.areaList.length; i++) {
            if (this.areaList[i].val === this.changeCity.area) {
              y = -(i * 40);
            }
          }
          this.areaStyle.transform = `translate3d(0,${y}px,0)`;
          break;
        default:
          break;
      }
    },
    touchStart(e, type) {
      e.preventDefault();
      this.pageY = e.targetTouches[0].pageY;
      switch (type) {
        case 'province':
          this.translateY = parseInt(
            this.provinceStyle.transform.slice(
              this.provinceStyle.transform.indexOf(',') + 1,
              this.provinceStyle.transform.lastIndexOf(',')
            ),
            10
          );
          break;
        case 'city':
          this.translateY = parseInt(
            this.cityStyle.transform.slice(
              this.cityStyle.transform.indexOf(',') + 1,
              this.cityStyle.transform.lastIndexOf(',')
            ),
            10
          );
          break;
        case 'area':
          this.translateY = parseInt(
            this.areaStyle.transform.slice(
              this.areaStyle.transform.indexOf(',') + 1,
              this.areaStyle.transform.lastIndexOf(',')
            ),
            10
          );
          break;
        default:
          break;
      }
    },
    touchMove(e, type) {
      e.preventDefault();
      const y = e.targetTouches[0].pageY - this.pageY;
      this.pageY = e.targetTouches[0].pageY;
      this.translateY = y + this.translateY;
      switch (type) {
        case 'province':
          this.provinceStyle.transform = `translate3d(0,${this.translateY}px,0)`;
          break;
        case 'city':
          this.cityStyle.transform = `translate3d(0,${this.translateY}px,0)`;
          break;
        case 'area':
          this.areaStyle.transform = `translate3d(0,${this.translateY}px,0)`;
          break;
        default:
          break;
      }
    },
    touchEnd(e, type) {
      e.preventDefault();
      let y = 0;
      let max = 0;
      if (this.translateY % 40 > 0.5) {
        y = parseInt(this.translateY / 40 + 1, 10) * 40;
      } else {
        y = parseInt(this.translateY / 40, 10) * 40;
      }
      switch (type) {
        case 'province':
          max = -(this.provinceList.length - 1) * 40;
          y = y > 0 ? 0 : y < max ? max : y;
          this.changeCity.province = this.provinceList[-parseInt(y / 40, 10)]
            ? this.provinceList[-parseInt(y / 40, 10)].val
            : 0;
          this.provinceStyle.transform = `translate3d(0,${y}px,0)`;
          break;
        case 'city':
          max = -(this.cityList.length - 1) * 40;
          y = y > 0 ? 0 : y < max ? max : y;
          this.changeCity.city = this.cityList[-parseInt(y / 40, 10)]
            ? this.cityList[-parseInt(y / 40, 10)].val
            : 0;
          this.cityStyle.transform = `translate3d(0,${y}px,0)`;
          break;
        case 'area':
          max = -(this.areaList.length - 1) * 40;
          y = y > 0 ? 0 : y < max ? max : y;
          this.changeCity.area = this.areaList[-parseInt(y / 40, 10)]
            ? this.areaList[-parseInt(y / 40, 10)].val
            : 0;
          this.areaStyle.transform = `translate3d(0,${y}px,0)`;
          break;
        default:
          break;
      }
    },
    close() {
      this.$emit('input', false);
    },
    sub() {
      const province = this.cityData[100000][this.changeCity.province] || '';
      const city = this.cityData[this.changeCity.province][this.changeCity.city] || '';
      const area = this.cityData[this.changeCity.city][this.changeCity.area] || '';
      const address = `${province}-${city}-${area}`;
      this.$emit('setCity', false, {
        address: address,
        province: province,
        city: city,
        area: area
      });
    }
  }
};
</script>

<style lang="less" scoped>
.address {
  .address-box {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    background-color: #f7f7f7;

    .btns {
      padding: 5px 15px;
      height: 45px;
      line-height: 35px;
      background-color: #f0f1f3;
      font-size: 16px;

      .close {
        padding: 0 15px;
        color: #999;
        float: left;
      }
      .change {
        padding: 0 15px;
        color: #f14936;
        float: right;
      }
    }
    .list-box {
      position: relative;
      display: flex;
      height: 200px;
      font-size: 16px;
      text-align: center;

      .select-box {
        position: absolute;
        left: 0;
        top: 80px;
        width: 100%;
        height: 40px;
        border-top: 1px solid #efefef;
        border-bottom: 1px solid #efefef;
      }
      .city-item {
        position: relative;
        flex: 1;
        padding: 0 5px;
        overflow: hidden;

        .list {
          position: absolute;
          top: 80px;
          left: 0;
          width: 100%;
          overflow: auto;
          transform: translate3d(0, 0, 0);
          transition: transform 0.18s ease-out;

          .item {
            height: 40px;
            line-height: 40px;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            color: #d4d4d4;

            &.z-active {
              color: #666;
            }
          }
        }
      }
    }
  }
}
</style>
