/**
 * Created by baoyinghai on 5/26/17.
 */
import React from 'react';
import EditButton from '../Button/EditButton';
import SaveButton from '../Button/SaveButton';
import AddButton from '../Button/AddButton';
import TimeButton from '../Button/TimeButton';
import hoc from '../../hoc';
import { Visualizations, setting } from '../../visualizations';
import Board, { calculatePosition, calculateHitBit } from './board';
import CardSetting from '../CardSetting';
import { popModal, fetch, popAlert, closeWhileClickSpace } from '../../util';
import FormDialog from '../FormDialog';
import { getPublicMetaData } from '../../constant/link';
import Hook from '../Icon/Hook';
import './DropMenu.less';

const RcItem = props => {
  const className = props.isHit ? 'time-menu-item hit':'time-menu-item';
  return (
    <div onClick={props.onClick} className={className}>
      <Hook/>
      <span className="desc-wrapper">{props.desc}</span>
    </div>
  );
};

const DropDown = props => {
  const { value, show, onHandleChange, switchHandler } = props;
  if (!show) return null;
  const handle = v => () => {
    switchHandler && switchHandler();
    onHandleChange && onHandleChange(v);
  };
  return (
    <div className="dashboard drop-down-wrapper">
      <div className="arrow-up"/>
      <div className="small-title">自动刷新间隔</div>
      <RcItem isHit={value === 0} desc="关闭" onClick={handle(0)} />
      <RcItem isHit={value === 1} desc="  1 分钟" onClick={handle(1)} />
      <RcItem isHit={value === 5} desc="  5 分钟" onClick={handle(5)} />
      <RcItem isHit={value === 10} desc="10 分钟" onClick={handle(10)} />
      <RcItem isHit={value === 15} desc="15 分钟" onClick={handle(15)} />
      <RcItem isHit={value === 30} desc="30 分钟" onClick={handle(30)} />
      <RcItem isHit={value === 60} desc="60 分钟" onClick={handle(60)} />
    </div>
  );
};

export default class DashBoard extends React.Component {

  state = {
    model: 'view',
    cards: this.props.cards,
    querySql: '',
    panelDefinitionId: -1,
    showDropDown: false,
    freshTime: 0,
    builtInType: null
  };

  renderCards = () => {
    return this.state.cards.map(card => {
      var Comp = Visualizations[card.chartType];
      if (!Comp) {
        console.error('comp is null');
      }
      if (this.state.model === 'view') {
        Comp = hoc.layout(hoc.loadData(Comp));
      } else {
        Comp = [hoc.setable, hoc.loadData, hoc.layout, hoc.moveable].reduce((initValue, fn) => fn(initValue), Comp);
      }
      return <Comp key={card.index} freshTime={this.state.freshTime} calculateHitBitBeside={this.calculateHitBitBeside} updateLayout={this.updateLayout} removeCard={this.removeCard} {...card} setting={setting[card.chartType]} updateSetting={this.updateSetting} />;
    });
  };

  calculateHitBitBeside = index => {
    return calculateHitBit(this.state.cards.filter(card => card.index !== index));
  };

  updateSetting = (key, setting, title) => {
    // chartSetting
    this.setState({
      cards: this.state.cards.map(card => {
        if (card.index === key) {
          card.chartSetting = setting;
          if (title) {
            card.title = title;
          }
        }
        return card;
      })
    }, () => {
      this.setState({
        cardsList: this.renderCards()
      });
    });
  };

  updateLayout = (key, layout) => {
    this.setState({
      cards: this.state.cards.map(card => {
        if (card.index === key) {
          card.layout = layout;
        }
        return card;
      })
    }, () => {
      this.setState({
        cardsList: this.renderCards()
      });
    });
  };

  removeCard = index => {
    this.setState({
      cards: this.state.cards.filter(card => card.index !== index)
    }, () => {
      this.setState({
        cardsList: this.renderCards()
      });
    });
  };

  save = () => {
    this.setState({
      model: 'view',
      // cards: [...this.state.cards]
    }, () => {
      this.setState({
        cardsList: this.renderCards()
      });
    });
    const { updateCards } = this.props;
    updateCards && updateCards(this.state.cards);
    // save
  };

