import { Component, Mixins, Prop, Watch } from 'vue-property-decorator';
import { Getter, State } from 'vuex-class';
import { reduce, ceil, subtract, divide, pick, cloneDeep, pickBy } from 'lodash';
import ContextMenuMixin from '@editor/mixins/contextMenu.mixin';
import DynamicFormMixin from './component/mixins/dynamicForm.mixin';
import Upload from './component/Upload/index.vue';
import ColorSelector from './component/ColorSelector/index.vue';
import DiscountGoodsSelector from './component/DiscountGoodsSelector/index.vue';
import SnapUpActivitySelector from './component/SnapUpActivitySelector/index.vue';
import VerticalAdStyleSelector from './component/VerticalAdStyleSelector/index.vue';
import CategoryTypeSelector from './component/CategoryTypeSelector/index.vue';
import CategorySelector from './component/CategorySelector/index.vue';
import BatchGoodsSelector from './component/BatchGoodsSelector/index.vue';
import DiscountGoodsSelectorV2 from './component/DiscountGoodsSelectorV2/index.vue';
import BaseSelect from './component/BaseSelect/index.vue';
import ComponentSelect from './component/ComponentSelect/index.vue';
import FormList from './component/FormList/index.vue';
import GoodsTableModal from './component/GoodsTableModal/index.vue';
import CouponTableModal from './component/CouponTableModal/index.vue';
import Textarea from './component/Textarea/index.vue';
import Number from './component/Number/index.vue';
import ColumnSelector from './component/ColumnSelector/index.vue';
import { resizeDiv, getStyle } from '@/service/utils.service';
import { getAllScheme } from '../../../store/modules/editor/scheme';
import EventBus from '@service/eventBus.service';

const allComponentsMap = getAllScheme();
@Component({ components: {
  Upload,
  ColorSelector,
  BaseSelect,
  FormList,
  Textarea,
  Number,
  ComponentSelect,
  GoodsTableModal,
  CouponTableModal,
  ColumnSelector,
  DiscountGoodsSelector,
  SnapUpActivitySelector,
  CategoryTypeSelector,
  CategorySelector,
  VerticalAdStyleSelector,
  BatchGoodsSelector,
  DiscountGoodsSelectorV2
}, name: 'DynamicForm' })
export default class DynamicForm extends Mixins(ContextMenuMixin, DynamicFormMixin) {
  @State(state => state.editor.curEleIndex) curEleIndex;
  @State(state => state.editor.curChildIndex) curChildIndex;
  @Getter('pageData') pageData;

  prevCommonStyle: object = {
    paddingTop: 0, paddingBottom: 0, paddingLeft: 0, paddingRight: 0
  };
  form: object = {};
  currentSchame: object[] = [];
  styleSchame: object = {
    curEle: [
      {
        label: '定位',
        list: [
          {
            content: '上对齐',
            icon: 'arrow-up-c',
            args: 'top'
          },
          {
            content: '右对齐',
            icon: 'arrow-right-c',
            args: 'right'
          },
          {
            content: '下对齐',
            icon: 'arrow-down-c',
            args: 'bottom'
          },
          {
            content: '左对齐',
            icon: 'arrow-left-c',
            args: 'left'
          },
          {
            content: '垂直居中',
            icon: 'android-film',
            args: 'vertical'
          },
          {
            content: '水平居中',
            icon: 'android-film',
            args: 'horizontal'
          },
        ]
      },
      {
        label: '位置'
      },
      {
        label: '尺寸',
        list: [
          {
            content: '全屏',
            icon: 'arrow-resize',
            args: 'full'
          },
          {
            content: '宽100%',
            icon: 'arrow-swap',
            args: 'width'
          },
          {
            content: '高100%',
            icon: 'arrow-swap',
            args: 'height'
          },
        ]
      },
      {
        label: '宽高'
      },
      {
        label: '背景图片'
      },
      {
        label: '背景颜色'
      }
    ],
    curChild: [
      {
        label: '容器尺寸',
        list: [
          {
            content: '全屏',
            icon: 'arrow-resize',
            args: [667, 375],
          },
          {
            content: '根据背景图片调整宽高',
            icon: 'image',
            args: [667, 375, 'image'],
          },
          {
            content: '根据元素默认尺寸调整宽高',
            icon: 'stop',
            args: ['', '', 'element'],
          },
          {
            content: '宽100%',
            icon: 'arrow-swap',
            args: [null, 375]
          },
          {
            content: '高100%',
            icon: 'arrow-swap',
            args: [667, null]
          }
        ]
      },
      {
        label: '容器宽高'
      },
      {
        label: '背景图片'
      },
      {
        label: '背景颜色'
      },
      {
        label: '上边距',
        key: 'paddingTop'
      },
      {
        label: '下边距',
        key: 'paddingBottom'
      },
      {
        label: '左边距',
        key: 'paddingLeft'
      },
      {
        label: '右边距',
        key: 'paddingRight'
      },
    ]
  };

