// @flow
import * as ICONS from 'constants/icons';
import * as PAGES from 'constants/pages';
import React from 'react';
import { parseURI } from 'lbry-redux';
import { YOUTUBE_STATUSES } from 'lbryinc';
import Page from 'component/page';
import SubscribeButton from 'component/subscribeButton';
import ShareButton from 'component/shareButton';
import { Tabs, TabList, Tab, TabPanels, TabPanel } from 'component/common/tabs';
import { useHistory } from 'react-router';
import Button from 'component/button';
import { formatLbryUrlForWeb } from 'util/url';
import ChannelContent from 'component/channelContent';
import ChannelAbout from 'component/channelAbout';
import ChannelDiscussion from 'component/channelDiscussion';
import ChannelThumbnail from 'component/channelThumbnail';
import ChannelEdit from 'component/channelEdit';
import classnames from 'classnames';
import HelpLink from 'component/common/help-link';
import ClaimSupportButton from 'component/claimSupportButton';
import ChannelStakedIndicator from 'component/channelStakedIndicator';
import ClaimMenuList from 'component/claimMenuList';
import OptimizedImage from 'component/optimizedImage';
import Yrbl from 'component/yrbl';
import I18nMessage from 'component/i18nMessage';
import TruncatedText from 'component/common/truncated-text';
// $FlowFixMe cannot resolve ...
import PlaceholderTx from 'static/img/placeholderTx.gif';

export const PAGE_VIEW_QUERY = `view`;
export const DISCUSSION_PAGE = `discussion`;

const PAGE = {
  CONTENT: 'content',
  LISTS: 'lists',
  ABOUT: 'about',
  DISCUSSION: DISCUSSION_PAGE,
  EDIT: 'edit',
};

type Props = {
  uri: string,
  claim: ChannelClaim,
  title: ?string,
  cover: ?string,
  thumbnail: ?string,
  page: number,
  match: { params: { attribute: ?string } },
  channelIsMine: boolean,
  isSubscribed: boolean,
  channelIsBlocked: boolean,
  blackListedOutpoints: Array<{
    txid: string,
    nout: number,
  }>,
  fetchSubCount: (string) => void,
  subCount: number,
  pending: boolean,
  youtubeChannels: ?Array<{ channel_claim_id: string, sync_status: string, transfer_state: string }>,
  blockedChannels: Array<string>,
  mutedChannels: Array<string>,
  unpublishedCollections: CollectionGroup,
};

