import { type FC, type RefObject, useEffect, useRef, useState } from 'react';
import { Link as RouterLink, type To } from 'react-router-dom';

import { IconAccessPoint, IconEdit, IconX } from '@material-hu/icons/tabler';
import Divider from '@material-hu/mui/Divider';
import IconButton from '@material-hu/mui/IconButton';
import Stack from '@material-hu/mui/Stack';
import Typography from '@material-hu/mui/Typography';

import Button from '@material-hu/components/design-system/Buttons/Button';
import HuTooltip from '@material-hu/components/design-system/Tooltip';

import useHuGoTheme from 'src/hooks/useHuGoTheme';
import { type LiveStreamInsights } from 'src/types/stream';
import { useLokaliseTranslation as useTranslation } from 'src/utils/i18n';

import InsightsAnchorMenu, {
  type InsightsAnchorOptions,
} from './InsightsAnchorMenu';
import InsightsAudience, {
  type InsightsAudienceProps,
} from './InsightsAudience';
import InsightsSummary, { type InsightsSummaryProps } from './InsightsSummary';
import LivestreamInsights from './livestream/LivestreamInsights';
import PostPreview, { type PostPreviewProps } from './PostPreview';

const SIDEBAR_WIDTH = '360px';

export enum ParentOptions {
  POST = 'POST',
  LIVE_STREAM = 'LIVE_STREAM',
}

type PostInsightsProps = {
  onClose: () => void;
  onGoToPostDetail: To;
  postDataQuery: PostPreviewProps['postDataQuery'];
  summaryProps: Pick<
    InsightsSummaryProps,
    'insightSummaryQuery' | 'downloadProps'
  >;
  audienceProps: Pick<InsightsAudienceProps, 'serviceProps' | 'downloadProps'>;
  liveStreamProps: LiveStreamInsights;
};

