import {
  Divider,
  Flex,
  Typography,
  Box,
  Button,
  Radio,
  Menu,
  ActionIcon,
  Modal,
  Alert,
  LoadingOverlay,
  Group,
  Badge
} from '@tidbcloud/uikit'
import { CodeBlock } from '@tidbcloud/uikit/biz'
import {
  IconAlertCircle,
  IconInfoCircle,
  IconPlus,
  IconPlusSquare,
  IconDotsHorizontal,
  IconLinkExternal01
} from '@tidbcloud/uikit/icons'
import React, { useEffect, useState } from 'react'

import { CardContainer, DeleteModal } from 'dbaas/components/IntegrationCard'
import { VendorLogo } from 'dbaas/components/Logo'
import TimeComponent from 'dbaas/components/TimeComponent'
import { AccessGuard } from 'dbaas/contexts/access-control'
import {
  CentralMetricsKey,
  CentralUserProject,
  createMetricsKey,
  deleteMetricsKey,
  useGetAllMetricsKey
} from 'dbaas/services'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

const ScrapeConfig: React.FC<
  React.PropsWithChildren<{
    project: CentralUserProject
    open: boolean
    onClose?: () => void
    metricsKey: string
    loading?: boolean
    error?: string
  }>
> = ({ open, onClose = () => {}, metricsKey, loading, error, project }) => {
  const config = `
scrape_configs:
  - job_name: ${project.name}
    scheme: https
    metrics_path: /public_api/v1/projects/${project.id}/metrics
    params:
      format: ["Prometheus"]
    bearer_token: ${metricsKey}
    static_configs:
    - targets: ["${window.location.hostname}"]
  `
  return (
    <Modal size={800} opened={open} onClose={onClose} centered={true} title="Scrape_config">
      <Box mih={270}>
        {loading ? (
          <LoadingOverlay visible />
        ) : error ? (
          <Alert icon={<IconAlertCircle size={16} />} color="red">
            {error}
          </Alert>
        ) : (
          <>
            <Alert icon={<IconInfoCircle size={16} />} color="peacock">
              Make sure to copy the config now. For security reasons, it cannot be shown again.
            </Alert>
            <CodeBlock language="yaml" mt={16}>
              {config}
            </CodeBlock>
          </>
        )}
      </Box>
      {/* {!error && <CopyButton text={config} menuName="Scrape Config" />} */}
    </Modal>
  )
}

const PrometheusDetail: React.FC<
  React.PropsWithChildren<{
    metricsKeys: CentralMetricsKey[]
    onRefresh?: () => void
    project: CentralUserProject
  }>
