import { useLazyQuery } from '@apollo/react-hooks'
import { makeStyles, ClickAwayListener } from '@material-ui/core'
import classnames from 'classnames'
import { format, set } from 'date-fns/fp'
import FileSaver from 'file-saver'
import * as R from 'ramda'
import React, { useState, useCallback } from 'react'
import Arrow from 'src/styling/icons/arrow/download_logs.svg?react'
import DownloadInverseIcon from 'src/styling/icons/button/download/white.svg?react'
import Download from 'src/styling/icons/button/download/zodiac.svg?react'

import { FeatureButton, Link } from 'src/components/buttons'
import { primaryColor, offColor, zircon } from 'src/styling/variables'
import { formatDate } from 'src/utils/timezones'

import Popper from './Popper'
import DateRangePicker from './date-range-picker/DateRangePicker'
import { RadioGroup } from './inputs'
import typographyStyles from './typography/styles'

const { info1, label1, label2, h4 } = typographyStyles

const dateContainerStyles = {
  wrapper: {
    height: 46,
    width: 99
  },
  container: {
    display: 'flex'
  },
  monthWeekDayContainer: {
    display: 'flex',
    flexDirection: 'column'
  },
  label: {
    extend: label1,
    lineHeight: 1.33,
    color: primaryColor
  },
  bigNumber: {
    extend: info1,
    lineHeight: 1,
    marginRight: 7
  },
  monthYear: {
    extend: label2,
    lineHeight: 1.17,
    color: primaryColor
  },
  weekDay: {
    extend: label1,
    lineHeight: 1.33,
    color: offColor
  }
}

const dateContainerUseStyles = makeStyles(dateContainerStyles)

const DateContainer = ({ date, children, ...props }) => {
  const classes = dateContainerUseStyles()

  return (
    <div className={classes.wrapper}>
      <div className={classes.label}>{children}</div>
      {date && (
        <>
          <div className={classes.container}>
            <div className={classes.bigNumber}>{format('d', date)}</div>
            <div className={classes.monthWeekDayContainer}>
              <span className={classes.monthYear}>{`${format(
                'MMM',
                date
              )} ${format('yyyy', date)}`}</span>
              <span className={classes.weekDay}>{format('EEEE', date)}</span>
            </div>
          </div>
        </>
      )}
    </div>
  )
}

const styles = {
  popoverContent: {
    width: 280
  },
  popoverHeader: {
    extend: h4,
    padding: [[15, 15, 0, 15]]
  },
  radioButtonsContainer: {
    padding: [[5, 15, 5, 15]]
  },
  radioButtons: {
    display: 'flex',
    justifyContent: 'space-between',
    flexDirection: 'row',
    color: primaryColor
  },
  dateRangePickerShowing: {
    display: 'block',
    height: '100%'
  },
  dateRangePickerHidden: {
    display: 'none',
    height: 0
  },
  download: {
    padding: [[10, 15]]
  },
  dateContainerWrapper: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    position: 'relative',
    backgroundColor: zircon,
    padding: [[0, 15]],
    minHeight: 70
  },
  arrowContainer: {
    position: 'absolute',
    left: 125,
    top: 26
  },
  arrow: {
    margin: 'auto'
  }
}

const useStyles = makeStyles(styles)
const ALL = 'all'
const RANGE = 'range'
const ADVANCED = 'advanced'
const SIMPLIFIED = 'simplified'

