import { notifier } from '@tidbcloud/uikit'
import { ActionIcon, Box, Card, CopyButton, Flex, Modal, Tooltip, Typography } from '@tidbcloud/uikit'
import { Form, FormTextInput } from '@tidbcloud/uikit/biz'
import { IconChevronDown, IconChevronUp, IconCopy03, IconEdit05 } from '@tidbcloud/uikit/icons'
import { useEffect, useState } from 'react'
import { useForm } from 'react-hook-form'

import TimeComponent from 'dbaas/components/TimeComponent'
import { useUpdateDataApp } from 'dbaas/services/dataservice'

import { useDataApiContext } from '../../context'
import { DATA_APP_NAME_RULES, APP_VERSION_RULES, showErrorMsg } from '../../helpers'
import { DataApp } from '../../types'

interface UpdateNameFormValues {
  app_name: string
  major: number
  minor: number
  patch: number
  description: string
}

type PropertyItem = {
  name: string
  value: string | React.ReactNode
  tooltip?: string
  copyContent?: string
  lines?: number
}

const BasicSetting = ({ baseUrls }: { baseUrls: string[] }) => {
  const { orgId, projectId, editApp, getAppList, setEditApp } = useDataApiContext()
  const propertiesConfig: PropertyItem[] = [
    {
      name: 'App ID',
      value: editApp?.external_app_id,
      copyContent: editApp?.external_app_id
    },
    {
      name: 'App Name',
      value: editApp?.app_name
    },
    {
      name: 'App Version',
      value: editApp?.app_version
    }
  ]

  const rightPropertiesConfig = [
    {
      name: 'Create by',
      value: editApp?.created_by
    },
    {
      name: 'Created at',
      value: <TimeComponent time={editApp?.created_at!} />
    },
    {
      name: 'Description',
      value: editApp?.description,
      lines: 2
    }
  ]
  const [editNameModalOpened, setEditNameModalOpened] = useState(false)
  const updateMutation = useUpdateDataApp()
  const formProps = useForm<UpdateNameFormValues>()
  const { setValue } = formProps

  const [curBaseUrlIdx, setCurBaseUrlIdx] = useState(0)

  useEffect(() => {
    if (editNameModalOpened) {
      setTimeout(() => {
        setValue('app_name', editApp?.app_name ?? '')
        const version = (editApp?.app_version ?? '').split('.')
        setValue('major', version.length ? parseInt(version[0]) : 1)
        setValue('minor', version.length >= 2 ? parseInt(version[1]) : 0)
        setValue('patch', version.length >= 3 ? parseInt(version[2]) : 0)
        setValue('description', editApp?.description ?? '')
      }, 0)
    }
  }, [editNameModalOpened])

  const updateName = async (values: UpdateNameFormValues) => {
    const name = values.app_name
    const version = `${values.major}.${values.minor}.${values.patch}`
    try {
      const res = await updateMutation.mutateAsync({
        orgId,
        projectId,
        appId: `${editApp?.id || 0}`,
        data: {
          app_name: name,
          app_version: version,
          description: values.description
        }
      })

      if (res.code === 200) {
        setEditApp({
          ...editApp,
          app_name: name,
          app_version: version,
          description: values.description
        } as DataApp)
        getAppList()
        setEditNameModalOpened(false)
      } else {
        notifier.error(res.message)
      }
    } catch (e) {
      showErrorMsg(e)
    }
  }

  const baseUrl = baseUrls.length > curBaseUrlIdx ? baseUrls[curBaseUrlIdx] : ''

  const copyContent = () => {
    return `App ID: ${editApp?.external_app_id}\nApp Name: ${editApp?.app_name}\nBase URL: ${baseUrl}`
  }

  const topButton = (
    <Flex justify="space-between">
      <Typography variant="title-md" mb={20}>
        Data App Properties
      </Typography>
      <Flex gap={8}>
        <ActionIcon aria-label="Edit" variant="default" onClick={() => setEditNameModalOpened(true)}>
          <IconEdit05 size={14} color="carbon.2" />
        </ActionIcon>

        <CopyButton value={copyContent()}>
          {({ copied, copy }) => (
            <Tooltip
              label={copied ? 'Copied' : copyContent()}
              withArrow
              multiline
              maw={300}
              sx={{ wordBreak: 'break-all', whiteSpace: 'break-spaces' }}
            >
              <ActionIcon aria-label="Copy" variant="default" onClick={copy}>
                <IconCopy03 size={14} />
              </ActionIcon>
            </Tooltip>
          )}
        </CopyButton>
      </Flex>
    </Flex>
  )

  const renderPropertiesConfig = (config: PropertyItem[], maxW = 300) => {
    return (
      <>
        {config.map((v, i) => (
          <Flex align="top" mb={i === config.length - 1 ? 0 : 24} key={i}>
            <Typography variant="label-md" w={100} sx={{ flexShrink: 0 }}>
              {v.name}
            </Typography>
            {v.tooltip ? (
              <Tooltip
                label={v.tooltip}
                withArrow
                multiline
                maw={maxW}
                sx={{ wordBreak: 'break-all', whiteSpace: 'break-spaces' }}
              >
                <Box sx={{ width: 0, flex: 1 }}>
                  <Typography variant="body-sm" sx={() => ({ overflow: 'hidden', textOverflow: 'ellipsis' })}>
                    {v.value}
                  </Typography>
                </Box>
              </Tooltip>
            ) : (
              <Flex
                align="center"
                gap={8}
                sx={() => ({
                  flexWrap: 'nowrap'
                })}
              >
                <Typography
                  variant="body-sm"
                  sx={{
                    flex: 1,
                    overflow: 'hidden',
                    textOverflow: 'ellipsis',
                    whiteSpace: 'break-spaces',
                    wordBreak: 'break-all',
                    display: '-webkit-box',
                    WebkitLineClamp: v.lines ?? 1,
                    WebkitBoxOrient: 'vertical'
                  }}
                >
                  {v.value}
                </Typography>
              </Flex>
            )}
            {v.copyContent && (
              <CopyButton value={v.copyContent}>
                {({ copied, copy }) => (
                  <Tooltip label={copied ? 'Copied' : 'Copy'} withArrow multiline>
                    <ActionIcon aria-label="Copy" variant="transparent" size={18} onClick={copy}>
                      <IconCopy03 />
                    </ActionIcon>
                  </Tooltip>
                )}
              </CopyButton>
            )}
          </Flex>
        ))}
      </>
    )
  }

  const editNameModal = (
    <Modal
      title="Edit App Name"
      opened={editNameModalOpened}
      centered
      trapFocus={false}
      onClose={() => setEditNameModalOpened(false)}
    >
      <Form form={formProps} onSubmit={updateName} formMode="onChange" onCancel={() => setEditNameModalOpened(false)}>
        <FormTextInput label="App Name" name="app_name" placeholder="Data App Name" rules={DATA_APP_NAME_RULES} />

        <Flex direction="column">
          <Typography variant="title-md" fw={500} mb={8}>
            App Version
          </Typography>
          <Flex gap={16} align="flex-start">
            <FormTextInput
              name="major"
              placeholder="0-9999"
              min={1}
              max={9999}
              rules={{
                ...APP_VERSION_RULES,
                required: 'Please enter major'
              }}
            />
            <FormTextInput
              label=""
              name="minor"
              placeholder="0-9999"
              max={9999}
              rules={{
                ...APP_VERSION_RULES,
                required: 'Please enter minor'
              }}
            />
            <FormTextInput
              label=""
              name="patch"
              placeholder="0-9999"
              max={9999}
              rules={{
                ...APP_VERSION_RULES,
                required: 'Please enter patch'
              }}
            />
          </Flex>
        </Flex>

        <FormTextInput
          label={
            <Flex>
              <Typography variant="label-lg">Description</Typography>
              <Typography variant="label-lg" c="carbon.6" ml={4}>
                (Optional)
              </Typography>
            </Flex>
          }
          name="description"
          placeholder="Provide a Data App description (up to 1000 characters)"
          maxLength={1000}
        />
      </Form>
    </Modal>
  )

  return (
    <>
      <Card pt={24} px={24} pb={6} h="100%">
        {topButton}
        <Flex align="center" mb={24}>
          <Typography variant="label-md" w={100} sx={{ flexShrink: 0 }}>
            Base URL
          </Typography>
          <Tooltip label={baseUrl} withArrow multiline sx={{ wordBreak: 'break-all', whiteSpace: 'break-spaces' }}>
            <Box sx={{ width: 0, flex: 1 }}>
              <Typography variant="body-sm" sx={() => ({ overflow: 'hidden', textOverflow: 'ellipsis' })}>
                {baseUrl}
              </Typography>
            </Box>
          </Tooltip>

          <Flex gap={8} align="center">
            <Box
              sx={{
                position: 'relative',
                width: 24,
                height: 24
              }}
            >
              <Box
                component={IconChevronUp}
                size={16}
                sx={{ position: 'absolute', top: 0, cursor: 'pointer' }}
                c={baseUrls.length > 1 ? 'carbon.7' : 'carbon.4'}
                onClick={() => {
                  setCurBaseUrlIdx(curBaseUrlIdx > 0 ? curBaseUrlIdx - 1 : baseUrls.length - 1)
                }}
              ></Box>
              <Box
                component={IconChevronDown}
                size={16}
                sx={{ position: 'absolute', bottom: 0, cursor: 'pointer' }}
                c={baseUrls.length > 1 ? 'carbon.7' : 'carbon.4'}
                onClick={() => {
                  setCurBaseUrlIdx(curBaseUrlIdx < baseUrls.length - 1 ? curBaseUrlIdx + 1 : 0)
                }}
              ></Box>
            </Box>
            <CopyButton value={baseUrl}>
              {({ copied, copy }) => (
                <Tooltip label={copied ? 'Copied' : 'Copy'} withArrow multiline>
                  <ActionIcon aria-label="Copy" variant="transparent" size={18} onClick={copy}>
                    <IconCopy03 />
                  </ActionIcon>
                </Tooltip>
              )}
            </CopyButton>
          </Flex>
        </Flex>
        <Flex gap={16} mb={24}>
          <Box
            sx={{
              flex: 1
            }}
          >
            {renderPropertiesConfig(propertiesConfig)}
          </Box>
          <Box
            sx={(theme) => ({
              width: 1,
              backgroundColor: theme.colors.carbon[4]
            })}
          ></Box>
          <Box sx={{ flex: 1 }}>{renderPropertiesConfig(rightPropertiesConfig)}</Box>
        </Flex>
      </Card>
      {editNameModal}
    </>
  )
}

export default BasicSetting