> = ({ metricsKeys, onRefresh, project }) => {
  const [showConfig, setShowConfig] = useState(false)
  const [loading, setLoading] = useState(false)
  const [metricsKey, setMetricsKey] = useState('')
  const [err, setErr] = useState('')
  const [selected, setSelected] = useState(-1)
  const {
    store: { tenantData }
  } = useStores()

  const addKey = async () => {
    setShowConfig(true)
    setLoading(true)
    try {
      const data = await createMetricsKey(tenantData.id, project.id)
      setMetricsKey(data?.key?.key || '')
      onRefresh?.()
    } catch (e) {
      setErr(getErrorMessage(e))
    }
    setLoading(false)

    eventTracking('Integration to Promethus Add File Button Clicked')
  }

  const onClose = () => {
    setShowConfig(false)
    setErr('')
  }

  const onDelete = (id: string) => async () => {
    await deleteMetricsKey(tenantData.id, project.id, id)
    onRefresh?.()
    setSelected(-1)
    eventTracking('Integration To Prometheus Delete Button Clicked')
  }

  return (
    <Box w="80%" ml={144}>
      <Group justify="space-between" align="flex-start" wrap="nowrap" mt={16} gap="md">
        <Typography>
          Generate scrape_configs file that Prometheus can use to monitor your project. For security, the contents of
          each file will only be shown once. Refer to the{' '}
          <Box
            component="a"
            p={0}
            fw={400}
            href="https://docs.pingcap.com/tidbcloud/monitor-prometheus-and-grafana-integration"
            target="_blank"
            rel="noreferrer"
            data-mp-event="Documentation Link Clicked"
            data-mp-source="Promethenus"
            onClick={() => eventTracking('Integration To Prometheus Documentation Link Clicked')}
          >
            documentation
          </Box>
          <span>&nbsp;for more details.</span>
        </Typography>
        {!metricsKeys.length && (
          <AccessGuard id="ProjectIntegrationAction">
            <Button
              variant="outline"
              leftSection={<IconPlus size={18} />}
              onClick={addKey}
              data-mp-event="mp-addfile-1691461014203"
              sx={{ flexShrink: 0 }}
            >
              Add File
            </Button>
          </AccessGuard>
        )}
      </Group>
      {!!metricsKeys.length && (
        <div>
          <Flex mt={8} justify="space-between" align="center">
            <Typography variant="title-lg">Scrape_config Files</Typography>
            <AccessGuard id="ProjectIntegrationAction">
              <Button
                variant="subtle"
                color="carbon.9"
                leftSection={<IconPlusSquare size={16} />}
                onClick={addKey}
                data-mp-event="mp-addfile-1691461014205"
              >
                Add File
              </Button>
            </AccessGuard>
          </Flex>
          <Divider my={8}></Divider>
          <Box
            sx={{
              display: 'flex'
            }}
          >
            {metricsKeys.map((mk, index) => {
              return (
                <Box
                  sx={{
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'space-between',
                    height: 40,
                    marginTop: 8,
                    paddingLeft: 16,
                    marginBottom: 8
                  }}
                  key={mk.key_id}
                >
                  <AccessGuard
                    id="ProjectIntegrationAction"
                    fallback={
                      <>
                        Created at <TimeComponent time={mk.created_at || ''} />
                      </>
                    }
                  >
                    <Radio
                      name="radio"
                      label={
                        <>
                          Created at <TimeComponent time={mk.created_at || ''} />
                        </>
                      }
                      checked={selected === index}
                      onClick={() => {
                        setSelected(index)
                      }}
                    />
                  </AccessGuard>

                  {selected === index && (
                    <AccessGuard id="ProjectIntegrationAction">
                      <Menu width={80}>
                        <Menu.Target>
                          <ActionIcon size={36} ml={24}>
                            <IconDotsHorizontal />
                          </ActionIcon>
                        </Menu.Target>
                        <Menu.Dropdown>
                          <DeleteModal
                            onSubmit={onDelete(mk.key_id || '')}
                            title="Delete scrape_config file"
                            trigger={<Menu.Item>Delete</Menu.Item>}
                            content="When you delete this scrape_config file, it cannot be undone."
                            placeholder="Type in DELETE to delete this key"
                          />
                        </Menu.Dropdown>
                      </Menu>
                    </AccessGuard>
                  )}
                </Box>
              )
            })}
          </Box>
        </div>
      )}
      <ScrapeConfig
        open={showConfig}
        loading={loading}
        onClose={onClose}
        project={project}
        error={err}
        metricsKey={metricsKey}
      />
    </Box>
  )
}

export const Prometheus: React.FC<
  React.PropsWithChildren<{
    open?: boolean
    project: CentralUserProject
  }>
> = ({ open, project }) => {
  const {
    store: { tenantData },
    actions
  } = useStores()

  const { data, isFetched, refetch } = useGetAllMetricsKey(tenantData.id, project.id)

  useEffect(() => {
    refetch()
    actions.fetchClusterList()
  }, [refetch, actions])

  const Content = () => {
    return (
      <Flex sx={{ flex: 1 }} justify="space-between" align="center">
        <Group>
          <Typography variant="title-md">Integration to Prometheus</Typography>
          <Badge variant="outline" size="sm" color="carbon" c="carbon.7" fw={500}>
            Preview
          </Badge>
        </Group>

        {!!data?.metrics_keys?.length && (
          <Flex onClick={(e) => e.stopPropagation()} align="center" gap={16}>
            <Button
              variant="subtle"
              component="a"
              target="_blank"
              rel="noreferrer"
              href="https://github.com/pingcap/docs/blob/master/tidb-cloud/monitor-prometheus-and-grafana-integration-grafana-dashboard-UI.json"
              data-mp-event="Integration Grafana JSON Link Clicked"
              rightSection={<IconLinkExternal01 size={18} />}
            >
              Grafana JSON
            </Button>
          </Flex>
        )}
      </Flex>
    )
  }
  return (
    <CardContainer
      open={open}
      left={<VendorLogo name="prometheus" size={64} />}
      content={<Content />}
      onClick={(status) => eventTracking('Integration Prometheus Card Clicked', { closed: status === 'closed' })}
    >
      {(status, _setStatus) => {
        if (!isFetched) {
          return null
        }
        if (status !== 'closed') {
          return (
            <>
              <Divider />
              <PrometheusDetail metricsKeys={data?.metrics_keys || []} project={project} onRefresh={refetch} />
            </>
          )
        }
        return null
      }}
    </CardContainer>
  )
}

export default Prometheus
