import { Button, Card, Flex, Typography, notifier } from '@tidbcloud/uikit'
import { Form, FormSelect } from '@tidbcloud/uikit/biz'
import { useInterval } from '@tidbcloud/uikit/hooks'
import { MONOSPANCED_FONT_FAMILY } from '@tidbcloud/uikit/theme'
import { observer } from 'mobx-react'
import { useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'

import dayjs from 'dbaas/components/dayjs'
import TimeComponent from 'dbaas/components/TimeComponent'
import { AccessDeniedHoverHint, useAccessCheck } from 'dbaas/contexts/access-control'
import { useUpdateOrganization } from 'dbaas/services/account'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'
import { eventTracking, MixpanelEvents } from 'dbaas/utils/tracking'

import { tzToUTCOffset, utcOffsetToTz } from './helpers'

type OrgTZFormValues = {
  timezone: string
}

const tzOffsets = [
  '-12:00',
  '-11:00',
  '-10:00',
  '-09:30',
  '-09:00',
  '-08:00',
  '-07:00',
  '-06:00',
  '-05:00',
  '-04:00',
  '-03:30',
  '-03:00',
  '-02:00',
  '-01:00',
  '+00:00',
  '+01:00',
  '+02:00',
  '+03:00',
  '+03:30',
  '+04:00',
  '+04:30',
  '+05:00',
  '+05:30',
  '+05:45',
  '+06:00',
  '+06:30',
  '+07:00',
  '+08:00',
  '+08:45',
  '+09:00',
  '+09:30',
  '+10:00',
  '+10:30',
  '+11:00',
  '+12:00',
  '+12:45',
  '+13:00',
  '+14:00'
]

// Available utcOffset list (-12 ~ 14)
const tzOptions = tzOffsets.map((tz) => ({
  value: tz,
  label: `UTC${tz === '+00:00' ? '±00:00' : tz}`
}))

export const Timezone = observer(() => {
  const {
    store: { tenantData },
    actions: { updateOrgTimezoneCache, fetchUserProfileV2 }
  } = useStores()
  const { timezone } = tenantData

  const accessible = useAccessCheck('OrgInfoEdit')
  const [currentTime, setCurrentTime] = useState(dayjs())

  const interval = useInterval(() => {
    setCurrentTime(dayjs())
  }, 1000)

  const formProps = useForm<OrgTZFormValues>({
    defaultValues: {
      timezone: utcOffsetToTz(tenantData.timezone || 0)
    }
  })

  const tzMutation = useUpdateOrganization({
    mutation: {
      onSuccess: (_response, { data: { user_set_timezone } }) => {
        updateOrgTimezoneCache(user_set_timezone || '')
        notifier.success('Timezone has been updated successfully.')
        formProps.reset({ timezone: user_set_timezone }, { keepDirty: false })
      },
      onError: (error) => {
        const message = getErrorMessage(error) || 'Fail to update timezone.'

        notifier.error(message)
      }
    }
  })
  const onSave = ({ timezone }: { timezone: string }) => {
    eventTracking(MixpanelEvents.IAMOrganizationTimezone.Update.SubmitClicked, { timezone: timezone })
    return tzMutation.mutateAsync({
      orgId: tenantData.id,
      data: {
        org_id: tenantData.id,
        name: tenantData.name,
        // deprecated
        timezone: tenantData.originalTimezone,

        user_set_timezone: timezone
      }
    })
  }

  const { watch, formState } = formProps
  const { isDirty } = formState
  const jitTimezone = tzToUTCOffset(watch('timezone'))

  useEffect(() => {
    // update form value when directly visit General page
    if (timezone === 0) {
      fetchUserProfileV2()
        .then((data) => {
          formProps.setValue('timezone', utcOffsetToTz(data[1]?.user_set_timezone || data[1]?.timezone || 0), {
            shouldDirty: false
          })
        })
        .catch(() => {})
    }
  }, [])

  useEffect(() => {
    interval.start()
    return interval.stop
  }, [])

  return (
    <Card p={24} mt={24}>
      <Form form={formProps} layout="none" withActions={false} onSubmit={onSave}>
        <Flex align="center" justify="space-between" gap={16}>
          <div>
            <Typography variant="title-lg">Organization Time Zone</Typography>
            <Typography variant="body-lg" mt={8}>
              To ensure consistency across collaborative workflows, all system data timestamps, (tasks, schedules, logs,
              and diagnostics, etc.) are displayed in the{' '}
              <b>
                Organization's timezone (UTC
                {utcOffsetToTz(tenantData.timezone)})
              </b>
              .
            </Typography>
          </div>
          <AccessDeniedHoverHint id="OrgInfoEdit">
            <Button
              variant="default"
              size="sm"
              disabled={!accessible || !isDirty}
              loading={tzMutation.isLoading}
              type="submit"
              data-mp-event="Organization Timezone Update Button Clicked"
            >
              Update
            </Button>
          </AccessDeniedHoverHint>
        </Flex>
        <Flex align="center" justify="space-between" mt={24}>
          <FormSelect
            data-testid="timezone"
            name="timezone"
            data={tzOptions}
            required
            withAsterisk={false}
            disabled={!accessible || tzMutation.isLoading}
          ></FormSelect>
          <Flex>
            <Typography variant="body-lg" c="carbon.7">
              Current Time:
            </Typography>
            <Typography variant="body-lg" ml={2} ff={MONOSPANCED_FONT_FAMILY} fz={12} lh="22px">
              <TimeComponent time={currentTime.format()} utcOffset={jitTimezone} format="YYYY-MM-DD HH:mm:ss Z" />
            </Typography>
          </Flex>
        </Flex>
      </Form>
    </Card>
  )
})
