// @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 'util/lbryURI';
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)) {
      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 desired %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://odysee.com/$/youtubetos" />
                        ),
                        faq: (
                          <Button
                            button="link"
                            label={__('how the program works')}
                            href="https://odysee.com/@OdyseeHelp:b/youtube-sync:b"
                          />
                        ),
                        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://odysee.com/@OdyseeHelp:b/youtube-sync:b"
                        />
                      ),
                    }}
                  >
                    This will verify you are an active YouTuber with over 300 subscribers and original content. Channel
                    names cannot be changed once chosen, please be extra careful. %learn_more%.
                  </I18nMessage>
                </div>
              </Form>
            }
            nag={errorMessage && <Nag message={errorMessage} type="error" relative />}
          />
        )}
      </div>
    </Wrapper>
  );
}
