content: import React from 'react';
  import { connect, useDispatch } from 'react-redux';
  import { bindActionCreators } from 'redux';
  import { Route, Link } from 'react-router-dom';
  import localForage from 'localforage';
  import ConfirmationButton from '../components/Fields/ConfirmationButton';
  import PusherConnectionList from '../components/PusherConnectionList';
  import SourcesPriority from '../components/Fields/SourcesPriority';
  import Commands from '../components/Fields/Commands';
  import TextField from '../components/Fields/TextField';
  import SelectField from '../components/Fields/SelectField';
  import Header from '../components/Header';
  import Icon from '../components/Icon';
  import Services from '../components/Services';
  import Servers from '../components/Servers';
  import * as coreActions from '../services/core/actions';
  import * as uiActions from '../services/ui/actions';
  import * as pusherActions from '../services/pusher/actions';
  import * as mopidyActions from '../services/mopidy/actions';
  import * as lastfmActions from '../services/lastfm/actions';
  import * as spotifyActions from '../services/spotify/actions';
  import { isHosted } from '../util/helpers';
  import { i18n, I18n, languagesAvailable } from '../locale';
  import Button from '../components/Button';
  import { dater } from '../components/Dater';
  
  const CheckboxSetting = ({
    name,
    checked,
    label,
    tooltip,
  }) => {
    const dispatch = useDispatch();
    return (
      <label>
        <input
          type="checkbox"
          name={name}
          checked={checked}
          onChange={() => dispatch(uiActions.set({ [name]: !checked }))}
        />
        <span className={`label ${tooltip ? 'tooltip' : ''}`}>
          {label}
          {tooltip && (
            <span className="tooltip__content">
              {tooltip}
            </span>
          )}
        </span>
      </label>
    );
  };
  
  class Settings extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        mopidy_host: this.props.mopidy.host,
        mopidy_port: this.props.mopidy.port,
        mopidy_library_artists_uri: this.props.mopidy.library_artists_uri,
        mopidy_library_albums_uri: this.props.mopidy.library_albums_uri,
        mopidy_library_tracks_uri: this.props.mopidy.library_tracks_uri,
        pusher_username: this.props.pusher.username,
        input_in_focus: null,
      };
    }
  
    componentDidMount() {
      const { uiActions: { setWindowTitle } } = this.props;
      setWindowTitle(i18n('settings.title'));
    }
  
    componentDidUpdate = () => {
      const { pusher: { username } } = this.props;
      const { pusher_username, input_in_focus } = this.state;
      let new_username = null;
  
      if (username && username !== pusher_username && input_in_focus !== 'pusher_username') {
        new_username = username;
      }
  
      if (new_username) this.setState({ pusher_username: new_username });
    }
  
    onLanguageChange = (language) => {
      const { uiActions: { setLanguage } } = this.props;
      setLanguage(language);
    }
  
    onMopidySettingChanged = (name, value) => {
      const {
        mopidyActions: {
          set,
        },
      } = this.props;
      const shortName = name.replace('mopidy_', '');
      set({ [shortName]: value });
      this.setState({ [name]: value });
    }
  
    doRestart = () => {
      const { pusherActions: { restart } } = this.props;
      restart();
    }
  
    doUpgrade = () => {
      const { pusherActions: { upgrade } } = this.props;
      upgrade();
    }
  
    doLocalScan = () => {
      const { pusherActions: { localScan } } = this.props;
      localScan();
    }
  
    renderLocalScanButton = () => {
      const {
        ui: { processes },
      } = this.props;
  
      const loading = processes.local_scan && processes.local_scan.status === 'running';
  
      return (
        <Button
          working={loading}
          onClick={this.doLocalScan}
          tracking={{ category: 'System', action: 'LocalScan' }}
        >
          <I18n path="settings.advanced.start_local_scan" />
        </Button>
      );
    }
  
    render = () => {
      const {
        mopidyActions: {
          set: setMopidy,
        },
        mopidy,
        pusherActions: {
          setUsername,
          runCommand,
          setCommands,
        },
        pusher,
        history,
        uiActions,
        ui,
      } = this.props;
      const {
        pusher_username,
      } = this.state;
  
      const options = (
        <>
          <Button
            discrete
            noHover
            to="/settings/debug"
          >
            <I18n path="debug.title">
              <Icon name="code" />
            </I18n>
          </Button>
          <Button
            href="https://github.com/jaedb/Iris/wiki"
            target="_blank"
            rel="noreferrer noopener"
            discrete
            noHover
          >
            <I18n path="settings.help">
              <Icon name="help" />
            </I18n>
          </Button>
        </>
      );
  
      return (
        <div className="view settings-view">
          <Header options={options} uiActions={uiActions}>
            <I18n path="settings.title">
              <Icon name="settings" type="material" />
            </I18n>
          </Header>
  
          <section className="content-wrapper">
  
            <h4 className="underline">
              <I18n path="settings.server.title" />
              <a name="server" />
            </h4>
  
            <label className="field">
              <div className="name"><I18n path="settings.server.username.label" /></div>
              <div className="input">
                <TextField
                  onChange={(value) => setUsername(value.replace(/\W/g, ''))}
                  value={pusher_username}
                  autosave
                />
                <div className="description">
                  <I18n path="settings.server.username.description" />
                </div>
              </div>
            </label>
  
            <Route path="/settings/:server?/:id?" component={Servers} />
  
            <h4 className="underline">
              <I18n path="settings.services.title" />
              <a name="services" />
            </h4>
  
            <Route path="/settings/:services?/:service?/:id?" component={Services} />
  
            <h4 className="underline">
              <I18n path="settings.interface.title" />
              <a name="interface" />
            </h4>
  
            <div className="field dropdown">
              <div className="name"><I18n path="settings.interface.language.label" /></div>
              <div className="input">
                <SelectField
                  onChange={this.onLanguageChange}
                  options={languagesAvailable.map((language) => ({
                    value: language.key,
                    label: `${language.name} (${language.key})`,
                  }))}
                  value={ui.language}
                />
              </div>
            </div>
  
            <div className="field radio">
              <div className="name">
                <I18n path="settings.interface.theme.label" />
              </div>
              <div className="input">
                <label>
                  <input
                    type="radio"
                    name="theme"
                    value="auto"
                    checked={ui.theme === 'auto'}
                    onChange={(e) => uiActions.set({ theme: e.target.value })}
                  />
                  <span className="label tooltip">
                    <I18n path="settings.interface.theme.auto" />
                    <span className="tooltip__content">
                      <I18n path="settings.interface.theme.auto_tooltip" />
                    </span>
                  </span>
                </label>
                <label>
                  <input
                    type="radio"
                    name="theme"
                    value="dark"
                    checked={ui.theme === 'dark'}
                    onChange={(e) => uiActions.set({ theme: e.target.value })}
                  />
                  <span className="label">
                    <I18n path="settings.interface.theme.dark" />
                  </span>
                </label>
                <label>
                  <input
                    type="radio"
                    name="theme"
                    value="light"
                    checked={ui.theme === 'light'}
                    onChange={(e) => uiActions.set({ theme: e.target.value })}
                  />
                  <span className="label">
                    <I18n path="settings.interface.theme.light" />
                  </span>
                </label>
              </div>
            </div>
  
            <div className="field checkbox">
              <div className="name"><I18n path="settings.interface.behavior.label" /></div>
              <div className="input">
                <CheckboxSetting
                  name="clear_tracklist_on_play"
                  checked={ui.clear_tracklist_on_play}
                  label={i18n('settings.interface.behavior.clear_tracklist')}
                  tooltip={i18n('settings.interface.behavior.clear_tracklist_tooltip')}
                />
                <CheckboxSetting
                  name="hotkeys_enabled"
                  checked={ui.hotkeys_enabled}
                  label={i18n('settings.interface.behavior.hotkeys')}
                />
                <CheckboxSetting
                  name="playback_controls_touch_enabled"
                  checked={ui.playback_controls_touch_enabled}
                  label={i18n('settings.interface.behavior.touch_events')}
                  tooltip={i18n('settings.interface.behavior.touch_events_tooltip')}
                />
                <CheckboxSetting
                  name="grid_glow_enabled"
                  checked={ui.grid_glow_enabled}
                  label={i18n('settings.interface.behavior.grid_glow')}
                  tooltip={i18n('settings.interface.behavior.grid_glow_tooltip')}
                />
              </div>
            </div>
  
            <div className="field checkbox">
              <div className="name"><I18n path="settings.interface.scrolling.label" /></div>
              <div className="input">
                <CheckboxSetting
                  name="smooth_scrolling_enabled"
                  checked={ui.smooth_scrolling_enabled}
                  label={i18n('settings.interface.scrolling.smooth_scrolling')}
                />
                <CheckboxSetting
                  name="wide_scrollbar_enabled"
                  checked={ui.wide_scrollbar_enabled}
                  label={i18n('settings.interface.scrolling.wide')}
                />
                <CheckboxSetting
                  name="hide_scrollbars"
                  checked={ui.hide_scrollbars}
                  label={i18n('settings.interface.scrolling.hidden')}
                />
              </div>
            </div>
  
            <div className="field sources-priority">
              <div className="name">
                <I18n path="settings.interface.sources_priority.label" />
              </div>
              <div className="input">
                <SourcesPriority
                  uri_schemes={mopidy.uri_schemes ? mopidy.uri_schemes : []}
                  uri_schemes_priority={ui.uri_schemes_priority ? ui.uri_schemes_priority : []}
                  uiActions={uiActions}
                />
                <div className="description">
                  <I18n path="settings.interface.sources_priority.description" />
                </div>
              </div>
            </div>
  
            {isHosted() ? null : (
              <div className="field checkbox">
                <div className="name">
                  <I18n path="settings.interface.reporting.label" />
                </div>
                <div className="input">
                  <CheckboxSetting
                    name="allow_reporting"
                    checked={ui.allow_reporting}
                    label={i18n('settings.interface.reporting.sublabel')}
                  />
                  <div className="description">
                    <I18n path="settings.interface.reporting.description" />
                    <a href="https://github.com/jaedb/Iris/wiki/Terms-of-use#privacy-policy" target="_blank"><I18n path="settings.interface.reporting.privacy_policy" /></a>
                    .
                  </div>
                </div>
              </div>
            )}
  
            <div className="field commands-setup" id="commands-setup">
              <div className="name">
                <I18n path="settings.interface.commands.label" />
              </div>
              <div className="input">
                <Commands
                  commands={pusher.commands}
                  runCommand={(id, notify) => runCommand(id, notify)}
                  onChange={(commands) => setCommands(commands)}
                />
                <Button to="/modal/edit-command">
                  <I18n path="actions.add" />
                </Button>
              </div>
            </div>
  
            <h4 className="underline">
              <I18n path="settings.advanced.title" />
              <a name="advanced" />
            </h4>
  
            <div className="field">
              <div className="name">
                <I18n path="settings.advanced.artist_uri.label" />
              </div>
              <div className="input">
                <TextField
                  value={this.state.mopidy_library_artists_uri}
                  onChange={(value) => this.onMopidySettingChanged('mopidy_library_artists_uri', value)}
                  autosave
                />
                <div className="description">
                  <I18n path="settings.advanced.artist_uri.description" />
                </div>
              </div>
            </div>
  
            <label className="field">
              <div className="name">
                <I18n path="settings.advanced.album_uri.label" />
              </div>
              <div className="input">
                <TextField
                  type="text"
                  value={this.state.mopidy_library_albums_uri}
                  onChange={(value) => this.onMopidySettingChanged('mopidy_library_albums_uri', value)}
                  autosave
                />
                <div className="description">
                  <I18n path="settings.advanced.album_uri.description" />
                </div>
              </div>
            </label>
  
            <label className="field">
              <div className="name">
                <I18n path="settings.advanced.track_uri.label" />
              </div>
              <div className="input">
                <TextField
                  type="text"
                  value={this.state.mopidy_library_tracks_uri}
                  onChange={(value) => this.onMopidySettingChanged('mopidy_library_tracks_uri', value)}
                  autosave
                />
                <div className="description">
                  <I18n path="settings.advanced.track_uri.description" />
                </div>
              </div>
            </label>
  
            <div className="field pusher-connections">
              <div className="name">
                <I18n path="settings.advanced.connections.label" />
              </div>
              <div className="input">
                <div className="text">
                  <PusherConnectionList />
                </div>
              </div>
            </div>
  
            <div className="field">
              <div className="name">
                <I18n path="settings.advanced.version.label" />
              </div>
              <div className="input">
                <span className="text">
                  <a
                    target="_blank"
                    rel="noopener noreferrer"
                    href={`https://github.com/jaedb/Iris/releases/tag/${pusher.version.current}`}
                  >
                    {pusher.version.current}
                  </a>
                  {' '}
                  <span className="mid_grey-text tooltip">
                    {window.build}
                    {window.build && (
                      <span className="tooltip__content">
                        {`${dater('ago', parseInt(window.build, 10) * 1000)} ago`}
                      </span>
                    )}
                  </span>
                  {pusher.version.upgrade_available ? (
                    <a
                      target="_blank"
                      rel="noopener noreferrer"
                      className="flag flag--dark"
                      href={`https://github.com/jaedb/Iris/releases/tag/${pusher.version.latest}`}
                    >
                      <Icon name="cloud_download" className="blue-text" />
                      <I18n
                        path="settings.advanced.version.upgrade_available"
                        version={pusher.version.latest}
                      >
                        {' '}
                      </I18n>
                    </a>
                  ) : (
                    <span className="flag flag--dark">
                      <Icon name="check" className="green-text" />
                      <I18n path="settings.advanced.version.up_to_date">
                        {' '}
                      </I18n>
                    </span>
                  )}
                </span>
              </div>
            </div>
  
            <div className="field">
              {this.renderLocalScanButton()}
              <Button to="/modal/share-configuration">
                <I18n path="settings.advanced.share_configuration" />
              </Button>
            </div>
  
            <div className="field">
              {pusher.version.upgrade_available && (
                <Button
                  type="secondary"
                  onClick={this.doUpgrade}
                  tracking={{ category: 'System', action: 'Upgrade', label: pusher.version.latest }}
                >
                  <I18n path="settings.advanced.version.upgrade" version={pusher.version.latest} />
                </Button>
              )}
              <Button
                type="destructive"
                working={mopidy.restarting}
                onClick={this.doRestart}
                tracking={{ category: 'System', action: 'Restart' }}
              >
                <I18n path="settings.advanced.restart" />
              </Button>
              <Button
                to="/modal/reset"
                type="destructive"
              >
                <I18n path="settings.advanced.reset" />
              </Button>
            </div>
  
            <h4 className="underline">
              <I18n path="settings.about.title" />
              <a name="about" />
            </h4>
  
            <div>
              <em><a href="https://github.com/jaedb/Iris" target="_blank">Iris</a></em>
              <I18n path="settings.about.blurb_1" />
              <a
                href="https://github.com/jaedb"
                target="_blank"
                rel="noopener noreferrer"
              >
                James Barnsley
              </a>
              <I18n path="settings.about.blurb_2" />
            </div>
            <br />
            <br />
            <div>
              <Button
                href="https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=james%40barnsley%2enz&lc=NZ&item_name=James%20Barnsley&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted"
                target="_blank"
                tracking={{ category: 'About', action: 'Paypal' }}
              >
                <I18n path="settings.about.donate">
                  <Icon type="fontawesome" name="paypal" />
                  {' '}
                </I18n>
              </Button>
              <Button
                href="https://github.com/jaedb/Iris"
                target="_blank"
                tracking={{ category: 'About', action: 'GitHub' }}
              >
                <I18n path="settings.about.github">
                  <Icon type="fontawesome" name="github" />
                  {' '}
                </I18n>
              </Button>
            </div>
  
          </section>
        </div>
      );
    }
  }
  
  const mapStateToProps = (state) => state;
  
  const mapDispatchToProps = (dispatch) => ({
    coreActions: bindActionCreators(coreActions, dispatch),
    uiActions: bindActionCreators(uiActions, dispatch),
    pusherActions: bindActionCreators(pusherActions, dispatch),
    mopidyActions: bindActionCreators(mopidyActions, dispatch),
    lastfmActions: bindActionCreators(lastfmActions, dispatch),
    spotifyActions: bindActionCreators(spotifyActions, dispatch),
  });
  
  export default connect(mapStateToProps, mapDispatchToProps)(Settings);
  