import { ActionIcon, Box, Card, Flex, Menu, Popover, Typography } from '@tidbcloud/uikit'
import { MRT_ColumnDef, ProTable } from '@tidbcloud/uikit/biz'
import { useDisclosure } from '@tidbcloud/uikit/hooks'
import { IconDotsHorizontal, IconHelpCircle, IconInfoCircle } from '@tidbcloud/uikit/icons'
import { capitalize } from 'lodash-es'
import { observer } from 'mobx-react'
import React, { useState } from 'react'

import { HeroComponent } from 'dbaas/components/Measurement'
import TimeComponent from 'dbaas/components/TimeComponent'
import { downloadContract, operateContract, useListUserViewContract } from 'dbaas/services/billing'
import { FormsBillingConfig, FormsContract } from 'dbaas/services/billing/interface'
import useStores from 'dbaas/stores/useStores'
import { eventTracking } from 'dbaas/utils/tracking'

import { openConfirmModal } from './modal'

enum ContractStatus {
  DRAFT = 'draft',
  DELETED = 'deleted',
  SUBMIT = 'submit', // Pending Activation
  CANCELED = 'canceled',
  ACTIVE = 'active',
  REJECTED = 'rejected',
  TERMINATED = 'terminated'
}

const StatusHeader = () => {
  const [opened, { close, open }] = useDisclosure(false)

  return (
    <Flex align="center" sx={{ zIndex: 10 }}>
      Status{' '}
      <Popover width={350} withArrow opened={opened} shadow="md">
        <Popover.Target>
          <IconHelpCircle size={16} style={{ marginLeft: 4 }} onMouseEnter={open} onMouseLeave={close} />
        </Popover.Target>
        <Popover.Dropdown>
          <Typography variant="body-lg">
            <IconInfoCircle size={14} /> After you receive a contract, the initial status of the contract is{' '}
            <b>Pending Activation</b>. After the content of the contract is verified, you can change the status to{' '}
            <b>Active</b>. At this point, the contract comes into force. The status of a contract is changed to{' '}
            <b>Terminated</b> on Expiration when the contract reaches the expiration date.
          </Typography>
        </Popover.Dropdown>
      </Popover>
    </Flex>
  )
}

export const Contracts: React.FC<React.PropsWithChildren<{ billingConfig: FormsBillingConfig; disabled?: boolean }>> =
  observer(({ billingConfig, disabled }) => {
    const {
      store: { tenantData }
    } = useStores()

    const [currentPage, setCurrentPage] = useState(1)
    const { data, isLoading, refetch, isFetched } = useListUserViewContract(
      tenantData.id,
      billingConfig.billing_config_id,
      {
        page: currentPage,
        page_size: 10
      }
    )

    const onDownload = async (id: string, contractID: string) => {
      eventTracking('Download Contract')
      const data = await downloadContract(tenantData.id, billingConfig.billing_config_id, id, {
        responseType: 'arraybuffer'
      })
      const file = new Blob([data as any as ArrayBuffer], {
        type: 'application/pdf'
      })
      const fileUrl = URL.createObjectURL(file)
      const a = document.createElement('a')
      document.body.appendChild(a)
      a.href = fileUrl
      a.download = `contract-${contractID}.pdf`
      a.click()
      setTimeout(() => {
        document.body.removeChild(a)
      }, 0)
    }

    const openAcceptModal = (id: string) => {
      return openConfirmModal({
        title: 'Accept Contract',
        content: (
          <>
            Before accepting the contract, you need to read and understand the content of contract.
            <br />
            Do you accept the contract?
          </>
        ),
        submitText: 'Accept',
        onSubmit: async () => {
          eventTracking('Accept Contract')
          await operateContract(tenantData.id, id, 'accept')
          await refetch()
        }
      })
    }

    const openRejectModal = (id: string) => {
      return openConfirmModal({
        title: 'Reject Contract',
        content: <>Are you sure to reject the contract?</>,
        submitText: 'Reject',
        onSubmit: async () => {
          eventTracking('Reject Contract')
          await operateContract(tenantData.id, id?.toString() || '', 'reject')
          await refetch()
        }
      })
    }

    const columns: MRT_ColumnDef<FormsContract>[] = [
      {
        header: 'Contract ID',
        accessorKey: 'contract_id',
        maxSize: 140
      },
      {
        Header: <StatusHeader />,
        header: '',
        id: 'status',
        minSize: 350,
        accessorFn: ({ status, operated_at, reason_for_last_operation }: FormsContract) => {
          return (
            <>
              {status === ContractStatus.SUBMIT ? 'Pending Activation' : capitalize(status)}
              {reason_for_last_operation && operated_at ? (
                <>
                  {' '}
                  ({reason_for_last_operation} on{' '}
                  <TimeComponent time={operated_at || ''} utcOffset={0} format="YYYY-MM-DD HH:mm:ss Z"></TimeComponent>)
                </>
              ) : null}
            </>
          )
        }
      },
      {
        header: 'Created At',
        accessorFn: ({ created_at }: FormsContract) => {
          return <TimeComponent time={created_at || ''} utcOffset={0} format="YYYY-MM-DD HH:mm:ss Z"></TimeComponent>
        }
      },
      {
        header: 'Actions',
        accessorFn: ({ status, id, contract_id }: FormsContract) => {
          const showDownload = status !== ContractStatus.CANCELED
          const showActions = status === ContractStatus.SUBMIT && !disabled

          if (!showDownload && !showActions) {
            return null
          }

          return (
            <Menu position="bottom">
              <Menu.Target>
                <ActionIcon size={32}>
                  <IconDotsHorizontal size={16} />
                </ActionIcon>
              </Menu.Target>
              <Menu.Dropdown>
                {showActions && (
                  <>
                    <Menu.Item
                      onClick={() => {
                        eventTracking('mp-accept-1691461016078')
                        openAcceptModal(id?.toString() || '')
                      }}
                    >
                      Accept
                    </Menu.Item>
                    <Menu.Item
                      onClick={() => {
                        eventTracking('mp-reject-1691461016080')
                        openRejectModal(id?.toString() || '')
                      }}
                    >
                      Reject
                    </Menu.Item>
                  </>
                )}
                {showDownload && (
                  <Menu.Item
                    onClick={() => {
                      eventTracking('mp-download-1691461016076')
                      onDownload(id?.toString() || '', contract_id)
                    }}
                  >
                    Download
                  </Menu.Item>
                )}
              </Menu.Dropdown>
            </Menu>
          )
        }
      }
    ]

    return (
      <Box pb={96}>
        <Card p={24}>
          <ProTable
            columns={columns}
            data={data?.contracts || []}
            loading={isLoading}
            emptyMessage="No Data"
            manualPagination={true}
            pagination={
              data?.total_results
                ? {
                    total: Math.ceil((data?.total_results || 0) / 10) || 0,
                    value: data?.page || 1,
                    onChange: (page) => {
                      setCurrentPage(page)
                    }
                  }
                : undefined
            }
          />
          {isFetched && <HeroComponent />}
        </Card>
      </Box>
    )
  })