  get curElement() {
    return this.getCurElement();
  }

  get point() {
    return this.curEleIndex || this.curEleIndex === 0 ? cloneDeep(this.pageData.elements[this.curEleIndex]?.point) : { h: 0, w: 0 };
  }

  get commonStyle() {
    let rs = { backgroundColor: '', backgroundImage: '', paddingTop: 0, paddingBottom: 0, paddingLeft: 0, paddingRight: 0 };
    if (this.curEleIndex || this.curEleIndex === 0) {
      if (this.curChildIndex || this.curChildIndex === 0) {
        rs = cloneDeep({ ...rs, ...this.pageData.elements[this.curEleIndex].child[this.curChildIndex].commonStyle });
      } else {
        rs = cloneDeep({ ...rs, ...this.pageData.elements[this.curEleIndex].commonStyle });
      }
    }
    // console.log('commonStyle', rs);
    return rs;
  }

  get hasGroup() {
    return this.currentSchame.schame?.some(v => v.title);
  }

  get curFormKey() {
    const keys = [];
    this.currentSchame?.forEach(schame => {
      if (schame.children) {
        schame.children.forEach(child => {
          keys.push(child.key);
        });
      } else {
        keys.push(schame.key);
      }
    });
    return keys;
  }

  get eleName() {
    let result = '';
    if (!this.curChildIndex && this.curChildIndex !== 0) {
      result = this.pageData?.elements[this.curEleIndex]?.name ?? '';
    }
    return result;
  }

  get isSelected() {
    return this.curChildIndex || this.curChildIndex === 0 || this.curEleIndex || this.curEleIndex === 0;
  }

  get childSelected() {
    return this.curChildIndex || this.curChildIndex === 0;
  }

  get parentSelected() {
    return (this.curEleIndex || this.curEleIndex === 0) && !this.curChildIndex && this.curChildIndex !== 0;
  }

  @Watch('curEleIndex', { immediate: true })
  onCurEleIndexChange(newVal) {
    this.setForm(newVal, 'curEleIndex');
  }

  @Watch('curChildIndex', { immediate: true })
  onCurChildIndexChange(newVal) {
    this.setForm(newVal, 'curChildIndex');
  }

  getCurElement() {
    let element = {};
    if (this.curEleIndex !== null) {
      if (this.curChildIndex !== null && this.pageData.elements[this.curEleIndex]) {
        element = this.pageData.elements[this.curEleIndex].child[this.curChildIndex];
      } else {
        element = this.pageData.elements[this.curEleIndex];
      }
    }
    this.currentSchame = allComponentsMap[element.name] || [];
    return element;
  }

  setForm(newVal, type) {
    this.form = { id: `${type}${newVal}` };
    const element = this.getCurElement();
    this.currentSchame?.forEach(schame => {
      if (schame.children) {
        schame.children.forEach(child => {
          this.$set(this.form, child.key, element.props[child.key]);
        });
      } else {
        this.$set(this.form, schame.key, element.props[schame.key]);
      }
    });
    // console.log('setForm', this.form);
  }

  // 监听form变化, 更新pageData
  @Watch('form', { immediate: true, deep: true })
  onFormChange(newVal, oldVal) {
    // console.log('onFormChange', newVal?.id, oldVal?.id);
    if (newVal?.id !== oldVal?.id) { return; }
    const params = pick(this.form, this.curFormKey);
    this.$nextTick(() => {
      const element = this.pageData.elements[this.curEleIndex];
      // swiper refresh 后会自动调整
      if (element.name !== 'cs-guide-cube') {
        this.adjustHeight();
      }
    });
    this.$emit('modProps', params, 'component');
  }

