import { Box, Card, Flex, Modal, notifier, Table, Typography } from '@tidbcloud/uikit'
import { observer } from 'mobx-react'
import React, { Fragment, useEffect, useState } from 'react'

import { cancelBindedTenantSupportPlan, FormsSupportPlan, tenantBindPublicSupportPlan } from 'dbaas/services'
import { getErrorMessage } from 'dbaas/services/errorCodes'
import useStores from 'dbaas/stores/useStores'

import { FeatureItem } from '../Plans'
import { PlanFeatures, PlanLevels, PlanTier, PurchaseParams } from '../Plans/plans'

import { SumCard } from './FormCard'

export const Purchase: React.FC<
  React.PropsWithChildren<{
    bindedPlan: FormsSupportPlan
    eligibleForFreeTrial?: boolean
    plansMap: Record<string, FormsSupportPlan>
    onComplete: () => void
    planTiers: PlanTier[]
    opened: boolean
    onClose: () => void
    purchaseParams: PurchaseParams
  }>
> = observer(
  ({ plansMap, onComplete, planTiers, bindedPlan, eligibleForFreeTrial, opened, onClose, purchaseParams }) => {
    const {
      store: { tenantData },
      actions: { fetchPaymentMethods, fetchOrgBillingInfo, fetchBillingProfile, fetchTenantPlanInfo }
    } = useStores()

    const [loading, setLoading] = useState(false)

    const level = purchaseParams.level || PlanLevels.DEVELOPER
    const action = purchaseParams.action || ''

    const isDowngrade = action === 'downgrade'

    const plan = plansMap[level]

    const planTiersMap = planTiers.reduce(
      (acc, item) => {
        acc[item.level] = item
        return acc
      },
      {} as Record<string, PlanTier>
    )

    const planCfg = planTiersMap[level] || planTiers[1]

    const currentPlanCfg = planTiersMap[bindedPlan.level || ''] || planTiers[1]

    useEffect(() => {
      fetchPaymentMethods(tenantData.id)
      fetchBillingProfile(tenantData.id)
      fetchOrgBillingInfo()
      fetchTenantPlanInfo()
    }, [])

    const onConfirm = async () => {
      if (loading) {
        return
      }
      setLoading(true)
      try {
        if (bindedPlan.level !== PlanLevels.BASIC) {
          await cancelBindedTenantSupportPlan(tenantData.id)
        }
        if (plan.level !== PlanLevels.BASIC) {
          await tenantBindPublicSupportPlan(tenantData.id, {
            support_plan_id: plan.support_plan_id
          })
        }
        onComplete()
      } catch (e) {
        notifier.error(getErrorMessage(e))
      } finally {
        setLoading(false)
      }
    }

    const availablePlanTiers = [currentPlanCfg, planCfg]

    const showFeature = (rowIndex: number, colIndex: number) => {
      if (!currentPlanCfg.features[rowIndex].features[colIndex] && !planCfg.features[rowIndex].features[colIndex]) {
        return false
      }
      return true
    }

    return (
      <Modal
        title={`${isDowngrade ? 'Downgrade' : 'Upgrade'}`}
        size={1200}
        withinPortal
        styles={{ content: { height: 'calc(100dvh - var(--modal-y-offset) * 2)' } }}
        opened={opened}
        onClose={onClose}
        closeOnClickOutside={false}
      >
        <Flex w="100%" gap={24}>
          <Card p={0} sx={{ flex: 1, width: '100%', flexDirection: 'column' }}>
            <Table
              horizontalSpacing={16}
              verticalSpacing={10}
              sx={{ tableLayout: 'fixed' }}
              withColumnBorders={false}
              withRowBorders={false}
            >
              <Box component="thead" bg="carbon.2">
                <Table.Tr>
                  <Box
                    component={Table.Th}
                    sx={(theme) => ({ borderRight: `1px solid ${theme.colors.carbon[3]} !important` })}
                  >
                    <Typography variant="body-sm" c="carbon.7">
                      Current:
                    </Typography>
                    <Typography variant="title-lg">{currentPlanCfg.title} Plan</Typography>
                  </Box>
                  <Table.Th>
                    <Typography variant="body-sm" c="carbon.7">
                      {isDowngrade ? 'Downgrade' : 'Upgrade'} to:
                    </Typography>
                    <Typography variant="title-lg">{planCfg.title} Plan</Typography>
                  </Table.Th>
                </Table.Tr>
              </Box>
              <Table.Tbody>
                {PlanFeatures.map((feature, rowIndex) => {
                  return (
                    <Fragment key={feature.title}>
                      <Table.Tr
                        sx={(theme) => ({
                          borderBottom: `1px solid ${theme.colors.carbon[3]}`,
                          borderTop: rowIndex ? `1px solid ${theme.colors.carbon[3]}` : undefined
                        })}
                      >
                        <Table.Td sx={(theme) => ({ borderRight: `1px solid ${theme.colors.carbon[3]} !important` })}>
                          <Typography variant="title-sm">{feature.title}</Typography>
                        </Table.Td>
                        <Table.Td>
                          <Typography variant="title-sm">{feature.title}</Typography>
                        </Table.Td>
                      </Table.Tr>
                      {feature.items.map((item, itemIndex) => {
                        return (
                          <Table.Tr key={item}>
                            {availablePlanTiers.map((plan, planIndex) => {
                              if (!showFeature(rowIndex, itemIndex)) {
                                return null
                              }
                              return (
                                <Table.Td
                                  key={plan.level}
                                  sx={(theme) => ({
                                    borderTop: itemIndex ? '1px solid transparent !important' : undefined,
                                    borderRight: !planIndex
                                      ? `1px solid ${theme.colors.carbon[3]} !important`
                                      : undefined
                                  })}
                                >
                                  <FeatureItem raw={item} features={[plan.features[rowIndex].features[itemIndex]]} />
                                </Table.Td>
                              )
                            })}
                          </Table.Tr>
                        )
                      })}
                    </Fragment>
                  )
                })}
                <Table.Tr>
                  <Table.Td
                    sx={(theme) => ({
                      borderRight: `1px solid ${theme.colors.carbon[3]}`
                    })}
                  ></Table.Td>
                  <Table.Td></Table.Td>
                </Table.Tr>
              </Table.Tbody>
            </Table>
          </Card>
          <div style={{ alignSelf: 'flex-start' }}>
            <SumCard
              orgId={tenantData.id}
              planCfg={planCfg}
              currentPlanCfg={currentPlanCfg}
              bindedPlan={bindedPlan}
              onComplete={onConfirm}
              isDowngrade={isDowngrade}
              onCancel={onClose}
              isFreeTrial={eligibleForFreeTrial && level === PlanLevels.DEVELOPER}
            />
          </div>
        </Flex>
      </Modal>
    )
  }
)
