/** @jsx jsx */
import { jsx } from '@emotion/core';
import PropTypes from 'prop-types';
import VisuallyHidden from '@reach/visually-hidden';
import sortBy from 'sort-by';

import { formatBytes } from '../utils/format.js';

import { ContentArea, ContentAreaHeaderBar } from './ContentArea.js';
import { FolderIcon, FileIcon, FileCodeIcon } from './Icons.js';

const linkStyle = {
  color: '#0076ff',
  textDecoration: 'none',
  ':hover': {
    textDecoration: 'underline'
  }
};

const tableCellStyle = {
  paddingTop: 6,
  paddingRight: 3,
  paddingBottom: 6,
  paddingLeft: 3,
  borderTop: '1px solid #eaecef'
};

const iconCellStyle = {
  ...tableCellStyle,
  color: '#424242',
  width: 17,
  paddingRight: 2,
  paddingLeft: 10,
  '@media (max-width: 700px)': {
    paddingLeft: 20
  }
};

const typeCellStyle = {
  ...tableCellStyle,
  textAlign: 'right',
  paddingRight: 10,
  '@media (max-width: 700px)': {
    paddingRight: 20
  }
};

function getRelName(path, base) {
  return path.substr(base.length > 1 ? base.length + 1 : 1);
}

export default function FolderViewer({ path, details: entries }) {
  const { subdirs, files } = Object.keys(entries).reduce(
    (memo, key) => {
      const { subdirs, files } = memo;
      const entry = entries[key];

      if (entry.type === 'directory') {
        subdirs.push(entry);
      } else if (entry.type === 'file') {
        files.push(entry);
      }

      return memo;
    },
    { subdirs: [], files: [] }
  );

  subdirs.sort(sortBy('path'));
  files.sort(sortBy('path'));

  const rows = [];

  if (path !== '/') {
    rows.push(
      <tr key="..">
        <td css={iconCellStyle} />
        <td css={tableCellStyle}>
          <a title="Parent directory" href="../" css={linkStyle}>
            ..
          </a>
        </td>
        <td css={tableCellStyle}></td>
        <td css={typeCellStyle}></td>
      </tr>
    );
  }

  subdirs.forEach(({ path: dirname }) => {
    const relName = getRelName(dirname, path);
    const href = relName + '/';

    rows.push(
      <tr key={relName}>
        <td css={iconCellStyle}>
          <FolderIcon />
        </td>
        <td css={tableCellStyle}>
          <a title={relName} href={href} css={linkStyle}>
            {relName}
          </a>
        </td>
        <td css={tableCellStyle}>-</td>
        <td css={typeCellStyle}>-</td>
      </tr>
    );
  });

  files.forEach(({ path: filename, size, contentType }) => {
    const relName = getRelName(filename, path);
    const href = relName;

    rows.push(
      <tr key={relName}>
        <td css={iconCellStyle}>
          {contentType === 'text/plain' || contentType === 'text/markdown' ? (
            <FileIcon />
          ) : (
            <FileCodeIcon />
          )}
        </td>
        <td css={tableCellStyle}>
          <a title={relName} href={href} css={linkStyle}>
            {relName}
          </a>
        </td>
        <td css={tableCellStyle}>{formatBytes(size)}</td>
        <td css={typeCellStyle}>{contentType}</td>
      </tr>
    );
  });

  let counts = [];
  if (files.length > 0) {
    counts.push(`${files.length} file${files.length === 1 ? '' : 's'}`);
  }
  if (subdirs.length > 0) {
    counts.push(`${subdirs.length} folder${subdirs.length === 1 ? '' : 's'}`);
  }

  return (
    <ContentArea>
      <ContentAreaHeaderBar>
        <span>{counts.join(', ')}</span>
      </ContentAreaHeaderBar>

      <table
        css={{
          width: '100%',
          borderCollapse: 'collapse',
          borderRadius: 2,
          background: '#fff',
          '@media (max-width: 700px)': {
            '& th + th + th + th, & td + td + td + td': {
              display: 'none'
            }
          },
          '& tr:first-of-type td': {
            borderTop: 0
          }
        }}
      >
        <thead>
          <tr>
            <th>
              <VisuallyHidden>Icon</VisuallyHidden>
            </th>
            <th>
              <VisuallyHidden>Name</VisuallyHidden>
            </th>
            <th>
              <VisuallyHidden>Size</VisuallyHidden>
            </th>
            <th>
              <VisuallyHidden>Content Type</VisuallyHidden>
            </th>
          </tr>
        </thead>
        <tbody>{rows}</tbody>
      </table>
    </ContentArea>
  );
}

if (process.env.NODE_ENV !== 'production') {
  FolderViewer.propTypes = {
    path: PropTypes.string.isRequired,
    details: PropTypes.objectOf(
      PropTypes.shape({
        path: PropTypes.string.isRequired,
        type: PropTypes.oneOf(['directory', 'file']).isRequired,
        contentType: PropTypes.string, // file only
        integrity: PropTypes.string, // file only
        size: PropTypes.number // file only
      })
    ).isRequired
  };
}