  create = () => {
    const self = this;
    fetch(getPublicMetaData, {}, response => {
      const dataSource = response || [];
      const body = props => {
        return (
          <FormDialog
            title="数据源"
            dataSource={dataSource}
            submit={value => {
              if (value) {
                if (value.methodType === 1) {
                  const card = dataSource.filter(f => f.panelDefinitionId === value.panelDefinitionId)[0];
                  self.addCards({
                    title: card.chartType || 'table',
                    layout: {
                      ...self.calculatePosition(8,5),
                      width: 8, height: 5
                    },
                    chartType: card.chartType || 'table',
                    querySql: card.querySql,
                    chartSetting: {},
                    panelDefinitionId: value.panelDefinitionId,
                    builtInType: card.builtInType,
                    deptId: card.deptId,
                    publicType: card.publicType
                  });
                } else if(value.panelDefinitionId === -1) {
                  self.setState({model: 'create', builtInType: null, querySql: '', panelDefinitionId: -1});
                } else {
                  const tag = dataSource.filter(d => d.panelDefinitionId === value.panelDefinitionId)[0];
                  self.setState({model: 'create', builtInType: tag.builtInType, querySql: tag.querySql, panelDefinitionId: value.panelDefinitionId});
                }
              }

            }}
            onClick={props.callback}
            createBottomButtons={props.createBottomButtons}
          />
        );
      };
      popModal('卡片新增', body);
    }, error => {
      console.log(error);
      popAlert('请求数据异常');
    });
  };

  cancel = () => {
    this.setState({
      model: 'edit'
    });
  };

  showTime = () => {
    this.showDropDown();
  };

  _renderButtons = () => {
    const ret = [];
    if (this.state.model === 'view') {
      ret.push(<EditButton onClick={() => {
        this.setState({model: 'edit'}, () => {
          this.setState({
            cardsList: this.renderCards()
          });
        });
        this.props.switchNavBar(false);
      }} />);
    } else if (this.state.model === 'edit') {
      ret.push(<SaveButton onClick={this.save} />);
      ret.push(<TimeButton onClick={this.showTime} />)
      ret.push(<AddButton onClick={this.create} />);
    }
    return ret;
  };

  componentWillReceiveProps(nextProps) {
    if (this.state.model === 'view' && JSON.stringify(nextProps.cards) !== JSON.stringify(this.state.cards)) {
      this.setState({
        cards: nextProps.cards,
      }, () => {
        this.setState({
          cardsList: this.renderCards()
        });
      });
    }
  }

  addCards = newCard => {
    this.setState({
      model: 'edit',
      cards: this.state.cards.map((card, index) => {
        card.index = index;
        return card;
      }).concat(newCard)
    }, () => {
      this.setState({
        cardsList: this.renderCards()
      });
    });
  };

  calculatePosition = (width, height) => {
    return calculatePosition(width, height, this.state.cards);
  };

  handleChange = v => {
    this.setState({
      freshTime: v
    });
  };

  showDropDown = () => {
    this.setState({
      showDropDown: !this.state.showDropDown
    });
  };

  render() {
    if (this.state.model === 'create') {
      return (
        <CardSetting
          builtInType={this.state.builtInType}
          querySql={this.state.querySql}
          cancel={this.cancel}
          addCards={this.addCards}
          calculatePosition={this.calculatePosition}
          panelDefinitionId={this.state.panelDefinitionId}
        />
      );
    }
    const DropDownMenu = closeWhileClickSpace(DropDown, {
      defaultShow: this.state.showDropDown,
      querySelector: 'button-bar'
    });
    return (
      <div>
        <div className="button-bar">
          {this._renderButtons()}
          {this.state.model === 'edit' && this.state.showDropDown && <DropDownMenu value={this.state.freshTime} switchHandler={this.showDropDown} onHandleChange={this.handleChange}/>}
        </div>
        <Board model={this.state.model} cards={this.state.cards}>
          {this.state.cardsList}
        </Board>
      </div>
    );
  }
}