import React from 'react';
import { Renderer, RendererProps } from '../factory';
import { BaseSchema, SchemaApi, SchemaCollection, SchemaTokenizeableString } from '../Schema';
import Timeline from '../components/Timeline';
import { ScopedContext, IScopedContext } from '../Scoped';
import { Spin } from 'antd';
import { filter } from '../utils/tpl';

import { RemoteOptionsProps, withRemoteConfig } from '../components/WithRemoteConfig';
import { Api } from '../types';

export interface TimelineItemSchema extends Omit<BaseSchema, 'type'> {
  /**
   * 时间点
   */
  time: string;

  /**
   * 时间节点标题
   */
  title?: SchemaCollection;

  /**
    * 详细内容
    */
  detail?: string;

  /**
   * detail折叠时文案
   */
  detailCollapsedText?: string;

  /**
   * detail展开时文案
   */
  detailExpandedText?: string;

  /**
   * 时间点圆圈颜色
   */
  color?: string;

  /**
   * 图标
   */
  icon?: SchemaCollection;
  /**
   * 节点图标的 CSS 类名
   */
  iconClassName?: string;
  /**
   * 节点时间的 CSS 类名
   */
  timeClassName?: string;
  /**
   * 节点标题的 CSS 类名
   */
  titleClassName?: string;
  /**
   * 节点详情的 CSS 类名
   */
  detailClassName?: string;
}

export interface TimelineSchema extends BaseSchema {
  /**
   * 指定为 Timeline 时间轴渲染器
   */
  type: 'timeline';

  /**
   * 节点数据
   */
  items?: Array<TimelineItemSchema>;

  /**
   * API 或 数据映射
   */
  source?: SchemaApi | SchemaTokenizeableString;

  /**
   * 文字相对于时间轴展示方向
   */
  mode?: 'left' | 'right' | 'alternate';

  /**
   * 展示方向
   */
  direction?: 'horizontal' | 'vertical'

  /**
   * 节点倒序
   */
  reverse?: boolean,
  /**
   * 统一配置的节点图标 CSS 类
   */
  iconClassName?: boolean,
  /**
   * 统一配置的节点时间 CSS 类
   */
  timeClassName?: boolean,
  /**
   * 统一配置的节点标题 CSS 类
   */
  titleClassName?: boolean,
  /**
   * 统一配置的节点详情 CSS 类
   */
  detailClassName?: boolean,
}

export interface TimelineProps
  extends RendererProps,
  Omit<TimelineSchema, 'className'> { }

export function TimelineCmpt(props: TimelineProps) {
  const {
    items,
    mode,
    direction,
    reverse,
    data,
    // config,
    // source,
    render
  } = props;

  // 获取源数据
  const timelineItemsRow: Array<TimelineItemSchema> = items || [];

  // 渲染内容
  const resolveRender = (region: string, val?: SchemaCollection) => typeof val === 'string'
    ? filter(val, data)
    : (val && render(region, val));

  // 处理源数据
  const resolveTimelineItems =
    timelineItemsRow?.map((timelineItem: TimelineItemSchema) => {
      return {
        ...timelineItem,
        icon: resolveRender('icon', timelineItem.icon),
        title: resolveRender('title', timelineItem.title),
      }
    });

  return (<Timeline
    items={resolveTimelineItems}
    direction={direction}
    reverse={reverse}
    mode={mode}
  />)
}

export default class TimelineRender extends React.Component<
     React.ComponentProps<typeof TimelineCmpt>
  > {
  constructor(props) {
      super(props);
      this.handleGetTimeLineData = this.handleGetTimeLineData.bind(this);
      this.reload = this.reload.bind(this);
      this.state = {
        timeLineItems: [],
        fetchLoading: false
      }
    }
    componentDidMount(): void {
      this.handleGetTimeLineData();
    }
    reload(subpath?: string, query?: any, ctx?: any, isItemAction?: boolean) {
      this.handleGetTimeLineData({subpath, query, ctx, isItemAction});
    }
    // 获取时间轴数据
    async handleGetTimeLineData(props?: any = {}) {
      const { query, ctx = {}} = props;
      const {__super, ...rest} = ctx || {};
      const { env, api, store } = this.props;
      try {
        this.setState({
          fetchLoading: true
        });
        const res = await env.fetcher(api as Api, Object.assign({}, store?.data, query, rest));
        const timelineItemsRow = res?.data?.items || [];
        this.setState({
          timeLineItems: timelineItemsRow
        })
      } finally {
        this.setState({
          fetchLoading: false
        })
      }
    }
    render() {
      const { config, deferLoad, loading, updateConfig, env, api, ...rest } = this.props;

      return <Spin spinning={this.state.fetchLoading}>{this.state.fetchLoading ? <div style={{height: 60}}></div>: <TimelineCmpt config={config} items={this.state.timeLineItems} {...rest} />}</Spin>;
    }
}
@Renderer({
  type: 'timeline'
})
export class TimelineRenderer extends TimelineRender {
  static contextType = ScopedContext;

  constructor(props: TimelineProps, context: IScopedContext) {
    super(props);
    const scoped = context;
    scoped.registerComponent(this, context);
  }
  componentWillUnmount(): void {
    super.componentWillUnmount?.();
    const scoped = this.context as IScopedContext;
    scoped.unRegisterComponent(this);
  }

}
