/**
 * @file        Tween component
 * @author      MicroMatrix <yangpan.1985@bytedance.com>
 * @copyright   2012-2020 bytedance
 * @link        git@code.byted.org:yangpan.1985/avg.git
 */

import React from 'react';
import PropTypes from 'prop-types';
import core from 'core/core';
import { Layer } from '../Layer';
import tweenGenerator from './perform';
import findPixiNode from '../findPixiNode';

const logger = core.getLogger('Tween');

class Tween extends React.Component {
  static propTypes = {
    schemes: PropTypes.object,
    children: PropTypes.any
  }
  constructor(props) {
    super(props);

    this.nodes = {};
    this.tweens = {};
    this.shadowState = {};

    this.tempSymbol = Symbol('tween');
    this.runningTween = [];
  }
  componentDidMount() {
    this.registerTweens();
  }
  componentWillUnmount() {
    for (const key of Object.keys(this.tweens)) {
      this.tweens[key].stop();
    }
  }
  registerTweens() {
    const schemeNames = Object.keys(this.props.schemes || {});

    for (const schemeName of schemeNames) {
      const scheme = this.props.schemes[schemeName];

      this.tweens[schemeName] = tweenGenerator(scheme, this.nodes);
    }

    if (schemeNames.includes('default')) {
      this.runTween('default');
    }
  }
  runTween(name) {
    const tween = this.tweens[name];

    if (tween) {
      this.runningTween[name] && this.runningTween[name].stop();
      this.runningTween[name] = tween;
      tween.start();
    } else {
      logger.warn(`Scheme ${name} is not defined.`);
    }
  }
  stopTween(name) {
    this.runningTween[name] && this.runningTween[name].stop();
  }
  runScheme(scheme, name = this.tempSymbol) {
    const tween = tweenGenerator(scheme, this.nodes);

    this.runningTween[name] && this.runningTween[name].stop();
    this.runningTween[name] = tween;

    tween.start();
  }
  getNodes(key, ref) {
    if (ref) {
      this.nodes[key] = findPixiNode(ref);
    }
  }
  render() {
    this.nodes = {};
    const elements = React.Children.map(this.props.children, element =>
      // const originState = this.state[element.key];
      // const updatedState = this.shadowState[element.key];
    element && React.cloneElement(element, {
      // ...originState, ...updatedState,
      ref: ref => { element.ref && element.ref(ref); this.getNodes(element.key, ref); },
    }));

    return <Layer {...this.props}>{ elements }</Layer>;
  }
}

// class Lite extends React.Component {
//   constructor(props) {
//     super(props);

//     this.state = props.children.props;
//   }
//   tween = null;
//   componentDidMount() {
//     const keys = Object.keys(this.props.to);

//     const ctx = {};
//     const target = {};
//     for (const key of keys) {
//       ctx[key] = this.state[key];
//       target[key] = this.props.to[key];
//     }

//     this.tween = new TWEEN.Tween(ctx)
//     // .delay(2000)
//     .to(target, this.props.duration)
//     .repeat(this.props.repeat)
//     .yoyo(this.props.yoyo)
//     .easing(TWEEN.Easing.Sinusoidal.In)
//     .onUpdate(() => {
//       this.setState(ctx);
//     })
//     .start();
//   }
//   componentWillUnmount() {
//     this.tween.stop();
//   }
//   render() {
//     if (this.props.children instanceof Array) {
//       throw 'Don\'t support more than one child in Tween.';
//     }
//     const element = React.cloneElement(this.props.children, {
//       ...this.state,
//     });
//     return element;
//   }
// }

// Tween.Lite = Lite;

export default Tween;
