import { Group, Stack } from '@tidbcloud/uikit'
import { Alert, Button, Divider, message, Modal } from 'antd'
import { useEffect, useState } from 'react'
import { FormProvider, useForm } from 'react-hook-form'
import { useQueryClient } from 'react-query'

import {
  getGetApiV1DevopsBillingProxyApiV1BillingSkuGroupsQueryKey,
  usePostApiV1DevopsBillingProxyApiV1BillingSkuGroups,
  usePutApiV1DevopsBillingProxyApiV1BillingSkuGroupsGroupId
} from 'apiClient/services/billing'
import { FormsSKUGroup } from 'apiClient/services/billing/interface'

import { SKUGroupForm, SKUGroupFormProps } from './SKUGroupForm'
import { UnitListTable } from './UnitListTable'
import { DEFAULT_SKU_GROUP_TYPE, isManualPriceSKUGroup } from './utils'

export interface SKUGroupModalProps extends SKUGroupFormProps {
  open: boolean
  data?: FormsSKUGroup
  onClose?: () => void
}

export type SKUGroupModalType = 'view' | 'edit' | 'create'

const getInitialValues = () => {
  return {
    category: '',
    group_id: 0,
    measure_unit: '',
    name: '',
    price_expression: {},
    price_formula: '',
    price_type: '',
    sku_group_type: DEFAULT_SKU_GROUP_TYPE,
    unit_key_pattern: ''
  }
}

const normalizeSKUGroupData = (data?: FormsSKUGroup) => ({
  ...getInitialValues(),
  ...data,
  sku_group_type: data?.sku_group_type || DEFAULT_SKU_GROUP_TYPE
})

export const SKUGroupModal = (props: SKUGroupModalProps) => {
  const client = useQueryClient()
  const { open, onClose: _onClose, ...skuGroupProps } = props
  const [innerData, setInnerData] = useState<FormsSKUGroup>()
  const { type, data: _data } = props
  const data = innerData || _data
  const methods = useForm<FormsSKUGroup>({
    defaultValues: getInitialValues()
  })
  const onClose = () => {
    _onClose?.()
    methods.reset(getInitialValues())
    setInnerData(undefined)
  }
  const {
    mutateAsync: createSKUGroup,
    isLoading: isCreating,
    isError: isCreateError,
    error: createError
  } = usePostApiV1DevopsBillingProxyApiV1BillingSkuGroups()
  const {
    mutateAsync: updateSKUGroup,
    isLoading: isUpdating,
    isError: isUpdateError,
    error: updateError
  } = usePutApiV1DevopsBillingProxyApiV1BillingSkuGroupsGroupId()
  const showUnitList = !!innerData || type === 'edit' || type === 'view'
  const isError = isCreateError || isUpdateError
  const error = createError || updateError
  const isLoading = isCreating || isUpdating

  useEffect(() => {
    if (!open && data) {
      return
    }
    methods.reset(normalizeSKUGroupData(data))
  }, [open, data])

  return (
    <Modal
      title="SKU Group"
      centered
      visible={open}
      onCancel={() => onClose?.()}
      width={1200}
      footer={null}
      closable={!isLoading}
      maskClosable={!isLoading}
    >
      <FormProvider {...methods}>
        <SKUGroupForm {...skuGroupProps} data={data} />
      </FormProvider>

      {type !== 'view' && (
        <Stack>
          {isError && (
            <Alert
              type="error"
              message={(error as any)?.response?.data?.message}
            />
          )}

          <Group justify="end" gap="xs">
            <Button loading={isLoading} onClick={onClose}>
              Cancel
            </Button>
            <Button
              loading={isLoading}
              type="primary"
              onClick={async () => {
                const { group_id, ...restData } = methods.getValues()
                if (isManualPriceSKUGroup(restData)) {
                  restData.price_formula = ''
                }
                try {
                  let res
                  if (type === 'create' && !group_id) {
                    res = await createSKUGroup({ data: restData })
                  } else if (type === 'edit' || !!group_id) {
                    res = await updateSKUGroup({
                      groupId: String(group_id!),
                      data: restData
                    })
                  }

                  setInnerData(res?.data)
                  client.refetchQueries(
                    getGetApiV1DevopsBillingProxyApiV1BillingSkuGroupsQueryKey()
                  )

                  message.success('Save successful!')
                } catch {}
              }}
            >
              Save
            </Button>
          </Group>
        </Stack>
      )}

      {open && showUnitList && (
        <>
          <Divider />
          <UnitListTable skuGroup={data!} type={type} />
        </>
      )}
    </Modal>
  )
}
