// @flow
import { SITE_NAME, DOMAIN } from 'config';
import * as PAGES from 'constants/pages';
import SUPPORTED_LANGUAGES from 'constants/supported_languages';
import React from 'react';
import Page from 'component/page';
import Button from 'component/button';
import Card from 'component/common/card';
import I18nMessage from 'component/i18nMessage';
import { Form, FormField } from 'component/common/form';
import { INVALID_NAME_ERROR } from 'constants/claim';
import { isNameValid } from 'lbry-redux';
import { Lbryio } from 'lbryinc';
import { useHistory } from 'react-router';
import YoutubeTransferStatus from 'component/youtubeTransferStatus';
import Nag from 'component/common/nag';
import { getDefaultLanguage, sortLanguageMap } from 'util/default-languages';

const STATUS_TOKEN_PARAM = 'status_token';
const ERROR_MESSAGE_PARAM = 'error_message';
const NEW_CHANNEL_PARAM = 'new_channel';

type Props = {
  youtubeChannels: ?Array<{ transfer_state: string, sync_status: string }>,
  doUserFetch: () => void,
  inSignUpFlow?: boolean,
  doToggleInterestedInYoutubeSync: () => void,
};

export default function YoutubeSync(props: Props) {
  const { youtubeChannels, doUserFetch, inSignUpFlow = false, doToggleInterestedInYoutubeSync } = props;
  const {
    location: { search, pathname },
    push,
    replace,
  } = useHistory();
  const urlParams = new URLSearchParams(search);
  const statusToken = urlParams.get(STATUS_TOKEN_PARAM);
  const errorMessage = urlParams.get(ERROR_MESSAGE_PARAM);
  const newChannelParam = urlParams.get(NEW_CHANNEL_PARAM);
  const [channel, setChannel] = React.useState('');
  const [language, setLanguage] = React.useState(getDefaultLanguage());
  const [nameError, setNameError] = React.useState(undefined);
  const [acknowledgedTerms, setAcknowledgedTerms] = React.useState(false);
  const [addingNewChannel, setAddingNewChannel] = React.useState(newChannelParam);
  const hasYoutubeChannels = youtubeChannels && youtubeChannels.length > 0;

  React.useEffect(() => {
    const urlParamsInEffect = new URLSearchParams(search);
    if (!urlParamsInEffect.get('reset_scroll')) {
      urlParamsInEffect.append('reset_scroll', 'youtube');
    }

    replace(`?${urlParamsInEffect.toString()}`);
  }, [pathname, search]);

  React.useEffect(() => {
    if (statusToken && !hasYoutubeChannels) {
      doUserFetch();
    }
  }, [statusToken, hasYoutubeChannels, doUserFetch]);

  React.useEffect(() => {
    if (!newChannelParam) {
      setAddingNewChannel(false);
    }
  }, [newChannelParam]);

  function handleCreateChannel() {
    Lbryio.call('yt', 'new', {
      type: 'sync',
      immediate_sync: true,
      channel_language: language,
      desired_lbry_channel_name: `@${channel}`,
      return_url: `https://${DOMAIN}/$/${inSignUpFlow ? PAGES.AUTH : PAGES.YOUTUBE_SYNC}`,
    }).then((ytAuthUrl) => {
      // react-router isn't needed since it's a different domain
      window.location.href = ytAuthUrl;
    });
  }

  function handleChannelChange(e) {
    const { value } = e.target;
    setChannel(value);
    if (!isNameValid(value, 'false')) {
      setNameError(INVALID_NAME_ERROR);
    } else {
      setNameError();
    }
  }

  function handleNewChannel() {
    urlParams.append('new_channel', 'true');
    push(`${pathname}?${urlParams.toString()}`);
    setAddingNewChannel(true);
  }

  const Wrapper = (props: { children: any }) => {
    return inSignUpFlow ? (
      <>{props.children}</>
    ) : (
      <Page noSideNavigation authPage>
        {props.children}
      </Page>
    );
  };

  return (
    <Wrapper>
      <div className="main__channel-creation">
        {hasYoutubeChannels && !addingNewChannel ? (
          <YoutubeTransferStatus alwaysShow addNewChannel={handleNewChannel} />
        ) : (
          <Card
            title={__('Sync your YouTube channel to %site_name%', { site_name: IS_WEB ? SITE_NAME : 'LBRY' })}
            subtitle={__('Get your YouTube videos in front of the %site_name% audience.', {
              site_name: IS_WEB ? SITE_NAME : 'LBRY',
            })}
            actions={
              <Form onSubmit={handleCreateChannel}>
                <fieldset-group class="fieldset-group--smushed fieldset-group--disabled-prefix">
                  <fieldset-section>
                    <label htmlFor="auth_first_channel">
                      {nameError ? (
                        <span className="error__text">{nameError}</span>
                      ) : (
                        __('Your %site_name% channel name', { site_name: IS_WEB ? SITE_NAME : 'LBRY' })
                      )}
                    </label>
                    <div className="form-field__prefix">@</div>
                  </fieldset-section>

                  <FormField
                    autoFocus
                    placeholder={__('channel')}
                    type="text"
                    name="yt_sync_channel"
                    className="form-field--short"
                    value={channel}
                    onChange={handleChannelChange}
                  />
                </fieldset-group>
                <FormField
                  name="language_select"
                  type="select"
                  label={__('Channel language')}
                  onChange={(event) => setLanguage(event.target.value)}
                  value={language}
                >
                  {sortLanguageMap(SUPPORTED_LANGUAGES).map(([langKey, langName]) => (
                    <option key={langKey} value={langKey}>
                      {langName}
                    </option>
                  ))}
                </FormField>
                <FormField
                  type="checkbox"
                  name="yt_sync_terms"
                  checked={acknowledgedTerms}
                  onChange={() => setAcknowledgedTerms(!acknowledgedTerms)}
                  label={
                    <I18nMessage
                      tokens={{
                        terms: (
                          <Button button="link" label={__('these terms')} href="https://lbry.com/faq/youtube-terms" />
                        ),
                        faq: (
                          <Button
                            button="link"
                            label={__('how the program works')}
                            href="https://lbry.com/faq/youtube"
                          />
                        ),
                        site_name: SITE_NAME,
                      }}
                    >
                      I want to sync my content to %site_name% and the LBRY network and agree to %terms%. I have also
                      read and understand %faq%.
                    </I18nMessage>
                  }
                />

                <div className="section__actions">
                  <Button
                    button="primary"
                    type="submit"
                    disabled={nameError || !channel || !acknowledgedTerms}
                    label={__('Claim Now')}
                  />

                  {inSignUpFlow && !errorMessage && (
                    <Button button="link" label={__('Skip')} onClick={() => doToggleInterestedInYoutubeSync()} />
                  )}

                  {errorMessage && <Button button="link" label={__('Skip')} navigate={`/$/${PAGES.REWARDS}`} />}
                </div>
                <div className="help--card-actions">
                  <I18nMessage
                    tokens={{
                      learn_more: <Button button="link" label={__('Learn more')} href="https://lbry.com/faq/youtube" />,
                    }}
                  >
                    This will verify you are an active YouTuber. Channel names cannot be changed once chosen, please be
                    extra careful. Additional instructions will be emailed to you after you verify your email on the
                    next page. %learn_more%.
                  </I18nMessage>
                </div>
              </Form>
            }
            nag={errorMessage && <Nag message={errorMessage} type="error" relative />}
          />
        )}
      </div>
    </Wrapper>
  );
}
