/** @jsx jsx */
import { jsx } from '@emotion/core';
import styled from '@emotion/styled';
import { SettingsConfig, SettingControl, Curve, CommandCategory } from '../../types';
import SelectControl from './SelectControl';
import SliderControl from './SliderControl';
import { gray100, gray800 } from '../../styles/colors_v2';
import { Fragment, useCallback, useContext } from 'react';
import { CommandSettingsContext } from '../../hooks/useCommandSettings';
import { MajorButton } from '../../styles/elements';
import { CommandEditorContext } from '../../hooks/useCommandEditor';
import { ProjectContext } from '../../hooks/useProject';
import { getSelectionLength } from '../../audio/utils/selectionTools';
import WalkthroughFlag from '../WalkthroughFlag';
import { commandSettingsWidth } from '../../styles/dimensions';
import { WalkthroughContext, WalkthroughStep } from '../../hooks/useWalkthrough';

const SettingsList = styled.div`
  color: ${gray800};
  padding: 12px;
  overflow: scroll;
  ::-webkit-scrollbar {
    display: none;
  }
`;

const SettingWrapper = styled.div`
  margin-bottom: 20px;
`;

const SettingName = styled.h4`
  font-size: 13px;
  margin-bottom:-2px;
`;

const Container = styled.div`
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: calc(100% - 20px);
`;

const StickyFooter = styled.footer`
  width: 296px;
  padding: 4px 12px 12px 12px;
  background-color: ${gray100};
  position: relative;
`;

const SelectionWarning = styled.p`
  padding-top: 0;
  margin-top: 0;
  color: ${gray800};
  font-size: 13px;
  text-align: center;
`;

const ExecuteButton = styled(MajorButton)`
  width: 100%;
  padding: 10px 20px;
`;

const Setting = function({ config, value, setValue }: { config: SettingsConfig<any>, value: any, setValue(newValue: any): void }) {
  const { name, control } = config;
  return (
    <SettingWrapper>
      <SettingName>{name}</SettingName>
      {control === SettingControl.Slider && config.min !== undefined && config.max !== undefined && (
        <SliderControl
          min={config.min}
          max={config.max}
          value={value}
          setValue={setValue}
          curve={config.curve || Curve.Linear}
        />
      )}
      {control === SettingControl.Select && config.options && <SelectControl value={value} setValue={setValue} options={config.options} />}
      {control === SettingControl.Switch && <SelectControl value={value} setValue={setValue} options={config.options || { 'On': true, 'Off': false }} />}
    </SettingWrapper>
  )
};

export default ({ onExecute }: { onExecute: () => void }) => {
  const { focusedCommand } = useContext(CommandEditorContext);
  const { selection } = useContext(ProjectContext);
  const { sortedSettings, settingValues, updateSetting } = useContext(CommandSettingsContext);
  const walkthrough = useContext(WalkthroughContext);
  const handleClick = useCallback(() => {
    onExecute();
    walkthrough.runCode();
  }, [onExecute, walkthrough])
  return (
    <Container>
      <SettingsList>
        {sortedSettings.filter((setting) => settingValues[setting.id] !== undefined).map((setting) => (
          <Setting
            key={setting.id}
            config={setting}
            value={settingValues[setting.id]}
            setValue={(value) => updateSetting(setting.id, value)}
          />
        ))}
      </SettingsList>

      <StickyFooter>
        <WalkthroughFlag
          style={{ bottom: '100%', width: commandSettingsWidth - 40, left: 20, right: 20 }}
          anchorStyle={{ left: '50%', marginLeft: -11 }}
          step={WalkthroughStep.RunCode}
        >
          {
            (focusedCommand && focusedCommand.category !== CommandCategory.Generator)
              ? getSelectionLength(selection) < 20000
                ? (<Fragment><strong>Select a bunch of audio up top</strong>, then click this big blue button!</Fragment>)
                : ('Now click this big blue button!')
              : 'Click this big blue button to run your code!'
          }
        </WalkthroughFlag>
        {focusedCommand && focusedCommand.category !== CommandCategory.Generator && getSelectionLength(selection) === 0 && (
          <SelectionWarning>
            You may need to select audio first.<br />
            Click and drag audio to select it.
          </SelectionWarning>
        )}
        <ExecuteButton onClick={handleClick}>Run Code</ExecuteButton>
      </StickyFooter>
    </Container>
  );
}
