<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- Created by Tw93 on 17/12/27. -->
<!--A City -->

<template>
  <div class="wxc-city" ref="city" :style="cityExtendStyle">
    <wxc-searchbar ref="wxc-searchbar"
                   v-bind="mergeInputConfig"
                   @wxcSearchbarInputOnInput="onInput"
                   @wxcSearchbarInputReturned="onSubmit"
                   @wxcSearchbarCancelClicked="onCancel"></wxc-searchbar>

    <wxc-tab ref="wxc-tab"
             v-if="showTab"
             @wxcTabSwitch="onTabSwitch"></wxc-tab>

    <wxc-indexlist :normal-list="normalList"
                   :hot-list-config="hotListConfig"
                   :nav-style="{ top: '24px'}"
                   :height="listHeight"
                   :show-index="showIndex"
                   :only-show-list="!showNavHeader || onlyShowList"
                   :city-location-config="currentCityLocationConfig"
                   @wxcIndexlistItemClicked="onItemClick"></wxc-indexlist>

    <wxc-result type="noGoods"
                :wrap-style="{top:'84px'}"
                :show="true"
                :customSet="result"
                v-if="showError"></wxc-result>
  </div>
</template>

<script>
  import defaultSourceData from './default-data';
  import * as Util from './util';
  import Utils from '../utils';
  import wxcTab from './tab.vue';
  import WxcSearchbar from '../wxc-searchbar'
  import WxcResult from '../wxc-result';
  import WxcIndexlist from '../wxc-indexlist';

  export default {
    components: { wxcTab, WxcSearchbar, WxcResult, WxcIndexlist },
    props: {
      animationType: {
        type: String,
        default: 'push'
      },
      inputConfig: {
        type: Object,
        default: () => ({})
      },
      sourceData: {
        type: Object,
        default: () => defaultSourceData
      },
      cityStyleType: {
        type: String,
        default: 'list'
      },
      currentLocation: String,
      cityHeight: {
        type: Number,
        default: 0
      },
      showTab: {
        type: Boolean,
        default: false
      },
      showIndex: {
        type: Boolean,
        default: true
      },
      showNavHeader: {
        type: Boolean,
        default: true
      }
    },
    data: () => ({
      tId: null,
      saveDefaultSourceData: {},
      cityData: {},
      onlyShowList: false,
      result: {
        noGoods: {
          pic: 'https://img.alicdn.com/tfs/TB1SpPHkf2H8KJjy0FcXXaDlFXa-200-200.png',
          button: '',
          content: '搜索无结果'
        }
      }
    }),
    created () {
      this.cityData = this.sourceData
      this.saveDefaultSourceData = this.sourceData
    },
    computed: {
      cityExtendStyle () {
        return Utils.uiStyle.pageTransitionAnimationStyle(this.animationType)
      },
      currentCityLocationConfig () {
        if (this.currentLocation) {
          return {
            type: this.cityStyleType,
            title: '定位',
            list: [
              { name: this.currentLocation, isLocation: true }
            ]
          }
        } else {
          return {};
        }
      },
      normalList () {
        return Util.getCities(this.cityData.cities)
      },
      hotListConfig () {
        return {
          type: this.cityStyleType,
          title: '热门',
          list: Util.getCities((this.cityData.hotCity))
        }
      },
      showError () {
        const { normalList, hotListConfig } = this;
        return (normalList && normalList.length < 1) && (hotListConfig && hotListConfig.list && hotListConfig.list.length < 1)
      },
      listHeight () {
        // 兼容去头逻辑
        let pageHeight = Utils.env.getPageHeight();

        const { cityHeight } = this;
        if (cityHeight && !isNaN(cityHeight) && cityHeight > 0) {
          pageHeight = cityHeight;
        }
        // searchInput 84
        const tabHeight = this.showTab ? 90 : 0;
        return pageHeight - 84 - tabHeight;
      },
      mergeInputConfig () {
        return {
          autofocus: false,
          alwaysShowCancel: true,
          placeholder: '中文/拼音/首字母',
          ...this.inputConfig
        }
      }
    },
    methods: {
      onTabSwitch (e) {
        this.$emit('wxcTabSwitch', e);
      },
      switchTab (i = 0) {
        setTimeout(() => {
          this.$refs['wxc-tab'].switchTab(i)
        }, 100);
      },
      onItemClick (e) {
        this.$refs['wxc-searchbar'].autoBlur();
        this.show(false);
        this.$emit('wxcCityItemSelected', { item: e.item });
      },
      onInput (e) {
        clearTimeout(this.tId);
        const { cities } = this.cityData;
        const { value } = e;
        if (value !== '' && cities && cities.length > 0) {
          const queryData = Util.query(cities, String(value).trim());
          this.cityData = {
            cities: queryData,
            hotCity: []
          };
          this.onlyShowList = true;
        } else {
          this.cityData = this.saveDefaultSourceData;
          this.onlyShowList = false;
        }
        this.tId = setTimeout(() => {
          this.$emit('wxcCityOnInput', {
            value: e.value
          });
        }, 300);
      },
      onCancel () {
        this.autoBlur();
        this.show(false);
        this.$emit('wxcCityCanceled', {});
      },
      onSubmit (e) {
        this.autoBlur();
        this.$emit('wxcCityOnKeyUpEnter', { value: e.value });
      },
      autoBlur () {
        const inputRef = this.$refs['wxc-searchbar'];
        inputRef && inputRef.autoBlur();
      },
      show (status = true, callback = null) {
        const ref = this.$refs.city
        if (this.animationType === 'push') {
          Utils.animation.pageTransitionAnimation(ref, `translateX(${status ? -750 : 750}px)`, status, callback)
        } else if (this.animationType === 'model') {
          Utils.animation.pageTransitionAnimation(ref, `translateY(${status ? -Utils.env.getScreenHeight() : Utils.env.getScreenHeight()}px)`, status, callback)
        }
      }
    }
  };
</script>

<style scoped>
  .wxc-city {
    position: fixed;
    width: 750px;
    background-color: #F2F3F4;
  }
</style>
