import MilestoneDescription from '@/components/Description/MilestoneDescription'
import { Alert, Colors, Popover, SwitchCard } from '@blueprintjs/core'
import { Dot, IconSize } from '@blueprintjs/icons'
import { css } from '@emotion/css'
import type { MilestoneState } from '@inject/graphql/fragment-types'
import type { VariablesOf } from '@inject/graphql/graphql'
import { SetMilestone } from '@inject/graphql/mutations'
import StyledTag from '@inject/shared/components/StyledTag'
import Timestamp from '@inject/shared/components/StyledTag/Timestamp'
import { notify } from '@inject/shared/notification/engine'
import { useState, type FC } from 'react'
import { useClient } from 'urql'

const timestamp = css`
  margin: 0.5rem;
`

interface MilestoneIndicatorProps {
  milestone: MilestoneState
  teamId: string
}

const MilestoneIndicator: FC<MilestoneIndicatorProps> = ({
  milestone: _milestone,
  teamId,
}) => {
  const client = useClient()
  const { reached, timestampReached, milestone } = _milestone

  /*
   * the switch will change its state even if the alert is cancelled;
   * we track of the state separately to revert it if the alert is cancelled
   */
  const [open, setOpen] = useState(false)

  return (
    <>
      <SwitchCard
        compact
        checked={reached}
        showAsSelectedWhenChecked={false}
        onChange={() => {
          setOpen(true)
        }}
      >
        <MilestoneDescription
          milestone={milestone}
          getChildren={displayName => (
            <div>
              <Popover
                interactionKind='hover'
                content={
                  reached ? (
                    <Timestamp
                      minimal
                      datetime={new Date(timestampReached || 0)}
                      isAchieved
                      className={timestamp}
                    />
                  ) : (
                    <StyledTag
                      isAchieved={false}
                      content='Not reached'
                      className={timestamp}
                    />
                  )
                }
              >
                <Dot
                  style={{
                    color: reached ? Colors.GREEN3 : Colors.RED3,
                    marginRight: '0.5rem',
                  }}
                  size={IconSize.LARGE}
                />
              </Popover>
              {displayName}
            </div>
          )}
        />
      </SwitchCard>

      <Alert
        intent='warning'
        isOpen={open}
        onClose={() => setOpen(false)}
        onConfirm={() => {
          client
            .mutation<unknown, VariablesOf<typeof SetMilestone>>(SetMilestone, {
              milestone: milestone.name,
              activate: !reached,
              teamId,
            })
            .toPromise()
            .catch(error => {
              notify(error.message, { intent: 'danger' })
            })
          /*
           * TODO: fix MilestoneState mutation to use ID ONLY FOR GIVEN STATE
           * update: cache => {
           *   setChecked(!reached)
           *   cache.modify({
           *     id: cache.identify({ __typename: 'MilestoneState', id }),
           *     fields: {
           *       reached: () => !reached,
           *       timestampReached: () => new Date().toISOString(),
           *     },
           *   })
           * },
           */
          setOpen(false)
        }}
        cancelButtonText='Cancel'
        confirmButtonText='Confirm'
        icon='warning-sign'
        canEscapeKeyCancel
        canOutsideClickCancel
      >
        Are you sure you want to mark this milestone as{' '}
        {reached ? 'unreached' : 'reached'}?
      </Alert>
    </>
  )
}

export default MilestoneIndicator
