import * as React from 'react'
import { useRef, useState } from 'react'

import Alert from '../../Alerts/Alert'
import Button from '../../Button/Button'
import Icon from '../../Icons/Icon'
import Popover from '../../Popover/Popover'
import { SideDrawer } from '../../SideDrawer/SideDrawer'
import Tooltip from '../../Tooltip/Tooltip'
import { useMediaQuery } from '../../../hooks/responsiveHooks'
import type {
  ComparisonDatePickerProps,
  SelectionState,
  SelectionStateBase,
  SelectionStateDispatchActions,
} from './ComparisonDatePicker'
import { ComparisonDatePicker } from './ComparisonDatePicker'
import styles from './comparison_date_picker_popup.module.scss'
import type { SideDrawerBase } from '../../SideDrawer/SideDrawer'
import { type AlertPropsWithDates } from '../Timeframe'
import { c } from '../../../translations/LibraryTranslationService'

type ComparisonDatePickerPopupProps = ComparisonDatePickerProps & {
  /** method will receive two values, `selectionState` and `selectionStateDispatch`; (selectionState, selectionStateDispatch) => void */
  onApply: OnApply
  /** indicates if the custom date range has been selected with valid dates */
  selectedCustomDateRange?: boolean
  /** Optionally add a layer position to the drawer to allow layered drawers. The number here will
   *  be the position in the stack of SideDrawer layers if there are multiple SideDrawers that
   *  need to be displayed. NOTE: Omit this prop if there is only 1 SideDrawer layer. This is
   *  important for styling. */
  sideDrawerLayerPosition?: number
  /** Passes any optional SideDrawer props to the ComparisonDatePicker SideDrawer */
  cdpSideDrawerProps?: Omit<
    SideDrawerBase,
    'children' | 'isOpen' | 'closeCallout'
  >
  alertProps?: AlertPropsWithDates
  /** Label for the first range */
  firstRangeLabel?: string
  /** Label for the second range */
  secondRangeLabel?: string
}

const CheckIcon = () => (
  <Icon icon='check' color='white' className={styles.tooltipIcon} />
)

const DateRangeDisplay = (
  props: ComparisonDatePickerPopupProps,
): React.JSX.Element => {
  const firstRange_startDate =
    props?.initial_firstRange_startDate?.format('MM-DD-YY') ?? null
  const firstRange_endDate =
    props?.initial_firstRange_endDate?.format('MM-DD-YY') ?? null
  const secondRange_startDate =
    props?.initial_secondRange_startDate?.format('MM-DD-YY') ?? null
  const secondRange_endDate =
    props?.initial_secondRange_endDate?.format('MM-DD-YY') ?? null

  return (
    <div style={{ minWidth: '280px' }}>
      <span className={styles.title}>Custom Timeframe</span>
      <div className={styles.dateRow}>
        <div className={styles.dateLabel}>Date Range</div>
        <div className={styles.dateValue}>
          {firstRange_startDate} - {firstRange_endDate}
        </div>
      </div>
      {props.showComparisonRange && (
        <div className={styles.dateRow}>
          <div className={styles.dateLabel}>Compare Range</div>
          <div className={styles.dateValue}>
            {secondRange_startDate} - {secondRange_endDate}
          </div>
        </div>
      )}
    </div>
  )
}

