import React, { ReactElement, useEffect, useState } from 'react';
import useStyles from './style';
import { useDispatch } from 'react-redux';
import {
  removeMessage,
  fetchBlog,
  publishBlog,
  unpublishBlog,
  fetchSubmittedBlogs,
  fetchPublishedBlogs,
  clearBlog,
} from './actions';
import { useStateSelector } from '@core/reducers';
import Snackbar from '@ui/common/snackbar';
import NotFound from '@ui/notfound';
import ConfirmationDialog from '@ui/common/confirmation';
import {
  Tab,
  AppBar,
  Tabs,
  LinearProgress,
  Grid,
  List,
  ListItem,
  Typography,
  Chip,
  Button,
  Link,
  CardHeader,
  Avatar,
} from '@material-ui/core';
import { BlogDetail, Author } from 'app-types';
import { convertToReadableDate } from '@utils/appUtils';
import FirstLetter from '@ui/common/firstletter';
import Preview from '@ui/common/preview';

const tabNames = ['submissions', 'published'];

type DialogState = {
  open: boolean;
  blog: BlogDetail | null;
};

export default function EditorBlogs(): ReactElement {
  const classes = useStyles();
  const {
    data,
    blog,
    isFetchingBlog,
    isPublishingBlog,
    isUnpublishingBlog,
    isFetchingSubmissions,
    isFetchingPublished,
    message,
  } = useStateSelector((state) => state.editorBlogState);

  const dispatch = useDispatch();

  const [currentTab, setCurrentTab] = useState(0);

  const [publishDialogState, setPublishDialogState] = useState<DialogState>({
    open: false,
    blog: null,
  });
  const [unpublishDialogState, setUnpublishDialogState] = useState<DialogState>({
    open: false,
    blog: null,
  });

  useEffect(() => {
    if (!data) {
      !isFetchingSubmissions && dispatch(fetchSubmittedBlogs());
      !isFetchingPublished && dispatch(fetchPublishedBlogs());
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const getBlogsForTab = () => {
    if (!data) return null;
    let blogs = null;
    if (tabNames[currentTab] === 'submissions') blogs = data['submissions'];
    else if (tabNames[currentTab] === 'published') blogs = data['published'];
    return blogs;
  };

  const getContent = () => {
    if (!data) return null;
    const blogs = getBlogsForTab();
    if (!blogs) return <NotFound message="No blog in this category" />;
    const content = blogs.map((blog) => (
      <List className={classes.list} key={blog._id}>
        <ListItem divider={true}>
          <div>
            <Typography gutterBottom variant="h6">
              {blog.title}
            </Typography>
            {blog.isPublished === true && (blog.isDraft === true || blog.isSubmitted === true) && (
              <Chip
                size="small"
                variant="outlined"
                color="primary"
                label="MODIFIED"
                className={classes.chip}
              />
            )}
            <Typography variant="body1" color="textSecondary" component="p">
              {blog.description}
            </Typography>
            {blog.tags.map((tag) => (
              <Chip
                key={tag}
                variant="outlined"
                size="small"
                label={tag}
                className={classes.chip2}
              />
            ))}
            <div>
              {blog.imgUrl && (
                <Link href={blog.imgUrl} target="_blank" color="primary">
                  <Chip
                    color="secondary"
                    size="small"
                    label={'View Cover Image'}
                    className={classes.chip4}
                  />
                </Link>
              )}
              {blog.blogUrl && <Chip size="small" label={blog.blogUrl} className={classes.chip3} />}
            </div>
            {blog.author && <AuthorView author={blog.author} date={blog.publishedAt} />}
            <div>
              <Button
                color="primary"
                className={classes.button1}
                variant="contained"
                size="small"
                onClick={() => dispatch(fetchBlog(blog))}
              >
                Preview
              </Button>
              {blog.isSubmitted === true && blog.isPublished === false && (
                <Button
                  className={classes.button2}
                  variant="contained"
                  size="small"
                  color="primary"
                  onClick={() => setPublishDialogState({ open: true, blog: blog })}
                >
                  Publish
                </Button>
              )}
              {blog.isSubmitted === true && blog.isPublished === true && (
                <Button
                  className={classes.button2}
                  variant="contained"
                  size="small"
                  color="primary"
                  onClick={() => setPublishDialogState({ open: true, blog: blog })}
                >
                  Publish Update
                </Button>
              )}
              {blog.isPublished === true && (
                <Button
                  className={classes.button2}
                  variant="contained"
                  size="small"
                  color="primary"
                  onClick={() => setUnpublishDialogState({ open: true, blog: blog })}
                >
                  Unpublish
                </Button>
              )}
            </div>
          </div>
        </ListItem>
      </List>
    ));
    if (content.length === 0) return <NotFound message="No blog in this category" />;
    return content;
  };

  return (
    <div className={classes.root}>
      <AppBar color="secondary" position="sticky">
        <Tabs
          value={currentTab}
          onChange={(event, newValue) => setCurrentTab(newValue)}
          indicatorColor="primary"
          textColor="primary"
          variant="fullWidth"
          scrollButtons="auto"
          aria-label="blogs tab"
        >
          {tabNames.map((name) => (
            <Tab
              className={classes.tab}
              key={name}
              label={name.toUpperCase()}
              id={`scrollable-auto-tab-${name}`}
              aria-controls={`scrollable-auto-tabpanel-${name}`}
            />
          ))}
        </Tabs>
        {(isFetchingSubmissions ||
          isFetchingPublished ||
          isFetchingBlog ||
          isPublishingBlog ||
          isUnpublishingBlog) && <LinearProgress color="secondary" />}
      </AppBar>
      <Grid className={classes.pannel} container justify="center" alignItems="center">
        <Grid item xs={11} sm={11} md={7}>
          <Grid container spacing={4} justify="center" alignItems="stretch">
            {getContent()}
          </Grid>
        </Grid>
      </Grid>
      {blog && <Preview blog={blog} open={true} onClose={() => dispatch(clearBlog.action())} />}
      <ConfirmationDialog
        open={publishDialogState.open}
        title={publishDialogState.blog !== null ? publishDialogState.blog.title : ''}
        message="Are you sure you want to publish this blog. Once published updates will be made live to public."
        onPositiveAction={() => {
          if (publishDialogState.blog) dispatch(publishBlog(publishDialogState.blog));
          setPublishDialogState({ open: false, blog: null });
        }}
        onNegativeAction={() => setPublishDialogState({ open: false, blog: null })}
        positionText="Publish Now"
        negativeText="Cancel"
      />
      <ConfirmationDialog
        open={unpublishDialogState.open}
        title={unpublishDialogState.blog !== null ? unpublishDialogState.blog.title : ''}
        message="Are you sure you want to unpublish this blog. Once unpublished blog will be removed from the public access."
        onPositiveAction={() => {
          if (unpublishDialogState.blog) dispatch(unpublishBlog(unpublishDialogState.blog));
          setUnpublishDialogState({ open: false, blog: null });
        }}
        onNegativeAction={() => setUnpublishDialogState({ open: false, blog: null })}
        positionText="Unpublish Now"
        negativeText="Cancel"
      />
      {message && (
        <Snackbar
          message={message.text}
          variant={message.type}
          onClose={() => dispatch(removeMessage.action())}
        />
      )}
    </div>
  );
}

const AuthorView = ({ author, date }: { author: Author; date?: string }) => {
  const classes = useStyles();
  return (
    <div className={classes.author}>
      {author.profilePicUrl ? (
        <CardHeader
          avatar={<Avatar aria-label={author.name} src={author.profilePicUrl} />}
          title={author.name}
          subheader={date ? convertToReadableDate(date) : ''}
        />
      ) : (
        <CardHeader
          avatar={<FirstLetter text={author.name} />}
          title={author.name}
          subheader={date ? convertToReadableDate(date) : ''}
        />
      )}
    </div>
  );
};