const LogsDownloaderPopover = ({
  name,
  query,
  args,
  title,
  getLogs,
  timezone,
  simplified,
  className
}) => {
  const [selectedRadio, setSelectedRadio] = useState(ALL)
  const [selectedAdvancedRadio, setSelectedAdvancedRadio] = useState(ADVANCED)

  const [range, setRange] = useState({ from: null, until: null })
  const [anchorEl, setAnchorEl] = useState(null)
  const [fetchLogs] = useLazyQuery(query, {
    onCompleted: data => createLogsFile(getLogs(data), range)
  })

  const classes = useStyles()

  const dateRangePickerClasses = {
    [classes.dateRangePickerShowing]: selectedRadio === RANGE,
    [classes.dateRangePickerHidden]: selectedRadio === ALL
  }

  const handleRadioButtons = evt => {
    const selectedRadio = R.path(['target', 'value'])(evt)
    setSelectedRadio(selectedRadio)
    if (selectedRadio === ALL) setRange({ from: null, until: null })
  }

  const handleAdvancedRadioButtons = evt => {
    const selectedAdvancedRadio = R.path(['target', 'value'])(evt)
    setSelectedAdvancedRadio(selectedAdvancedRadio)
  }

  const handleRangeChange = useCallback(
    (from, until) => {
      setRange({ from, until })
    },
    [setRange]
  )

  const downloadLogs = (range, args) => {
    if (selectedRadio === ALL) {
      fetchLogs({
        variables: {
          ...args,
          simplified: selectedAdvancedRadio === SIMPLIFIED,
          excludeTestingCustomers: true
        }
      })
    }

    if (!range || !range.from) return
    if (range.from && !range.until) range.until = new Date()

    if (selectedRadio === RANGE) {
      fetchLogs({
        variables: {
          ...args,
          from: range.from,
          until: range.until,
          simplified: selectedAdvancedRadio === SIMPLIFIED,
          excludeTestingCustomers: true
        }
      })
    }
  }

  const createLogsFile = (logs, range) => {
    const formatDateFile = date => {
      return formatDate(date, timezone, 'yyyy-MM-dd_HH-mm')
    }

    const blob = new window.Blob([logs], {
      type: 'text/plain;charset=utf-8'
    })

    FileSaver.saveAs(
      blob,
      selectedRadio === ALL
        ? `${formatDateFile(new Date())}_${name}.csv`
        : `${formatDateFile(range.from)}_${formatDateFile(
            range.until
          )}_${name}.csv`
    )
  }

  const handleOpenRangePicker = event => {
    setAnchorEl(anchorEl ? null : event.currentTarget)
  }

  const handleClickAway = () => {
    setAnchorEl(null)
  }

  const radioButtonOptions = [
    { display: 'All logs', code: ALL },
    { display: 'Date range', code: RANGE }
  ]

  const advancedRadioButtonOptions = [
    { display: 'Advanced logs', code: ADVANCED },
    { display: 'Simplified logs', code: SIMPLIFIED }
  ]

  const open = Boolean(anchorEl)
  const id = open ? 'date-range-popover' : undefined

  return (
    <ClickAwayListener onClickAway={handleClickAway}>
      <div className={className}>
        <FeatureButton
          Icon={Download}
          InverseIcon={DownloadInverseIcon}
          onClick={handleOpenRangePicker}
          variant="contained"
        />
        <Popper id={id} open={open} anchorEl={anchorEl} placement="bottom">
          <div className={classes.popoverContent}>
            <div className={classes.popoverHeader}>{title}</div>
            <div className={classes.radioButtonsContainer}>
              <RadioGroup
                name="logs-select"
                value={selectedRadio}
                options={radioButtonOptions}
                ariaLabel="logs-select"
                onChange={handleRadioButtons}
                className={classes.radioButtons}
              />
            </div>
            {selectedRadio === RANGE && (
              <div className={classnames(dateRangePickerClasses)}>
                <div className={classes.dateContainerWrapper}>
                  {range && (
                    <>
                      <DateContainer date={range.from}>From</DateContainer>
                      <div className={classes.arrowContainer}>
                        <Arrow className={classes.arrow} />
                      </div>
                      <DateContainer date={range.until}>To</DateContainer>
                    </>
                  )}
                </div>
                <DateRangePicker
                  maxDate={set(
                    {
                      hours: 23,
                      minutes: 59,
                      seconds: 59,
                      milliseconds: 999
                    },
                    new Date()
                  )}
                  onRangeChange={handleRangeChange}
                />
              </div>
            )}
            {simplified && (
              <div className={classes.radioButtonsContainer}>
                <RadioGroup
                  name="simplified-tx-logs"
                  value={selectedAdvancedRadio}
                  options={advancedRadioButtonOptions}
                  ariaLabel="simplified-tx-logs"
                  onChange={handleAdvancedRadioButtons}
                  className={classes.radioButtons}
                />
              </div>
            )}
            <div className={classes.download}>
              <Link color="primary" onClick={() => downloadLogs(range, args)}>
                Download
              </Link>
            </div>
          </div>
        </Popper>
      </div>
    </ClickAwayListener>
  )
}

export default LogsDownloaderPopover
