import { LiveProvider, LiveEditor, LiveError, LivePreview } from 'react-live';
import React from 'react';
import styled from '@emotion/styled';
import { css, Spinner } from 'theme-ui';
import { useComments, CommentStatus } from '../useComments';
import { AddComment } from './AddComment';
import type { PrismTheme } from 'prism-react-renderer';

export const prismTheme: PrismTheme = {
  plain: {
    color: '#e7d2ed',
  },
  styles: [
    {
      types: ['prolog', 'comment', 'doctype', 'cdata'],
      style: {
        color: 'hsl(30, 20%, 50%)',
      },
    },
    {
      types: ['property', 'tag', 'boolean', 'number', 'constant', 'symbol'],
      style: { color: '#f677e1' },
    },
    {
      types: ['attr-name', 'string', 'char', 'builtin', 'insterted'],
      style: {
        color: 'hsl(75, 70%, 70%)',
      },
    },
    {
      types: [
        'operator',
        'entity',
        'url',
        'string',
        'variable',
        'language-css',
      ],
      style: {
        color: 'hsl(40, 90%, 70%)',
      },
    },
    {
      types: ['deleted'],
      style: {
        color: 'rgb(255, 85, 85)',
      },
    },
    {
      types: ['italic'],
      style: {
        fontStyle: 'italic',
      },
    },
    {
      types: ['important', 'bold'],
      style: {
        fontWeight: 'bold',
      },
    },
    {
      types: ['regex', 'important'],
      style: {
        color: '#e90',
      },
    },
    {
      types: ['atrule', 'attr-value', 'keyword'],
      style: {
        color: '#f677e1',
      },
    },
    {
      types: ['punctuation', 'symbol'],
      style: {
        opacity: 0.7,
      },
    },
  ],
};

const red = '#ff5555';

const StyledProvider = styled(LiveProvider)`
  box-shadow: 1px 1px 20px rgba(20, 20, 20, 0.27);
  overflow: hidden;
  display: flex;
  flex-direction: column;
`;

const LiveWrapper = styled.div`
  display: flex;
  width: 100%;
  flex: 50%;
  flex-direction: row;
  justify-content: stretch;
  align-items: stretch;
  @media (max-width: 600px) {
    flex-direction: column-reverse;
  }
`;

const column = css`
  flex-basis: 50%;
  width: 50%;
  max-width: 50%;
  @media (max-width: 600px) {
    flex-basis: auto;
    width: 100%;
    max-width: 100%;
  }
`;

const StyledEditor = styled.div`
  background: #021727;
  color: white;
  font-family: ${p => p.theme.fonts!['monospace']};
  font-size: 1.1em;
  height: 715px;
  padding: 10px;
  margin-left: 20px;
  @media (max-width: 600px) {
    margin-left: 0;
    margin-bottom: 30px;
    height: 300px;
  }
  overflow: auto;
  border-radius: ${p => p.theme.radii!['medium']};
  ${column};
  * > textarea:focus {
    outline: none;
  }
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.12),
    0 4px 4px rgba(0, 0, 0, 0.12), 0 8px 8px rgba(0, 0, 0, 0.12),
    0 16px 16px rgba(0, 0, 0, 0.12);
`;

const StyledPreview = styled(LivePreview)`
  position: relative;
  background: transparent;
  overflow: hidden;
  display: flex;
  padding-right: 20px;
  @media (max-width: 600px) {
    padding-right: 0;
    padding-bottom: 20px;
    max-height: inherit;
  }
  *:focus {
    outline-style: solid;
    outline-color: ${({ theme }) => theme.colors?.primary};
    border-color: ${({ theme }) => theme.colors?.primary};
  }
  ${column};

  /* scrollbox */
  section > div {
    max-height: 382px;
    overflow-y: auto;
    overflow-y: overlay;
  }
`;

const StyledError = styled(LiveError)`
  display: block;
  padding: 8px;
  background: ${red};
  color: black;
  white-space: pre-wrap;
  text-align: left;
  font-size: 0.9em;
  font-family: 'Source Code Pro', monospace;
  height: 80px;
  overflow: auto;
`;

const formatDate = (dateStr: string) => {
  const date = new Date(dateStr);
  const seconds = Math.floor((new Date() - date) / 1000);

  let interval = Math.floor(seconds / 31536000);

  if (interval > 1) {
    return interval + ' years ago';
  }
  interval = Math.floor(seconds / 2592000);
  if (interval > 1) {
    return interval + ' months ago';
  }
  interval = Math.floor(seconds / 86400);
  if (interval > 1) {
    return interval + ' days ago';
  }
  interval = Math.floor(seconds / 3600);
  if (interval > 1) {
    return interval + ' hours ago';
  }
  interval = Math.floor(seconds / 60);
  if (interval > 1) {
    return interval + ' minutes ago';
  }
  if (Math.floor(seconds) === 0) {
    return 'now';
  }
  return Math.floor(seconds) + ' seconds ago';
};

const formatStatus = (status: CommentStatus) => {
  switch (status) {
    case 'added':
      return '👌';
    case 'delivered-awaiting-approval':
      return '🕑';
    case 'sending':
      return '✉️';
  }
};

const scope = { useComments, formatDate, AddComment, formatStatus, Spinner };

export const LiveEdit = ({ code }: { code: string }) => (
  <StyledProvider code={code} noInline={true} theme={prismTheme} scope={scope}>
    <LiveWrapper>
      <StyledPreview />
      <StyledEditor>
        <LiveEditor />
      </StyledEditor>
    </LiveWrapper>
    <div>
      <StyledError />
    </div>
  </StyledProvider>
);