function ChannelPage(props: Props) {
  const {
    uri,
    claim,
    title,
    cover,
    // page, ?page= may come back some day?
    channelIsMine,
    isSubscribed,
    blackListedOutpoints,
    fetchSubCount,
    subCount,
    pending,
    youtubeChannels,
    blockedChannels,
    mutedChannels,
    unpublishedCollections,
  } = props;
  const {
    push,
    goBack,
    location: { search },
  } = useHistory();
  const [viewBlockedChannel, setViewBlockedChannel] = React.useState(false);
  const urlParams = new URLSearchParams(search);
  const currentView = urlParams.get(PAGE_VIEW_QUERY) || PAGE.CONTENT;
  const [discussionWasMounted, setDiscussionWasMounted] = React.useState(false);
  const editing = urlParams.get(PAGE_VIEW_QUERY) === PAGE.EDIT;
  const { channelName } = parseURI(uri);
  const { permanent_url: permanentUrl } = claim;
  const claimId = claim.claim_id;
  const formattedSubCount = Number(subCount).toLocaleString();
  const isBlocked = claim && blockedChannels.includes(claim.permanent_url);
  const isMuted = claim && mutedChannels.includes(claim.permanent_url);
  const isMyYouTubeChannel =
    claim &&
    youtubeChannels &&
    youtubeChannels.some(({ channel_claim_id, sync_status, transfer_state }) => {
      if (
        channel_claim_id === claim.claim_id &&
        sync_status !== YOUTUBE_STATUSES.YOUTUBE_SYNC_ABANDONDED &&
        transfer_state !== YOUTUBE_STATUSES.YOUTUBE_SYNC_COMPLETED_TRANSFER
      ) {
        return true;
      }
    });

  const hasUnpublishedCollections = unpublishedCollections && Object.keys(unpublishedCollections).length;

  let collectionEmpty;
  if (channelIsMine) {
    collectionEmpty = hasUnpublishedCollections ? (
      <section className="main--empty">
        {
          <p>
            <I18nMessage
              tokens={{
                pick: <Button button="link" navigate={`/$/${PAGES.LISTS}`} label={__('Pick')} />,
              }}
            >
              You have unpublished lists! %pick% one and publish it!
            </I18nMessage>
          </p>
        }
      </section>
    ) : (
      <section className="main--empty">{__('You have no lists! Create one from any playable content.')}</section>
    );
  } else {
    collectionEmpty = <section className="main--empty">{__('No Lists Found')}</section>;
  }

  let channelIsBlackListed = false;

  if (claim && blackListedOutpoints) {
    channelIsBlackListed = blackListedOutpoints.some(
      (outpoint) => outpoint.txid === claim.txid && outpoint.nout === claim.nout
    );
  }

  // If a user changes tabs, update the url so it stays on the same page if they refresh.
  // We don't want to use links here because we can't animate the tab change and using links
  // would alter the Tab label's role attribute, which should stay role="tab" to work with keyboards/screen readers.
  let tabIndex;
  switch (currentView) {
    case PAGE.CONTENT:
      tabIndex = 0;
      break;
    case PAGE.LISTS:
      tabIndex = 1;
      break;
    case PAGE.ABOUT:
      tabIndex = 2;
      break;
    case PAGE.DISCUSSION:
      tabIndex = 3;
      break;
    default:
      tabIndex = 0;
      break;
  }

  function onTabChange(newTabIndex) {
    let url = formatLbryUrlForWeb(uri);
    let search = '?';

    if (newTabIndex === 0) {
      search += `${PAGE_VIEW_QUERY}=${PAGE.CONTENT}`;
    } else if (newTabIndex === 1) {
      search += `${PAGE_VIEW_QUERY}=${PAGE.LISTS}`;
    } else if (newTabIndex === 2) {
      search += `${PAGE_VIEW_QUERY}=${PAGE.ABOUT}`;
    } else {
      search += `${PAGE_VIEW_QUERY}=${PAGE.DISCUSSION}`;
    }

    push(`${url}${search}`);
  }

  React.useEffect(() => {
    if (currentView === PAGE.DISCUSSION) {
      setDiscussionWasMounted(true);
    }
  }, [currentView]);

  React.useEffect(() => {
    fetchSubCount(claimId);
  }, [uri, fetchSubCount, claimId]);

  if (editing) {
    return (
      <Page
        noFooter
        noSideNavigation={editing}
        backout={{
          title: __('Editing @%channel%', { channel: channelName }),
          simpleTitle: __('Editing'),
        }}
      >
        <ChannelEdit uri={uri} onDone={() => goBack()} />
      </Page>
    );
  }

  return (
    <Page noFooter>
      <header className="channel-cover">
        <div className="channel__quick-actions">
          {isMyYouTubeChannel && (
            <Button
              button="alt"
              label={__('Claim Your Channel')}
              icon={ICONS.YOUTUBE}
              navigate={`/$/${PAGES.CHANNELS}`}
            />
          )}
          {!channelIsBlackListed && <ShareButton uri={uri} />}
          {!(isBlocked || isMuted) && <ClaimSupportButton uri={uri} />}
          {!(isBlocked || isMuted) && (!channelIsBlackListed || isSubscribed) && <SubscribeButton uri={permanentUrl} />}
          {/* TODO: add channel collections <ClaimCollectionAddButton uri={uri} fileAction /> */}
          <ClaimMenuList uri={claim.permanent_url} inline isChannelPage />
        </div>
        {cover && <img className={classnames('channel-cover__custom')} src={PlaceholderTx} />}
        {cover && <OptimizedImage className={classnames('channel-cover__custom')} src={cover} objectFit="cover" />}
        <div className="channel__primary-info">
          <ChannelThumbnail className="channel__thumbnail--channel-page" uri={uri} allowGifs hideStakedIndicator />
          <h1 className="channel__title">
            <TruncatedText lines={2} showTooltip>
              {title || '@' + channelName}
            </TruncatedText>
            <ChannelStakedIndicator uri={uri} large />
          </h1>
          <div className="channel__meta">
            <span>
              {formattedSubCount} {subCount !== 1 ? __('Followers') : __('Follower')}
              <HelpLink href="https://lbry.com/faq/views" />
            </span>
            {channelIsMine && (
              <>
                {pending ? (
                  <span>{__('Your changes will be live in a few minutes')}</span>
                ) : (
                  <Button
                    button="alt"
                    title={__('Edit')}
                    onClick={() => push(`?${PAGE_VIEW_QUERY}=${PAGE.EDIT}`)}
                    icon={ICONS.EDIT}
                    iconSize={18}
                    disabled={pending}
                  />
                )}
              </>
            )}
          </div>
        </div>
        <div className="channel-cover__gradient" />
      </header>

      {(isBlocked || isMuted) && !viewBlockedChannel ? (
        <div className="main--empty">
          <Yrbl
            title={isBlocked ? __('This channel is blocked') : __('This channel is muted')}
            subtitle={
              isBlocked
                ? __('Are you sure you want to view this content? Viewing will not unblock @%channel%', {
                    channel: channelName,
                  })
                : __('Are you sure you want to view this content? Viewing will not unmute @%channel%', {
                    channel: channelName,
                  })
            }
            actions={
              <div className="section__actions">
                <Button button="primary" label={__('View Content')} onClick={() => setViewBlockedChannel(true)} />
              </div>
            }
          />
        </div>
      ) : (
        <Tabs onChange={onTabChange} index={tabIndex}>
          <TabList className="tabs__list--channel-page">
            <Tab disabled={editing}>{__('Content')}</Tab>
            <Tab disabled={editing}>{__('Playlists')}</Tab>
            <Tab>{editing ? __('Editing Your Channel') : __('About --[tab title in Channel Page]--')}</Tab>
            <Tab disabled={editing}>{__('Community')}</Tab>
          </TabList>
          <TabPanels>
            <TabPanel>
              {currentView === PAGE.CONTENT && (
                <ChannelContent
                  uri={uri}
                  channelIsBlackListed={channelIsBlackListed}
                  viewHiddenChannels
                  empty={<section className="main--empty">{__('No Content Found')}</section>}
                />
              )}
            </TabPanel>
            <TabPanel>
              {currentView === PAGE.LISTS && (
                <ChannelContent
                  claimType={'collection'}
                  uri={uri}
                  channelIsBlackListed={channelIsBlackListed}
                  viewHiddenChannels
                  empty={collectionEmpty}
                />
              )}
            </TabPanel>
            <TabPanel>
              <ChannelAbout uri={uri} />
            </TabPanel>
            <TabPanel>
              {(discussionWasMounted || currentView === PAGE.DISCUSSION) && <ChannelDiscussion uri={uri} />}
            </TabPanel>
          </TabPanels>
        </Tabs>
      )}
    </Page>
  );
}

export default ChannelPage;
