import MilestoneDescription from '@/components/Description/MilestoneDescription'
import { Alert, Card, Colors, Popover, SwitchCard } from '@blueprintjs/core'
import { Dot, Flag, 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 { useState, type FC } from 'react'
import { useClient } from 'urql'

const timestamp = css`
  margin: 0.5rem;
`

const wrapper = css`
  display: flex;
  align-items: center;
  gap: 0.2rem;
  justify-content: center;
`

interface MilestoneIndicatorProps {
  milestone: MilestoneState
  teamId: string
  disabled?: boolean
}

const MilestoneIndicator: FC<MilestoneIndicatorProps> = ({
  milestone: _milestone,
  teamId,
  disabled,
}) => {
  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)

  const cardChildren = (
    <>
      <MilestoneDescription
        milestone={milestone}
        getChildren={displayName => (
          <>
            <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>
            <div className={wrapper}>
              {displayName}
              {milestone.final && (
                <Flag style={{ padding: '0.2rem' }} title='Final milestone' />
              )}
            </div>
          </>
        )}
      />

      {!disabled && (
        <Alert
          intent='warning'
          isOpen={open}
          onClose={() => setOpen(false)}
          onConfirm={() => {
            client
              .mutation<unknown, VariablesOf<typeof SetMilestone>>(
                SetMilestone,
                {
                  milestone: milestone.name,
                  activate: !reached,
                  teamId,
                }
              )
              .toPromise()
            /*
             * 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 ? 'not reached' : 'reached'}?
        </Alert>
      )}
    </>
  )

  return disabled ? (
    <Card style={{ order: reached ? 1 : 3 }} compact>
      {cardChildren}
    </Card>
  ) : (
    <SwitchCard
      style={{ order: reached ? 1 : 3 }}
      compact
      checked={reached}
      showAsSelectedWhenChecked={false}
      onChange={() => {
        setOpen(true)
      }}
    >
      {cardChildren}
    </SwitchCard>
  )
}

export default MilestoneIndicator
