import * as React from 'react';
import { InferGetStaticPropsType } from 'next';
import { useRouter } from 'next/router';
import Avatar from '@mui/material/Avatar';
import AvatarGroup from '@mui/material/AvatarGroup';
import Box from '@mui/material/Box';
import Container from '@mui/material/Container';
import Divider from '@mui/material/Divider';
import Typography from '@mui/material/Typography';
import Paper from '@mui/material/Paper';
import Pagination from '@mui/material/Pagination';
import Button from '@mui/material/Button';
import KeyboardArrowRightRoundedIcon from '@mui/icons-material/KeyboardArrowRightRounded';
import Chip from '@mui/material/Chip';
import XIcon from '@mui/icons-material/X';
import GitHubIcon from '@mui/icons-material/GitHub';
import LinkedInIcon from '@mui/icons-material/LinkedIn';
import YouTubeIcon from '@mui/icons-material/YouTube';
import DiscordIcon from 'docs/src/icons/DiscordIcon';
import Head from 'docs/src/modules/components/Head';
import AppHeader from 'docs/src/layouts/AppHeader';
import AppFooter from 'docs/src/layouts/AppFooter';
import GradientText from 'docs/src/components/typography/GradientText';
import BrandingCssVarsProvider from 'docs/src/BrandingCssVarsProvider';
import { authors as AUTHORS } from 'docs/src/modules/components/TopLayoutBlog';
import HeroEnd from 'docs/src/components/home/HeroEnd';
import { Link } from '@mui/docs/Link';
import generateRssFeed from 'docs/scripts/generateRSSFeed';
import Section from 'docs/src/layouts/Section';
import SectionHeadline from 'docs/src/components/typography/SectionHeadline';
import { getAllBlogPosts, BlogPost } from 'docs/lib/sourcing';

export const getStaticProps = () => {
  const data = getAllBlogPosts();
  generateRssFeed(data.allBlogPosts);
  return {
    props: data,
  };
};

function PostPreview(props: BlogPost) {
  return (
    <React.Fragment>
      <Box sx={{ display: 'flex', gap: 0.5, mb: 1.5 }}>
        {props.tags.map((tag) => (
          <Chip
            key={tag}
            label={tag}
            size="small"
            variant="outlined"
            color="primary"
            sx={(theme) => ({
              height: 22,
              fontWeight: 'medium',
              fontSize: theme.typography.pxToRem(13),
              '& .MuiChip-label': {
                px: '6px',
              },
              ...theme.applyDarkStyles({
                color: (theme.vars || theme).palette.grey[200],
              }),
            })}
          />
        ))}
      </Box>
      <Typography component="h2" variant="subtitle1" gutterBottom sx={{ fontWeight: 'bold' }}>
        <Link
          aria-describedby={`describe-${props.slug}`}
          href={`/blog/${props.slug}/`}
          sx={{
            color: 'text.primary',

            '&:hover': {
              textDecoration: 'underline',
            },
          }}
        >
          {props.title}
        </Link>
      </Typography>
      <Typography sx={{ color: 'text.secondary', mb: 'auto' }}>{props.description}</Typography>
      {props.authors && (
        <AvatarGroup
          sx={(theme) => ({
            mt: 2,
            mb: 1,
            alignSelf: 'flex-start',
            '& .MuiAvatar-circular': {
              width: 28,
              height: 28,
              fontSize: theme.typography.pxToRem(13),
              fontWeight: theme.typography.fontWeightSemiBold,
              color: (theme.vars || theme).palette.text.primary,
              border: `1px solid ${(theme.vars || theme).palette.divider}`,
              outline: '3px solid',
              outlineColor: '#FFF',
              backgroundColor: (theme.vars || theme).palette.grey[100],
            },
            ...theme.applyDarkStyles({
              '& .MuiAvatar-circular': {
                outlineColor: (theme.vars || theme).palette.primaryDark[900],
                backgroundColor: (theme.vars || theme).palette.primaryDark[700],
              },
            }),
          })}
        >
          {(props.authors as Array<keyof typeof AUTHORS>).map((author) => (
            <Avatar
              key={author}
              alt=""
              src={`${AUTHORS[author].avatar}?s=${28}`}
              srcSet={`${AUTHORS[author].avatar}?s=${28 * 2} 2x, ${AUTHORS[author].avatar}?s=${
                28 * 3
              } 3x`}
            />
          ))}
        </AvatarGroup>
      )}
      <Box
        sx={{
          display: { sm: 'block', md: 'flex' },
          justifyContent: 'space-between',
          alignItems: 'end',
        }}
      >
        <Box sx={{ position: 'relative' }}>
          {props.authors && (
            <Typography variant="body2" sx={{ fontWeight: 'medium' }}>
              {props.authors
                .slice(0, 3)
                .map((userId) => {
                  const name = AUTHORS[userId as keyof typeof AUTHORS]?.name;
                  if (name) {
                    if (props.authors && props.authors.length > 1) {
                      // display only firstName
                      return name.split(' ')[0];
                    }
                    return name;
                  }
                  return userId;
                })
                .join(', ')}
              {props.authors.length > 2 && ', and more.'}
            </Typography>
          )}
          {props.date && (
            <Typography variant="caption" sx={{ fontWeight: 'regular', color: 'text.tertiary' }}>
              {new Date(props.date).toDateString()}
            </Typography>
          )}
        </Box>
        <Button
          component={Link}
          aria-describedby={`describe-${props.slug}`}
          href={`/blog/${props.slug}`}
          id={`describe-${props.slug}`}
          endIcon={<KeyboardArrowRightRoundedIcon />}
          size="small"
          sx={{ mt: { xs: 0.5, md: 0 }, p: { xs: 0, sm: '6px 8px' } }}
        >
          Read more
        </Button>
      </Box>
    </React.Fragment>
  );
}

