import React, {useCallback, useEffect, useState} from 'react';
import * as ReactDOM from 'react-dom/client';
import {
  SidebarButtonToggleStyle,
  SidebarCloseButtonStyle, SidebarDataOptionsStyle,
  SidebarHeaderStyle,
  SidebarStyle,
} from "./data-options.style.js";
import {isClickOutside, isEscHit} from "../responsive-button/ResponsiveButton.jsx";
import {DesignPreview} from "./DesignPreview.jsx";

function DataOptions(props = {}) {
  props.rootAttributes = props.rootAttributes ?? {};

  const initialState = {dataName: 'default', data: {}, dataOptions: [], designPreview: []};
  const [state, setState] = useState(initialState);
  const updateState = (update) => setState(Object.assign({}, state, update));

  const [sidebarOpen, setSidebarOpen] = useState(false);

  useEffect(async () => {
    const data = await fetchDataOptions(state.dataName);
    updateState(data);
  }, []);

  const handleCloseSidebarEscEvent = useCallback((e) => {
    if (isEscHit(e)) {
      (() => {
        closeSidebar()
      })();
    }
  }, []);

  useEffect(() => {
    document.addEventListener("keydown", handleCloseSidebarEscEvent);

    // Unsubscribe from ESC listener.
    return () => {
      document.removeEventListener("keydown", handleCloseSidebarEscEvent);
    }
  }, [handleCloseSidebarEscEvent]);

  const handleBlur = async (e) => await isClickOutside(e) ? closeSidebar() : null;
  const previewOption = getDesignPreviewImage(state.dataName, state.designPreview);

  return <div style={{display: 'flex', gap: '1rem', alignItems: 'center'}}>
    <SidebarButtonToggleStyle onClick={() => openSidebar()} title="Open a Sidebar with Data Options"/>

    <DesignPreview previewOption={previewOption}/>

    <SidebarStyle className={sidebarOpen ? 'active sidebar-active' : ''} tabIndex='0' onBlur={handleBlur}>
      <SidebarHeaderStyle>
        <SidebarCloseButtonStyle onClick={() => closeSidebar()}></SidebarCloseButtonStyle>
      </SidebarHeaderStyle>

      {state.dataOptions && !!state.dataOptions.length &&
        <SidebarDataOptionsStyle>
          <label htmlFor="data-options">Data Options</label>

          <select name="data" id="data-options" onChange={(e) => changeDataOption(e)} value={state.dataName}>
            {state.dataOptions.map((item) => {
              const isSelected = state.dataName === item;
              return <option value={item} selected={isSelected}>{item}</option>
            })}
          </select>
        </SidebarDataOptionsStyle>
      }

      {state.data &&
        <pre>{JSON.stringify(state.data, null, 2)}</pre>
      }
    </SidebarStyle>
  </div>;

  function openSidebar() {
    setSidebarOpen(true);
    setTimeout(() => document.querySelector('.sidebar-active').focus());
  }

  function closeSidebar() {
    setSidebarOpen(false);
  }

  async function changeDataOption(e) {
    const dataName = e.target.value;
    props.rootAttributes.previewFrame.src = window.devTool.previewFrameUrl + '?data=' + dataName;

    const dataOption = await fetchDataOptions(dataName);
    updateState(Object.assign({}, dataOption, {dataName}));
  }

  async function fetchDataOptions(name = 'default') {
    const queryParameters = new URLSearchParams({name});
    const response = await fetch(`/data?${queryParameters}`);
    return await response.json();
  }

  function getDesignPreviewImage(currentDataName, designPreviewOptions = []) {
    const dataOptions = designPreviewOptions.filter((item) => {
      return item.dataSource === currentDataName;
    });

    dataOptions.sort((a, b) => b.widthDimension - a.widthDimension);

    return dataOptions.find((item) => {
      return item.widthDimension // first
    });
  }
}

export function setupDataOptions(rootAttributes) {
  // INIT
  const wrapper = document.createElement('div');
  document.querySelector('.page_toolbar__left').prepend(wrapper)

  const root = ReactDOM.createRoot(wrapper);
  const html = (<DataOptions rootAttributes={rootAttributes}/>);
  root.render(html);
}
