import {
  Alert,
  Colors,
  Icon,
  IconSize,
  SwitchCard,
  Tooltip,
} from '@blueprintjs/core'
import type { MilestoneState } from '@inject/graphql/fragments/MilestoneState.generated'
import { useSetMilestone } from '@inject/graphql/mutations/SetMilestone.generated'
import Timestamp from '@inject/shared/components/Timestamp'
import { useNotifyContext } from '@inject/shared/notification/contexts/NotifyContext'
import { useEffect, useState, type FC } from 'react'

interface MilestoneIndicatorProps {
  milestone: MilestoneState
  teamId: string
}

const MilestoneIndicator: FC<MilestoneIndicatorProps> = ({
  milestone: _milestone,
  teamId,
}) => {
  const { reached, timestampReached, milestone, id } = _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 [checked, setChecked] = useState(reached)
  useEffect(() => setChecked(reached), [reached])

  const { notify } = useNotifyContext()
  const [open, setOpen] = useState(false)
  const [mutate] = useSetMilestone()

  return (
    <SwitchCard
      compact
      checked={checked}
      showAsSelectedWhenChecked={false}
      onChange={() => {
        setChecked(!checked)
        setOpen(true)
      }}
    >
      <Alert
        intent='warning'
        isOpen={open}
        onClose={() => setOpen(false)}
        onCancel={() => setChecked(reached)}
        onConfirm={() => {
          mutate({
            variables: {
              milestone: milestone.name,
              activate: !reached,
              teamId,
            },
            update: cache => {
              setChecked(!reached)
              cache.modify({
                id: cache.identify({ __typename: 'MilestoneState', id }),
                fields: {
                  reached: () => !reached,
                  timestampReached: () => new Date().toISOString(),
                },
              })
            },
            onError(error) {
              setChecked(reached)
              notify(error.message, { intent: 'danger' })
            },
          })
          setOpen(false)
        }}
        cancelButtonText='Cancel'
        confirmButtonText='Confirm'
        icon='warning-sign'
      >
        Are you sure you want to mark this milestone as{' '}
        {reached ? 'unreached' : 'reached'}?
      </Alert>
      <Tooltip
        fill
        compact
        usePortal
        content={
          reached ? (
            <Timestamp
              minimal
              datetime={new Date(timestampReached || 0)}
              isAchieved
            />
          ) : (
            <Timestamp isAchieved={false} alternativeContent='Not reached' />
          )
        }
      >
        <div>
          <Icon
            icon='dot'
            style={{
              color: reached ? Colors.GREEN3 : Colors.RED3,
              marginRight: '0.5rem',
            }}
            size={IconSize.LARGE}
          />
          {milestone.name || ''}
        </div>
      </Tooltip>
    </SwitchCard>
  )
}

export default MilestoneIndicator
