import React, { Suspense, useState, useEffect } from 'react';
import { connect } from 'react-redux';
import PageAnimation from './PageAnimation';
import Screen from 'components/ScreenPreview';
import {
  ScreenProvider,
  ScreenDataProvider,
  PanelDataProvider,
  ComponentDataProvider,
  FilterDataProvider,
  CallbackProvider,
  InteractionProvider
} from 'components/ScreenPreview/Context';
import { getComponentData } from 'models/component';
import { emitCallback } from 'models/callback';
import { generateId } from 'utils/utils';
import styles from './ScreenContainer.less';
import classnames from 'classnames';
import WatermarkCanvas from 'components/WatermarkCanvas';
interface IPayload {
  _from: {
    //
  };
  id: string | number;
}

function ScreenContainer({
  id,
  scale,
  active,
  animation,
  containerHeight,
  screensById,
  componentsById,
  panelsById,
  filters,
  callbackKeys,
  callbackValues,
  interactions,
  getComponentData,
  emitCallback,
  emitEvent
}) {
  const [payloads, setPayloads] = useState<IPayload[]>([]);
  const screen = screensById[id];

  useEffect(() => {
    if (active && payloads.length) {
      const currentPayloads = payloads;
      payloads.map((payload) => {
        emitEvent({
          screenId: id,
          payload: {
            ...payload,
            _from: {
              ...payload._from,
              screenId: id
            }
          }
        });
      });

      setPayloads((prev) =>
        prev.filter((o) => {
          return !currentPayloads.find((oo) => oo.id === o.id);
        })
      );
    }
  }, [payloads, active]);

  const handleEmitEvent = (payload) => {
    setPayloads((prev) => {
      const result = prev.concat({
        id: generateId(),
        ...payload
      });

      return result;
    });
  };

  if (screen) {
    const { config, tenantId } = screen;
    const [dimension] = config;
    const width = dimension._value.find((d) => d._name === 'width')._value;
    const height = dimension._value.find((d) => d._name === 'height')._value;
    const top = (containerHeight - height * scale) / 2;
    const realTop = top < 0 ? 0 : top;

    return (
      <ScreenProvider tenantId={tenantId} getComponentData={getComponentData} emitEvent={handleEmitEvent} emitCallback={emitCallback}>
        <ScreenDataProvider screensById={screensById}>
          <PanelDataProvider panelsById={panelsById}>
            <ComponentDataProvider componentsById={componentsById}>
              <CallbackProvider callbackKeys={callbackKeys} callbackValues={callbackValues}>
                <FilterDataProvider filters={filters}>
                  <InteractionProvider interactions={interactions}>
                    <Suspense fallback="">
                      <PageAnimation active={active} animation={animation}>
                        <div
                          className={classnames(styles.container)}
                          style={{ position: 'absolute', transform: `scale(${scale})`, top: realTop }}>
                          <Screen id={id} width={width} height={height} />
                          <WatermarkCanvas width={width} height={height} />
                        </div>
                      </PageAnimation>
                    </Suspense>
                  </InteractionProvider>
                </FilterDataProvider>
              </CallbackProvider>
            </ComponentDataProvider>
          </PanelDataProvider>
        </ScreenDataProvider>
      </ScreenProvider>
    );
  } else {
    return null;
  }
}

const mapStateToProps = ({ componentsById, screensById, panelsById, filters, callback, interactions }) => {
  const { callbackKeys, callbackValues } = callback;

  return {
    componentsById,
    screensById,
    panelsById,
    filters: filters.list,
    callbackKeys,
    callbackValues,
    interactions
  };
};

const mapDispatchToProps = {
  getComponentData,
  emitCallback
};

export default connect(mapStateToProps, mapDispatchToProps)(ScreenContainer);