export function ComparisonDatePickerPopup(
  props: ComparisonDatePickerPopupProps,
): React.JSX.Element {
  const isMobileView = useMediaQuery({ type: 'max', breakpoint: 'md' })
  const [isDrawerOpen, setDrawerOpen] = useState(false)
  const [isSelectedRangeDrawerOpen, setSelectedRangeDrawerOpen] =
    useState(false)

  // State to capture selectionState and selectionStateDispatch from ComparisonDatePicker
  const [capturedSelectionState, setCapturedSelectionState] =
    useState<SelectionState | null>(null)
  const capturedSelectionStateDispatch =
    useRef<React.Dispatch<SelectionStateDispatchActions> | null>(null)

  const PopoverOrDrawerContent = ({
    visible,
    setVisible,
  }: {
    visible: boolean
    setVisible: React.Dispatch<React.SetStateAction<boolean>>
  }) => {
    return (
      <>
        {props.alertProps && (
          <div className={`${styles.marginBottom}`}>
            <Alert {...props.alertProps} />
          </div>
        )}
        <ComparisonWrapper
          {...props}
          visible={visible}
          setVisible={setVisible}
          isDrawerOpen={isDrawerOpen}
          onSelectionStateChange={setCapturedSelectionState}
          onSelectionStateDispatchChange={(dispatch) => {
            capturedSelectionStateDispatch.current = dispatch
          }}
        />
      </>
    )
  }

  const content = (
    <div
      className={`${styles.contentContainer} ${
        props.selectedCustomDateRange ? styles.selected : ''
      }`}
    >
      {isMobileView ? (
        <>
          <Button as='unstyled' onClick={() => setDrawerOpen(true)}>
            <Icon icon='calendar' iconSize='16px' color='dark-blue' />
          </Button>
          <SideDrawer
            noContentPadding={true}
            isOpen={isDrawerOpen}
            closeCallout={() => setDrawerOpen(false)}
            headerContent=''
            {...(capturedSelectionState &&
              capturedSelectionStateDispatch.current && {
                footerContent: footerButtons(
                  {
                    ...props,
                    setVisible: setDrawerOpen,
                    visible: isDrawerOpen,
                  },
                  capturedSelectionState,
                  capturedSelectionStateDispatch.current,
                ),
              })}
          >
            {PopoverOrDrawerContent({
              visible: isDrawerOpen,
              setVisible: setDrawerOpen,
            })}
          </SideDrawer>
        </>
      ) : (
        <Popover
          disableCloseOnScroll
          popoverContent={({ visible, setVisible }) =>
            PopoverOrDrawerContent({
              visible,
              setVisible,
            })
          }
          position='right'
          className='datepicker'
          maxWidth='460' // datePicker width(428) + padding(32)
        >
          {({ visible, setVisible }) => (
            <Button as='unstyled' onClick={() => setVisible(!visible)}>
              <Icon icon='calendar' iconSize='16px' color='dark-blue' />
            </Button>
          )}
        </Popover>
      )}

      {props.selectedCustomDateRange && (
        <div className={styles.tooltip}>
          {isMobileView ? (
            <>
              <div style={{ display: 'flex' }}>
                <Button
                  as='unstyled'
                  onClick={() => setSelectedRangeDrawerOpen(true)}
                >
                  <CheckIcon />
                </Button>
              </div>
              <SideDrawer
                isOpen={isSelectedRangeDrawerOpen}
                closeCallout={() => setSelectedRangeDrawerOpen(false)}
                headerContent=''
                contentClassName={styles.drawerStyles}
              >
                <DateRangeDisplay {...props} />
              </SideDrawer>
            </>
          ) : (
            <CheckIcon />
          )}
        </div>
      )}
    </div>
  )

  return props.selectedCustomDateRange && !isMobileView ? (
    <Tooltip
      position='right'
      tooltipContent={<DateRangeDisplay {...props} />}
      maxWidth='auto'
    >
      {content}
    </Tooltip>
  ) : (
    content
  )
}

function footerButtons(
  props: ComparisonDatePickerPopupProps & {
    setVisible: React.Dispatch<React.SetStateAction<boolean>>
    visible: boolean
  },
  selectionState: SelectionState,
  selectionStateDispatch: React.Dispatch<SelectionStateDispatchActions>,
) {
  const { setVisible, visible } = props

  return (
    <div className={`${styles.flexSpaceBetween} ${styles.marginTop8}`}>
      <Button
        styleType='text-blue'
        onClick={() => {
          const originalDates: SelectionStateBase = {
            firstRange_startDate: props.initial_firstRange_startDate ?? null,
            firstRange_endDate: props.initial_firstRange_endDate ?? null,
            secondRange_startDate: props.initial_secondRange_startDate ?? null,
            secondRange_endDate: props.initial_secondRange_endDate ?? null,
          }
          selectionStateDispatch({ action: 'resetInputs', originalDates })
        }}
      >
        {c('clearDates')}
      </Button>
      <Button
        styleType='tertiary'
        onClick={() => {
          props.onApply(selectionState)
          setVisible?.(!visible)
        }}
      >
        {c('apply')}
      </Button>
    </div>
  )
}

function ComparisonWrapper(
  props: ComparisonDatePickerPopupProps & {
    setVisible: React.Dispatch<React.SetStateAction<boolean>>
    visible: boolean
    isDrawerOpen: boolean
    onSelectionStateChange: (state: SelectionState) => void
    onSelectionStateDispatchChange: (
      dispatch: React.Dispatch<SelectionStateDispatchActions>,
    ) => void
  },
) {
  const {
    onSelectionStateChange,
    onSelectionStateDispatchChange,
    isDrawerOpen,
  } = props

  return (
    <ComparisonDatePicker key={props.visible.toString()} {...props}>
      {(selectionState, selectionStateDispatch) => {
        // Capture the current values whenever this renders
        onSelectionStateChange(selectionState)
        onSelectionStateDispatchChange(selectionStateDispatch)
        return !isDrawerOpen ? (
          footerButtons(props, selectionState, selectionStateDispatch)
        ) : (
          <></>
        )
      }}
    </ComparisonDatePicker>
  )
}

type OnApply = (dates: SelectionStateBase) => void