const PostInsights: FC<PostInsightsProps> = props => {
  const {
    onClose,
    onGoToPostDetail,
    postDataQuery,
    summaryProps,
    audienceProps,
    liveStreamProps,
  } = props;

  const [parentOptionSelected, setParentOptionSelected] =
    useState<ParentOptions>(ParentOptions.POST);
  const [optionSelected, setOptionSelected] = useState(1);
  const summaryRef = useRef(null);
  const audienceRef = useRef(null);
  const liveStreamSummaryRef = useRef<HTMLDivElement>(null);
  const liveStreamAudienceRef = useRef<HTMLDivElement>(null);
  const liveStreamAudiencePerMinuteRef = useRef<HTMLDivElement>(null);
  const liveStreamPlatformsRef = useRef<HTMLDivElement>(null);

  const { t } = useTranslation('post');
  const HuGoThemeProvider = useHuGoTheme();

  const refMap: Record<
    ParentOptions,
    Record<number, RefObject<HTMLDivElement>>
  > = {
    POST: {
      1: summaryRef,
      2: audienceRef,
    },
    LIVE_STREAM: {
      1: liveStreamSummaryRef,
      2: liveStreamAudienceRef,
      3: liveStreamAudiencePerMinuteRef,
      4: liveStreamPlatformsRef,
    },
  };

  const isLivestremPost = Boolean(postDataQuery.data?.data.stream);

  const anchorOptions: InsightsAnchorOptions = [
    {
      id: ParentOptions.POST,
      title: t('post:post_web'),
      Icon: IconEdit,
      items: [
        {
          id: 1,
          title: t('summary'),
        },
        {
          id: 2,
          title: t('post:audience_web'),
        },
      ],
    },
    ...(isLivestremPost
      ? [
          {
            id: ParentOptions.LIVE_STREAM,
            title: t('general:liveStream'),
            Icon: IconAccessPoint,
            items: [
              {
                id: 1,
                title: t('summary'),
              },
              {
                id: 2,
                title: t('post:audience_web'),
              },
              {
                id: 4,
                title: t('post:platforms'),
              },
            ],
          },
        ]
      : []),
  ];

  useEffect(() => {
    const refs = refMap[parentOptionSelected];
    const refEntries = Object.entries(refs);

    const elementToIdMap = new Map();
    refEntries.forEach(([id, ref]) => {
      if (ref.current) {
        elementToIdMap.set(ref.current, Number(id));
      }
    });

    const elements = Array.from(elementToIdMap.keys());

    const observer = new IntersectionObserver(
      entries => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            const optionId = elementToIdMap.get(entry.target);
            if (optionId) {
              setOptionSelected(optionId);
            }
          }
        });
      },
      { root: null, rootMargin: '0px', threshold: 1 },
    );

    elements.forEach(element => observer.observe(element));

    return () => observer.disconnect();
  }, [parentOptionSelected]);

  const handleOptionClick = (optionId: number, parentId: ParentOptions) => {
    setParentOptionSelected(parentId);
    setOptionSelected(optionId);

    requestAnimationFrame(() => {
      const targetRef = refMap[parentId]?.[optionId];
      if (targetRef?.current) {
        targetRef.current.scrollIntoView({
          behavior: 'smooth',
          block: 'center',
        });
      }
    });
  };

  return (
    <HuGoThemeProvider>
      <Stack
        sx={{
          height: '100vh',
          display: 'flex',
          flexDirection: 'column',
          overflow: 'hidden',
        }}
      >
        <Stack
          sx={{
            flexDirection: 'row',
            alignItems: 'center',
            justifyContent: 'space-between',
            backgroundColor: theme =>
              theme.palette.new.background.layout.tertiary,
            py: 1.5,
            px: 3,
            gap: 2,
            flexShrink: 0,
          }}
        >
          <Typography
            variant="globalL"
            fontWeight="fontWeightSemiBold"
            color="textPrimary"
          >
            {t('INSIGHTS')}
          </Typography>
          <HuTooltip
            description={t('CLOSE')}
            direction="left"
          >
            <IconButton
              aria-label={t('CLOSE')}
              onClick={onClose}
            >
              <IconX />
            </IconButton>
          </HuTooltip>
        </Stack>
        <Divider />
        <Stack
          sx={{
            flexDirection: 'row',
            backgroundColor: theme =>
              theme.palette.new.background.layout.default,
            flex: 1,
            overflow: 'hidden',
          }}
        >
          <Stack
            sx={{
              backgroundColor: theme =>
                theme.palette.new.background.layout.tertiary,
              borderRight: ({ palette }) =>
                `1px solid ${palette.new.border.neutral.default}`,
              width: SIDEBAR_WIDTH,
              py: 1.5,
              overflowY: 'auto',
              flexShrink: 0,
            }}
          >
            <Stack sx={{ px: 1.5, gap: 1.5 }}>
              <PostPreview postDataQuery={postDataQuery} />
              <Stack sx={{ flexDirection: 'row' }}>
                <Button
                  component={RouterLink}
                  to={onGoToPostDetail}
                  variant="tertiary"
                  sx={{ p: 0.25 }}
                >
                  {t('go_to_post')}
                </Button>
              </Stack>
              <Divider />
            </Stack>
            <Stack sx={{ pt: 2 }}>
              <InsightsAnchorMenu
                options={anchorOptions}
                onClick={handleOptionClick}
                parentOptionSelected={parentOptionSelected}
                optionSelected={optionSelected}
              />
            </Stack>
          </Stack>
          <Stack
            sx={{
              flexDirection: 'column',
              height: '100%',
              alignItems: 'center',
              overflowY: 'auto',
              py: 5,
              px: 3,
              width: '100%',
            }}
          >
            <Stack
              sx={theme => ({
                maxWidth: '1040px',
                width: '100%',
                gap: 4,
                [theme.breakpoints.down('lg')]: {
                  maxWidth: '650px',
                },
                [theme.breakpoints.down('md')]: {
                  maxWidth: '450px',
                },
              })}
            >
              {parentOptionSelected === 'POST' && (
                <>
                  <InsightsSummary
                    ref={summaryRef}
                    {...summaryProps}
                  />
                  <InsightsAudience
                    ref={audienceRef}
                    {...audienceProps}
                  />
                </>
              )}
              {parentOptionSelected === 'LIVE_STREAM' && (
                <LivestreamInsights
                  insights={liveStreamProps}
                  summaryRef={liveStreamSummaryRef}
                  audienceRef={liveStreamAudienceRef}
                  audiencePerMinuteRef={liveStreamAudiencePerMinuteRef}
                  platformsRef={liveStreamPlatformsRef}
                />
              )}
            </Stack>
          </Stack>
        </Stack>
      </Stack>
    </HuGoThemeProvider>
  );
};

export default PostInsights;
