import React, { useEffect, useRef, useState } from 'react';
import s from './PlayerComponent.module.scss';
import {
  Player,
  Share,
  useConfigurator,
  useProductCache,
  useThreekitInitStatus,
} from '@threekit-tools/treble';
import { ArBtn } from '../ArBtn/ArBtn';
import BackArrow from '../../assets/BackArrow';
import { AnimatedHint } from '../AnimatedHint/AnimatedHint';
import { getRotationAngles, rotateTool } from '../../utils/rotatePlayer';
import { useStoreDispatch, useStoreSelector } from '../../App';
import {
  SetActiveItem,
  SetAttributes,
  SetIsCustomAttr,
  SetIsShortId,
  SetModal,
  SetPriceInfo,
} from '../../store/actions/Settings';
import SaveSvg from './../../assets/SaveSvg';
import LeftCamera from './../../assets/LeftCamera';
import RightCamera from './../../assets/RightCamera';
import { useLocation } from 'react-router-dom';
import {
  assetID,
  cameraPositions,
  PAGE_NAME,
  THREEKIT_PARAMS,
} from '../../utils/constants';
import { getSavedConfiguration } from './../../utils/configuration';
import { SavedConfig } from './../SavedConfig/SavedConfig';
import { modalName } from '../../store/reducers/Settings';
import axios from 'axios';
import { getActualPriceById } from '../../store/selectors/selectors';
import { getActualPrice } from '../AttributeComponents/Product';
import { Link } from 'react-router-dom';
export default function PlayerComponent({ ...props }) {
  const { ReturnToMainPage, customSettings, shortId, configSettings } = props;
  const [attributes, setConfiguration]: any = useConfigurator();
  const attributeInfo = useStoreSelector(getActualPriceById);
  const playerRef: any = useRef(null);
  const [playerHeight, setPlayerHeight] = useState(0);
  const [newSceneIsSet, setNewSceneIsSet] = useState(true);
  const { pathname, search }: any = useLocation();
  const jeepName = window.threekit.configurator.getMetadata().name
    ? window.threekit.configurator.getMetadata().name
    : 'Jeep';
  {
    (function () {
      window.addEventListener('resize', resizeThrottler, false);

      let resizeTimeout: any;
      function resizeThrottler() {
        // ignore resize events as long as an actualResizeHandler execution is in the queue
        if (!resizeTimeout) {
          resizeTimeout = setTimeout(function () {
            resizeTimeout = null;
            actualResizeHandler();

            // The actualResizeHandler will execute at a rate of 15fps
          }, 66);
        }
      }

      function actualResizeHandler() {
        // handle the resize event
        if (playerRef.current) {
          let height = playerRef.current.clientWidth;
          setUpCurrentHeightPlayer(height);
        }
      }
    })();
  }

  useEffect(() => {
    // loadCurrentScene();
    setNewSceneIsSet(true);
  }, [pathname]);

  useEffect(() => {
    if (playerRef.current && newSceneIsSet) {
      let height = playerRef.current.clientWidth;
      setUpCurrentHeightPlayer(height);
    }
  }, [playerRef]);

  function setUpCurrentHeightPlayer(height: number) {
    let result = (1380 * height) / 2048;
    setPlayerHeight(result);
    //@ts-ignore
    window.playerHeight = result;
  }

  type changeCameraPositionT = {
    direction: 'prev' | 'next';
  };
  const hasLoaded = useThreekitInitStatus();
  const dispatch = useStoreDispatch();
  const [rotateState, setRotateState]: any = useState({
    min: 0,
    max: 7,
    value: 7,
  });

  function updatePLayerFix() {
    if (hasLoaded && jeepName === 'Gladiator') {
      setTimeout(() => {
        //@ts-ignore
        window.stageConfig.setConfiguration({
          'Camera Position': 6,
        });
        //@ts-ignore
        window.stageConfig.setConfiguration({
          'Camera Position': 7,
        });
      }, 4000);
    }
  }

  function changeCameraPosition({ direction }: changeCameraPositionT) {
    //@ts-ignore
    let cameraValue = window.stageConfig.getConfiguration()['Camera Position'];
    let result: number = cameraValue;

    if (direction === 'prev') {
      if (cameraValue <= rotateState.min) {
        result = rotateState.max;
      } else {
        result--;
      }
    } else if (direction === 'next') {
      if (cameraValue >= rotateState.max) {
        result = rotateState.min;
      } else {
        result++;
      }
    }

    setRotateState({
      ...rotateState,
      value: result,
    });
  }
  //
  useEffect(() => {
    //@ts-ignore
    if (hasLoaded && window.playerT && newSceneIsSet) {
      //@ts-ignore
      window.stageConfig.setConfiguration({
        'Camera Position': rotateState.value,
      });
    }
  }, [rotateState.value]);
  function getActualAttr() {
    //@ts-ignore
    const attr = window.configurator.getAttributes();
    const arrayAttr: any = {};
    attr.map((item: any) => {
      if (item.visible) {
        const isAssetType = item.type === 'Asset';
        let defaultValue;
        let price = 0;
        if (isAssetType) {
          const currentDefaultValue = item.values.find(
            (value: any) => value.assetId === item.defaultValue.assetId
          );
          defaultValue = currentDefaultValue ? currentDefaultValue.label : '';
        } else {
          defaultValue = item.defaultValue;
        }

        arrayAttr[item.name] = {
          activeItem: '',
          defaultItem: defaultValue,
          assetType: item.assetType,
          cameraPosition: cameraPositions[item.name],
          price: price,
          shopInfo: {
            quantity: 1,
          },
        };
      }
    });

    dispatch(SetAttributes(arrayAttr));
  }
  async function loadRotateMethod() {
    //@ts-ignore
    window.playerT = await window.threekit.player.enableApi('player');
    //@ts-ignore
    const api = await window.playerT.api;
    //@ts-ignore
    window.threekit.player.tools.removeTool('zoom');
    //@ts-ignore
    window.configurator = await api.getConfigurator();

    //@ts-ignore
    window.stageConfig = await window.playerT.api.getStageConfigurator();

    //@ts-ignore
    await window.stageConfig.prefetchAttributes(['Camera Position']);
    //@ts-ignore
    const cameraData = window.stageConfig
      .getAttributes()
      .find((item: any) => item.name === 'Camera Position');
    // await window.configurator.prefetchAttributes(['Camera Position']);
    setRotateState({
      ...rotateState,
      min: cameraData.min,
      max: cameraData.max,
    });

    if (!!getRotationAngles()) {
      let props: any = getRotationAngles();

      //@ts-ignore
      await window.threekit.player.tools.addTool(rotateTool(props));
      getActualAttr();
    }
  }

  function setNewActiveAttr({ name, label, price }: any) {
    setTimeout(() => {
      dispatch(
        SetActiveItem({
          name: name,
          data: {
            activeItem: label,
            price,
            shopInfo: { quantity: 1 },
          },
        })
      );
    }, 0);
  }

  useEffect(() => {
    // let shortIdUrl = new URLSearchParams(search).get('shortId') || shortId;
    let shortIdUrl = shortId;
    console.log('shortIdUrl123: ', shortIdUrl);
    console.log('configSettings: ', configSettings);
    let qrId = new URLSearchParams(search).get('qr');

    async function fetchConfig() {
      let result: any = await getSavedConfiguration({
        // ...THREEKIT_PARAMS,
        authToken: configSettings.publicToken,
        orgId: configSettings.orgId,
        assetId: configSettings.assetId,
        threekitUrl:
          configSettings.threekitEnviroment === 'preview'
            ? 'https://preview.threekit.com/'
            : 'https://admin.threekit.com/',
        configurationId: shortIdUrl,
      });
      setConfiguration(result.variant).then((res: any) => {
        setUpConfiguratorParams();
        dispatch(SetIsShortId(true));
      });
    }

    if (hasLoaded) {
      loadRotateMethod();
      getActualPriceArray();
      getTrueVh();
      dispatch(
        SetModal({
          list: { loader: false },
        })
      );
      updatePLayerFix();
      if (!!shortIdUrl) {
        fetchConfig();
      } else {
        if (qrId) {
          let ios = new URLSearchParams(search).get('ios');
          let android = new URLSearchParams(search).get('android');

          dispatch(
            SetModal({ list: { arStep1: true }, info: { ios, android } })
          );
        }
        setUpConfiguratorParams();
        dispatch(SetIsShortId(true));
      }
      updatePLayerFix();
    }
  }, [hasLoaded]);

  function getTrueVh() {
    setTimeout(() => {
      let vh = window.innerHeight * 0.01;
      // First we get the viewport height and we multiple it by 1% to get a value for a vh unit
      // Then we set the value in the --vh custom property to the root of the document
      document.documentElement.style.setProperty('--vh', `${vh}px`);
      // // We listen to the resize event

      window.addEventListener('resize', () => {
        // We execute the same script as before
        let vh = window.innerHeight * 0.01;
        document.documentElement.style.setProperty('--vh', `${vh}px`);
      });
    }, 0);
  }

  function setUpConfiguratorParams() {
    if (customSettings) {
      let actualAttr: any = {};
      dispatch(SetIsCustomAttr(customSettings));

      Object.keys(attributes).forEach((key: any) => {
        // let attributeIsActive = new URLSearchParams(search).get(key);
        if (customSettings[key]) {
          const attrType = attributes[key].type;
          if (attrType === 'Asset') {
            const actualValue = attributes[key].values.find(
              (item: any) => item.metadata.option === customSettings[key]
            );
            if (!!actualValue) {
              let price: number = 0;
              let priceInfo: any;
              setTimeout(() => {
                //@ts-ignore
                window.threekit.configurator.setConfiguration({
                  [key]: {
                    //@ts-ignore
                    query: { metadata: { option: customSettings[key] } },
                  },
                });
                if (actualValue.label !== 'None') {
                  const id = actualValue.metadata._id;
                  priceInfo = attributeInfo[id];
                  price = getActualPrice({
                    isAsset: attrType === 'Asset',
                    item: actualValue,
                    priceInfo,
                  });
                }
                setNewActiveAttr({
                  name: key,
                  label: actualValue.label,
                  price,
                });
              }, 1000);
            }
          } else {
            const actualValue = attributes[key].values.find(
              (item: any) => item.value === customSettings[key]
            );

            if (!!actualValue) {
              actualAttr[key] = customSettings[key];
              setNewActiveAttr({
                name: key,
                label: actualValue.label,
                price: 0,
              });
            }
          }

          setConfiguration(actualAttr);
        }
      });
    }
  }

  function getActualPriceArray() {
    let lengthPriceAttr = 0;
    let arrayPrice: any = [];

    Object.values(attributes).forEach((value: any) => {
      if (value.type === 'Asset') {
        value.values.map((val: any) => {
          const id = val.metadata._id;
          if (id) {
            lengthPriceAttr++;
            arrayPrice.push(id);
          }
        });
      }
    });
    // console.log('arrayPrice: ', arrayPrice);
  }

  return (
    <div className={s.wrapper}>
      <div className={s.player__wrapper}>
        <div className={s.player_info}>
          <div onClick={() => ReturnToMainPage()} className={s.player_back}>
            <BackArrow />
            <span>Change Jeep</span>
          </div>

          <div className={s.player_name}>{jeepName}</div>
        </div>
        <SavedConfig />
      </div>
      <div
        className={s.player_content}
        ref={playerRef}
        style={playerHeight ? { height: `${playerHeight}px` } : {}}
      >
        <Player minHeight="230px">
          <Player.BottomCenterWidgets>
            {hasLoaded && (
              <div className={s.hint__wrapper}>
                <AnimatedHint />

                <div className={s.hint_arrows}>
                  <div
                    className={s.camera_arrow}
                    onClick={() => changeCameraPosition({ direction: 'prev' })}
                  >
                    <LeftCamera />
                  </div>
                  <div
                    className={s.camera_arrow}
                    onClick={() => changeCameraPosition({ direction: 'next' })}
                  >
                    <RightCamera />
                  </div>
                </div>
              </div>
            )}
          </Player.BottomCenterWidgets>
          <Player.MiddleLeftWidgets>
            <div
              className={s.camera_arrow}
              onClick={() => changeCameraPosition({ direction: 'prev' })}
            >
              <LeftCamera />
            </div>
          </Player.MiddleLeftWidgets>
          <Player.MiddleRightWidgets>
            <div
              className={s.camera_arrow}
              onClick={() => changeCameraPosition({ direction: 'next' })}
            >
              <RightCamera />
            </div>
          </Player.MiddleRightWidgets>
        </Player>
      </div>
    </div>
  );
}