const PAGE_SIZE = 7;

export default function Blog(props: InferGetStaticPropsType<typeof getStaticProps>) {
  const router = useRouter();
  const postListRef = React.useRef<HTMLDivElement>(null);
  const [page, setPage] = React.useState(0);
  const [selectedTags, setSelectedTags] = React.useState<Record<string, boolean>>({});
  const { allBlogPosts, tagInfo: rawTagInfo } = props;
  const [firstPost, secondPost, ...otherPosts] = allBlogPosts;
  const tagInfo = { ...rawTagInfo };
  [firstPost, secondPost].forEach((post) => {
    post.tags.forEach((tag) => {
      if (tagInfo[tag]) {
        tagInfo[tag]! -= 1;
      }
    });
  });
  Object.entries(tagInfo).forEach(([tagName, tagCount]) => {
    if (tagCount === 0) {
      delete tagInfo[tagName];
    }
  });
  const filteredPosts = otherPosts.filter((post) => {
    if (Object.keys(selectedTags).length === 0) {
      return true;
    }

    return post.tags.some((tag) => {
      return Object.keys(selectedTags).includes(tag);
    });
  });
  const pageStart = page * PAGE_SIZE;
  const totalPage = Math.ceil(filteredPosts.length / PAGE_SIZE);
  const displayedPosts = filteredPosts.slice(pageStart, pageStart + PAGE_SIZE);
  const getTags = React.useCallback(() => {
    const { tags = '' } = router.query;
    return (typeof tags === 'string' ? tags.split(',') : tags || [])
      .map((str) => str.trim())
      .filter((tag) => !!tag);
  }, [router.query]);

  React.useEffect(() => {
    const arrayTags = getTags();
    const finalTags: Record<string, boolean> = {};
    arrayTags.forEach((tag) => {
      finalTags[tag] = true;
    });
    setSelectedTags(finalTags);
    setPage(0);
  }, [getTags]);

  const removeTag = (tag: string) => {
    router.push(
      {
        query: {
          ...router.query,
          tags: getTags().filter((value) => value !== tag),
        },
      },
      undefined,
      { shallow: true },
    );
  };

  return (
    <BrandingCssVarsProvider>
      <Head
        title="Blog - MUI"
        description="Follow the MUI blog to learn about new product features, latest advancements in UI development, and business initiatives."
        card="/static/social-previews/blog-preview.jpg"
        disableAlternateLocale
      />
      <AppHeader />
      <main id="main-content">
        <Section cozy bg="gradient">
          <SectionHeadline
            alwaysCenter
            overline="Blog"
            title={
              <Typography variant="h2" component="h1">
                Stay <GradientText>in the loop</GradientText> with
                <br /> the latest about MUI&apos;s products
              </Typography>
            }
          />
        </Section>
        <Divider />
        <Container sx={{ mt: { xs: 2, sm: -6 } }}>
          <Box
            component="ul"
            sx={{
              display: 'grid',
              m: 0,
              p: 0,
              gap: 2,
              gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))',
            }}
          >
            {[firstPost, secondPost].map((post) => (
              <Paper
                key={post.slug}
                component="li"
                variant="outlined"
                sx={(theme) => ({
                  p: 2,
                  display: 'flex',
                  flexDirection: 'column',
                  backgroundImage: (theme.vars || theme).palette.gradients.radioSubtle,
                  boxShadow: '0 4px 12px rgba(170, 180, 190, 0.2)',
                  ...theme.applyDarkStyles({
                    background: (theme.vars || theme).palette.primaryDark[900],
                    backgroundImage: (theme.vars || theme).palette.gradients.radioSubtle,
                    boxShadow: '0 4px 12px rgba(0, 0, 0, 0.4)',
                  }),
                })}
              >
                {post.image && (
                  <Box
                    component="img"
                    src={post.image}
                    sx={{
                      aspectRatio: '16 / 9',
                      width: '100%',
                      height: 'auto',
                      objectFit: 'cover',
                      borderRadius: '4px',
                    }}
                  />
                )}
                <PostPreview {...post} />
              </Paper>
            ))}
          </Box>
        </Container>
        <Container
          ref={postListRef}
          sx={{
            py: { xs: 4, sm: 6, md: 8 },
            mt: -6,
            display: 'grid',
            gridTemplateColumns: { md: '1fr 380px' },
            columnGap: 8,
          }}
        >
          <Typography
            component="h2"
            variant="h6"
            sx={{ fontWeight: 'semiBold', mb: { xs: 1, sm: 2 }, mt: 8 }}
          >
            Posts{' '}
            {Object.keys(selectedTags).length ? (
              <span>
                tagged as{' '}
                <Typography component="span" variant="inherit" color="primary" noWrap>
                  &quot;{Object.keys(selectedTags)[0]}&quot;
                </Typography>
              </span>
            ) : (
              ''
            )}
          </Typography>
          <Box sx={{ gridRow: 'span 2' }}>
            <Box
              sx={{
                position: 'sticky',
                top: 90,
                mt: { xs: 0, md: 9 },
                mb: { xs: 2, md: 0 },
                display: 'flex',
                flexDirection: 'column',
                gap: 2,
                '& .MuiPaper-root': {
                  p: 2,
                  bgcolor: 'transparent',
                  borderColor: 'divider',
                },
              }}
            >
              <Paper variant="outlined">
                <Typography
                  component="h3"
                  variant="subtitle2"
                  sx={{ color: 'text.primary', fontWeight: 'semiBold', mb: 2 }}
                >
                  Filter posts by tag
                </Typography>
                <Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
                  {Object.keys(tagInfo).map((tag) => {
                    const selected = !!selectedTags[tag];
                    return (
                      <Chip
                        key={tag}
                        variant={selected ? 'filled' : 'outlined'}
                        color={selected ? 'primary' : undefined}
                        {...(selected
                          ? {
                              label: tag,
                              onDelete: () => {
                                postListRef.current?.scrollIntoView();
                                removeTag(tag);
                              },
                            }
                          : {
                              label: tag,
                              onClick: () => {
                                postListRef.current?.scrollIntoView();
                                router.push(
                                  {
                                    query: {
                                      ...router.query,
                                      tags: tag,
                                    },
                                  },
                                  undefined,
                                  { shallow: true },
                                );
                              },
                            })}
                        size="small"
                      />
                    );
                  })}
                </Box>
              </Paper>
              <Paper variant="outlined">
                <Typography
                  component="h3"
                  variant="subtitle2"
                  gutterBottom
                  sx={{ color: 'text.primary', fontWeight: 'semiBold' }}
                >
                  Want to hear more from us?
                </Typography>
                <Typography variant="body2" sx={{ color: 'text.secondary', mb: 2 }}>
                  Get up to date with everything MUI-related through our social media:
                </Typography>
                <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 2, '* > svg': { mr: 1 } }}>
                  <Link href="https://github.com/mui" target="_blank" sx={{ fontSize: 14 }}>
                    <GitHubIcon fontSize="small" />
                    GitHub
                  </Link>
                  <Link href="https://x.com/MUI_hq" target="_blank" sx={{ fontSize: 14 }}>
                    <XIcon fontSize="small" />X
                  </Link>
                  <Link href="https://mui.com/r/discord/" target="_blank" sx={{ fontSize: 14 }}>
                    <DiscordIcon fontSize="small" />
                    Discord
                  </Link>
                  <Link
                    href="https://www.linkedin.com/company/mui/"
                    target="_blank"
                    sx={{ fontSize: 14 }}
                  >
                    <LinkedInIcon fontSize="small" />
                    LinkedIn
                  </Link>
                  <Link
                    href="https://www.youtube.com/@MUI_hq"
                    target="_blank"
                    sx={{ fontSize: 14 }}
                  >
                    <YouTubeIcon fontSize="small" />
                    Youtube
                  </Link>
                </Box>
              </Paper>
            </Box>
          </Box>
          <div>
            <Box component="ul" sx={{ p: 0, m: 0 }}>
              {displayedPosts.map((post) => (
                <Box
                  component="li"
                  key={post.slug}
                  sx={{
                    py: 2.5,
                    display: 'flex',
                    flexDirection: 'column',
                    position: 'relative',
                    '&:not(:last-of-type)': {
                      borderBottom: '1px solid',
                      borderColor: 'divider',
                    },
                  }}
                >
                  <PostPreview {...post} />
                </Box>
              ))}
            </Box>
            <Pagination
              page={page + 1}
              count={totalPage}
              variant="outlined"
              shape="rounded"
              onChange={(_, value) => {
                setPage(value - 1);
                postListRef.current?.scrollIntoView();
              }}
              sx={{ mt: 1, mb: 4 }}
            />
          </div>
        </Container>
      </main>
      <Divider />
      <HeroEnd />
      <Divider />
      <AppFooter />
    </BrandingCssVarsProvider>
  );
}
