import { useCallback, useState } from 'react';

import type { ClickableProps } from '~/src/components/Clickable';
import type { PageProps } from '~/src/components/Page';
import type { SelectedAnalytics } from '~/src/store/dashboard/selectors/analytics';
import type { SelectedCustomPage, SelectedItem } from '~/src/store/types';
import type { ReactNode } from 'react';
import type { AnalyticsRangePresets } from '../types';

import { PageTypes } from '~/lib/types';
import Box from '~/src/components/Box';
import Clickable from '~/src/components/Clickable';
import ClickableModalActions from '~/src/components/ClickableActionsModal';
import FadeOnMount from '~/src/components/FadeOnMount';
import MoreIcon from '~/src/components/Icon/MoreIcon';
import BackgroundImage from '~/src/components/Image/BackgroundImage';
import { useAppToast } from '~/src/components/NextApp/lib/CoreUi';
import Page from '~/src/components/Page';
import { ICON_SIZE } from '~/src/components/PageHeader';
import PageMetadata from '~/src/components/PageMetadata';
import Text from '~/src/components/Text';
import useIsLargeScreen from '~/src/hooks/useIsLargeScreen';
import useTheme from '~/src/hooks/useTheme';
import { useI18n } from '~/src/lib/i18n';
import toShortUrl from '~/src/lib/toShortUrl';
import { useTracker } from '~/src/lib/tracker/useTracker';
import copyToClipboard from '~/src/lib/utils/copyToClipboard';
import { DEFAULT_DAYS } from '../constants';
import TimelineHero from '../TimelineHero';
import useFetchDashboardData from '../useFetchDashboardData';

interface DashboardItemPageProps
  extends Pick<PageProps, 'trackPageView' | 'trackerContext'> {
  item: SelectedItem | SelectedCustomPage;
  renderContent: (analytics: SelectedAnalytics) => ReactNode;
  rangePresets: AnalyticsRangePresets;
}

const DashboardItemPage = ({
  item,
  renderContent,
  rangePresets,
  ...pageProps
}: DashboardItemPageProps) => {
  const { pageBrand, image, pagePath } = item;

  const { t } = useI18n('dashboard');
  const [range, setRange] = useState<keyof typeof rangePresets>('default');
  const isLargeScreen = useIsLargeScreen();
  const { trackEvent } = useTracker();
  const toast = useAppToast();
  const theme = useTheme();

  const { isLoading, analytics, analyticsError, refetchAnalytics } =
    useFetchDashboardData({
      item,
      days: rangePresets[range],
    });

  return (
    <Page
      pageType={PageTypes.ANALYTICS}
      withMenuButton
      withBackButton
      renderHeaderContent={() => (
        <Text size="1.5rem" isBold color={theme.textColor40}>
          {t('labels.dashboard')}
        </Text>
      )}
      renderHeaderRight={useCallback(
        () => (
          <Box flexRow alignCenter fullHeight>
            {isLargeScreen && (
              <Clickable
                testId="visitPage"
                href={pagePath}
                // pagePath defined once the item has been fetched
                isDisabled={!pagePath}
                margin="0 .7rem 0 0"
              >
                <Text isBold size="1.6rem" color={theme.textColor90}>
                  {t('actions.visitPage')}
                </Text>
              </Clickable>
            )}
            <ClickableModalActions
              testId="pageActions"
              isInline
              // pagePath defined once the item has been fetched
              isDisabled={!pagePath}
              items={[
                {
                  testId: 'actionVisitPage',
                  content: t('actions.visitPage'),
                  href: pagePath,
                },
                {
                  testId: 'actionEditPage',
                  content: t('actions.editPage'),
                  href: `${pagePath}/edit`,
                },
                {
                  testId: 'actionCopyLink',
                  content: t('actions.copyLink'),
                  onClick: () => {
                    if (!pagePath) return;

                    const shortUrl = toShortUrl({
                      pagePath,
                      pageBrand,
                    });

                    copyToClipboard(shortUrl);

                    trackEvent({
                      type: 'link-copied',
                      linkType: 'general',
                    });

                    toast({
                      text: t('events.copiedShortLink', { shortUrl }),
                    });
                  },
                },
              ]}
            >
              <MoreIcon
                direction="left"
                size={ICON_SIZE}
                margin="0 -0.2em 0 0"
              />
            </ClickableModalActions>
          </Box>
        ),
        [pagePath, isLargeScreen]
      )}
      contentStyle={{
        fontSize: 15,
        paddingTop: 60,
      }}
      renderBackground={useCallback(
        () =>
          image ? (
            <BackgroundImage
              testId="backgroundImage"
              src={image}
              alt={t('backgroundImageAlt')}
              objectPosition="50% 40%"
              gradient="linear-gradient(0deg,rgba(0,0,0,1) 0%,rgba(0,0,0,.30) 100%)"
              fadeInDuration={800}
              coverParent
              style={{ opacity: 0.2 }}
              cover
            />
          ) : undefined,
        [image]
      )}
      {...pageProps}
    >
      <Box
        testId="dashboardRanges"
        flexBox
        justifyCenter
        alignCenter
        gap="1rem"
        margin="5rem 0 2rem"
        style={{ fontSize: '1.5rem', color: '#555' }}
      >
        <ToggleButton
          testId="defaultRangeButton"
          text={t('days', { days: DEFAULT_DAYS })}
          isSelected={range === 'default'}
          isDisabled={isLoading}
          onClick={() => {
            setRange('default');
          }}
        />
        <div style={{ fontWeight: 'bold' }}>·</div>
        <ToggleButton
          testId="lifetimeRangeButton"
          text={t('allTime')}
          isSelected={range === 'lifetime'}
          isDisabled={isLoading}
          onClick={() => {
            setRange('lifetime');
          }}
        />
      </Box>
      <TimelineHero
        isLoading={isLoading}
        analytics={analytics}
        error={analyticsError}
        onRetry={refetchAnalytics}
        renderDefaultText={({ totalDays }) =>
          t('visitsToPagePastDays', { totalDays })
        }
      />
      {(() => {
        if (isLoading || !analytics) return;

        return (
          <Box
            style={{ fontSize: 15, background: theme.background }}
            padding={`80 ${isLargeScreen ? 40 : 20} 200`}
          >
            <FadeOnMount>
              <div>{renderContent(analytics)}</div>
            </FadeOnMount>
          </Box>
        );
      })()}
      <PageMetadata title={t('labels.dashboard')} />
    </Page>
  );
};

const ToggleButton = ({
  isSelected,
  text,
  ...clickableProps
}: {
  isSelected: boolean;
  text: string;
} & ClickableProps) => (
  <Clickable padding="0.3rem 0" isInline {...clickableProps}>
    <Text isBold color={isSelected ? '#fff' : undefined}>
      {text}
    </Text>
  </Clickable>
);

export default DashboardItemPage;
