import React, {useEffect, useState} from "react";
import {ButtonStyling, ResponsiveButtonStyle, ResponsiveOptionsDropdown} from "./responsive-button.style.js";

const responsiveOptions = {
  desktop: [1920, 1800, 1680, 1440, 1360, 1280, 1024],
  tablet: [992, 768, 600],
  mobile: [480, 414, 375, 360, 320],
}

const defaultResponsiveOptions = {
  reset: '100%',
  desktop: responsiveOptions.desktop[0],
  tablet: responsiveOptions.tablet[1],
  mobile: responsiveOptions.mobile[2],
}

export function ResponsiveButton({mode, active, onSelect}) {
  const [state, setState] = useState({open: true, activeBreakpoint: defaultResponsiveOptions[mode]});
  const updateState = (update) => setState(Object.assign({}, state, update));

  useEffect(() => {
    const closeDropdown = (e) => isEscHit(e) ? updateState({open: false}) : null;

    if (state.open) {
      document.addEventListener("keydown", closeDropdown);
    }

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

  // Blur event / Outside click
  const handleBlur = async (e) => await isClickOutside(e) ? updateState({open: false}) : null;

  return <ResponsiveButtonStyle tabIndex='0' onBlur={handleBlur}>
    <ButtonStyling data-mode={mode} data-active={active} onClick={() => select()}>{mode}</ButtonStyling>
    {active && state.open && responsiveOptions[mode] &&
      <ResponsiveOptionsDropdown>
        {responsiveOptions[mode].map((breakpoint) => {
          return <li>
            <a className={state.activeBreakpoint === breakpoint ? 'active' : ''} onClick={() => select(breakpoint)}>{breakpoint}</a>
          </li>;
        })}
      </ResponsiveOptionsDropdown>
    }
  </ResponsiveButtonStyle>;

  //
  // Actions
  //

  function select(activeBreakpoint = null) {
    // Click on option in Dropdown.
    if (activeBreakpoint) {
      updateState({open: false, activeBreakpoint});
      onSelect(activeBreakpoint);
      return;
    }

    // Click on device button.
    if (!active) {
      onSelect(state.activeBreakpoint)
      updateState({open: false});
    } else {
      updateState({open: true});
    }
  }
}

export function update(state, update) {
  return Object.assign({}, state, update);
}

export async function isClickOutside(e) {
  const currentTarget = e.currentTarget;

  return new Promise(resolve => {
    setTimeout(() => resolve(!currentTarget.contains(document.activeElement)));
  })
}

export function isEscHit(event) {
  return event.key === 'Escape'
}