  updatePoint(value, key) {
    // console.log('updatePoint', this.point);
    const elements = this.pageData.elements[this.curEleIndex];
    this.updatePageInfo({ containerIndex: this.curEleIndex, data: { ...elements, point: { ...elements.point, ...this.point  } } });
  }

  updateStyle(value, key) {
    // console.log('updateCommonStyle', this.commonStyle);
    const elements = this.pageData.elements[this.curEleIndex];
    // this.updatePageInfo({ containerIndex: this.curEleIndex, data: { ...elements, commonStyle: { ...elements.commonStyle, ...this.commonStyle  } } });
    this.updateCommonStyle({ containerIndex: this.curEleIndex, childIndex: this.curChildIndex, data: this.commonStyle });
  }

  getDataFromProps() {
    if (this.curEleIndex || this.curEleIndex === 0) {
      this.point = this.pageData.elements[this.curEleIndex]?.point || this.point;
      this.commonStyle = Object.assign({}, initialCommonStyle, this.pageData.elements[this.curEleIndex].commonStyle);
      if (this.curChildIndex || this.curChildIndex === 0) {
        this.commonStyle = Object.assign({}, this.pageData.elements[this.curEleIndex].child[this.curChildIndex].commonStyle);
      }
    }
  }

  resizedEvent(h, w, responsive) {
    const elements = this.pageData.elements[this.curEleIndex];
    if (responsive) {
      if (responsive === 'image' && elements.commonStyle.backgroundImage) {
        // if (elements.name === 'freedom-container') {
        resizeDiv(elements.commonStyle.backgroundImage, 667, 375, (imgHeight) => {
          this.updatePageInfo({ containerIndex: this.curEleIndex, data: { ...elements, point: { ...elements.point, w: w ?? elements.point.w, h: imgHeight ?? elements.point.h, responsive: true } } });
        });
        // }
      } else if (responsive === 'element' && elements.id) {
        this.adjustHeight();
      }
    } else {
      this.updatePageInfo({ containerIndex: this.curEleIndex, data: { ...elements, point: { ...elements.point, w: w ?? elements.point.w, h: h ?? elements.point.h } } });
    }
  }

  changeAlignType(type) {
    const freedomBody = document.querySelector('.freedom-body');
    const curElement = (freedomBody as Element).children[this.curChildIndex];
    const [ containerW, containerH ] = [getStyle(freedomBody, 'width'), getStyle(freedomBody, 'height')];
    const [ eleW, eleH ] = [getStyle(curElement, 'width'), getStyle(curElement, 'height')];
    const elements = this.pageData.elements[this.curEleIndex].child[this.curChildIndex];
    let { left, top } = elements.commonStyle;
    switch (type) {
    case 'top':
      top = 0; break;
    case 'right':
      left = subtract(containerW, eleW); break;
    case 'bottom':
      top = subtract(containerH, eleH); break;
    case 'left':
      left = 0; break;
    case 'vertical':
      top = ceil(divide(subtract(containerH, eleH), 2), 2); break;
    case 'horizontal':
      left = ceil(divide(subtract(containerW, eleW), 2), 2); break;
    case 'full': case 'width': case 'height':
      EventBus.$emit('resizedChildEvent', type); break;
    default: break;
    }
    this.updatePageInfo({ containerIndex: this.curEleIndex, childIndex: this.curChildIndex, data: { ...elements, commonStyle: { ...elements.commonStyle, left, top } } });
  }

  changeMargin() {
    const ele = this.getCurElement();
    const prevCommonStyle = cloneDeep(ele.commonStyle || {});
    // this.point.w = this.point.w - (this.commonStyle.paddingLeft || 0) - (this.commonStyle.paddingRight || 0);
    this.point.h = this.point.h - (prevCommonStyle.paddingTop || 0) - (prevCommonStyle.paddingBottom || 0) + (this.commonStyle.paddingTop || 0) + (this.commonStyle.paddingBottom || 0);
    this.updateCommonStyle({ containerIndex: this.curEleIndex, childIndex: this.curChildIndex, data: this.commonStyle });
    this.updatePoint();
    this.adjustHeight();
  }
}
