import { SmileOutlined } from '@ant-design/icons'
import { Form, FormInstance, Input, Select, Typography } from 'antd'
import TextArea from 'antd/lib/input/TextArea'

import {
  EntityRemediationApprovalFlow,
  EntityRemediationTicket,
  EntityRemediationTicketPhase
} from 'apiClient/services/devops/interface'

const { Paragraph, Text } = Typography

export interface PhaseFieldInfo {
  name: string
  label: string
}

export interface PhaseFieldRenderOptions {
  requiresInput?: boolean
}

export interface PhaseInstance {
  name: EntityRemediationTicketPhase
  label: string
  isfinal: boolean
  isoptional?: boolean
  getFields?: (
    form?: FormInstance,
    ticket?: EntityRemediationTicket,
    options?: PhaseFieldRenderOptions
  ) => React.ReactNode
  fieldList?: PhaseFieldInfo[]
  approvalInfo?: () => React.ReactNode
  checkItems?: React.ReactNode[]
  icon?: React.ReactNode
}

// Phase 1: phase created
const phaseCreatedFields = (
  form?: FormInstance,
  ticket?: EntityRemediationTicket
) => {
  return (
    <>
      <Form.Item label="Customer" name="customer">
        <Input />
      </Form.Item>
      <Form.Item label="Tenant ID" name="tenant_id">
        <Input />
      </Form.Item>
      <Form.Item label="Cluster ID" name="cluster_id">
        <Input />
      </Form.Item>
      <Form.Item label="Cluster Type" name="cluster_type">
        <Select
          options={[
            { value: 'serverless', label: 'Serverless' },
            {
              value: 'dedicated_multi_tidb',
              label: 'Dedicated - Multiple TiDB Nodes'
            },
            {
              value: 'dedicated_single_tidb',
              label: 'Dedicated - Single TiDB Node'
            }
          ]}
        />
      </Form.Item>
    </>
  )
}

const phaseCreated: PhaseInstance = {
  name: 'created',
  label: 'Creator',
  isfinal: false,
  isoptional: false,
  getFields: phaseCreatedFields
}

// Phase 2: phase region TSE leader
const phaseRegionTSELeaderFields = (
  form?: FormInstance,
  ticket?: EntityRemediationTicket,
  options?: PhaseFieldRenderOptions
) => {
  const requiresInput = options?.requiresInput ?? true
  return (
    <>
      <Form.Item
        label="Root Cause Analysis from TSE"
        name="root_cause_from_gs"
        rules={
          requiresInput
            ? [
                {
                  required: true,
                  message: 'Root Cause Analysis from TSE is required'
                }
              ]
            : []
        }
        required={requiresInput}
      >
        <TextArea rows={6} />
      </Form.Item>
    </>
  )
}

const phaseRegionTSELeaderApprovalInfo = () => {
  return (
    <Typography>
      <Paragraph>
        Please check the following item carefully before approve or reject.
      </Paragraph>
    </Typography>
  )
}

const phaseRegionTSELeaderCheckItems = [
  <Typography>
    Is TiDB cloud <Text strong>really</Text> missed the SLA from RDG
    perspective?
  </Typography>,
  <Typography>
    Is the reported issue <Text strong>not</Text> caused by misuse, unauthorized
    modifications, or third-party hardware, software, or any other services
    other than TiDB Cloud?
  </Typography>,
  <Typography>Can we reproduce the issue?</Typography>
]

const phaseRegionTSELeader: PhaseInstance = {
  name: 'region_tse_leader',
  label: 'Region TSE Leader',
  isfinal: false,
  isoptional: false,
  getFields: phaseRegionTSELeaderFields,
  fieldList: [
    {
      name: 'root_cause_from_gs',
      label: 'Root Cause Analysis from TSE'
    }
  ],
  approvalInfo: phaseRegionTSELeaderApprovalInfo,
  checkItems: phaseRegionTSELeaderCheckItems
}

// Phase 3: phase EG SLA Owner
const phaseRDGSLAOwnerFields = (
  form?: FormInstance,
  ticket?: EntityRemediationTicket,
  options?: PhaseFieldRenderOptions
) => {
  const requiresInput = options?.requiresInput ?? true
  return (
    <>
      <Form.Item
        label="Accident Report Link"
        name="accident_report_link"
        rules={[{ required: true }, { type: 'url' }]}
      >
        <Input />
      </Form.Item>
      <Form.Item
        label="Root Cause Analysis from RDG"
        name="root_cause_from_rdg"
        rules={
          requiresInput
            ? [
                {
                  required: true,
                  message: 'Root Cause Analysis from RDG is required'
                }
              ]
            : []
        }
        required={requiresInput}
      >
        <TextArea rows={6} />
      </Form.Item>
    </>
  )
}

const phaseRDGSLAOwnerApprovalInfo = () => {
  return (
    <Typography>
      <Paragraph>
        Please check the following item carefully before approve or reject.
      </Paragraph>
    </Typography>
  )
}

const phaseRDGSLAOwnerCheckItems = [
  <Typography>
    Confirm TiDB Cloud missed the SLA for reasons that may require customer
    compensation. If no compensation is required, please reject the ticket.
  </Typography>
]

const phaseRDGSLAOwner: PhaseInstance = {
  name: 'rdg_sla_owner',
  label: 'EG SLA Owner',
  isfinal: false,
  isoptional: false,
  getFields: phaseRDGSLAOwnerFields,
  fieldList: [
    {
      label: 'Accident Report Link',
      name: 'accident_report_link'
    },
    {
      label: 'Root Cause Analysis from RDG',
      name: 'root_cause_from_rdg'
    }
  ],
  approvalInfo: phaseRDGSLAOwnerApprovalInfo,
  checkItems: phaseRDGSLAOwnerCheckItems
}

const phaseFinalDecisionMakerApprovalInfo = () => {
  return (
    <Typography>
      <Paragraph>
        Please check the following item carefully before approve or reject.
      </Paragraph>
    </Typography>
  )
}

const phaseFinalDecisionMakerCheckItems = [
  <Typography>Double check EG SLA Owner's conclusion.</Typography>,
  <Typography>Confirm the Monthly Uptime Percentage.</Typography>
]

// Phase 4: phase EG decision maker
const phaseRDGFinalDecisionMaker: PhaseInstance = {
  name: 'rdg_final_decision_maker',
  label: 'EG Decision Maker',
  isfinal: false,
  isoptional: false,
  approvalInfo: phaseFinalDecisionMakerApprovalInfo,
  checkItems: phaseFinalDecisionMakerCheckItems
}

// Phase 5: phase global deal desk
const calculateCompensation = (
  clusterBilling: string,
  ticket: EntityRemediationTicket
) => {
  const numBilling = Number(clusterBilling)
  if (numBilling === 0) return 0

  const slaVal = Number(ticket.monthly_uptime_percentage)
  if (slaVal === 0) return 0
  switch (ticket.cluster_type) {
    case 'dedicated_multi_tidb':
      if (slaVal < 0.9999 && slaVal > 0.99) return numBilling * 0.1
      if (slaVal < 0.99 && slaVal > 0.95) return numBilling * 0.25
      if (slaVal < 0.95) return numBilling * 0.1
      break
    case 'dedicated_single_tidb':
      if (slaVal < 0.999 && slaVal > 0.99) return numBilling * 0.1
      if (slaVal < 0.99 && slaVal > 0.95) return numBilling * 0.25
      if (slaVal < 0.95) return numBilling * 0.1
      break
    case 'serverless':
      if (slaVal < 0.999 && slaVal > 0.99) return numBilling * 0.1
      if (slaVal < 0.99 && slaVal > 0.95) return numBilling * 0.25
      if (slaVal < 0.95) return numBilling * 0.1
      break
    default:
      return 0
  }
}

const phaseGlobalDealDeskFields = (
  form?: FormInstance,
  ticket?: EntityRemediationTicket
) => {
  return (
    <>
      <Form.Item
        label="Cluster Billing (US dollar)"
        name="cluster_billing"
        rules={[
          { required: true },
          { type: 'number', min: 0, transform: (n) => Number(n) }
        ]}
      >
        <Input prefix="$" />
      </Form.Item>
      <Form.Item
        noStyle
        shouldUpdate={(prevValues, currentValues) =>
          prevValues.cluster_billing !== currentValues.cluster_billing
        }
      >
        {({ getFieldValue }) =>
          getFieldValue('cluster_billing') ? (
            <Typography>
              <pre>
                Accoring to{' '}
                <Typography.Link
                  target="#"
                  href="https://pingcap.feishu.cn/wiki/Wt2cw8ckniBHe2kiDxTcjeQ1n1e"
                >
                  End Customer Remediation Process
                </Typography.Link>
                .
                <br />
                Calculated compensation value: $
                {calculateCompensation(
                  getFieldValue('cluster_billing'),
                  ticket!
                )}
              </pre>
            </Typography>
          ) : null
        }
      </Form.Item>
      <Form.Item
        label="Compensation Value (US dollar)"
        name="total_compensation"
        rules={[
          { required: true },
          { type: 'number', min: 0, transform: (n) => Number(n) }
        ]}
      >
        <Input prefix="$" />
      </Form.Item>
    </>
  )
}

const phaseGlobalDealDeskApprovalInfo = () => {
  return (
    <Typography>
      <Paragraph>
        Please check the following item carefully before approve or reject.
      </Paragraph>
    </Typography>
  )
}

const phaseGlobalDealDeskCheckItems = [
  <Typography>
    All necessary supporting documents have been presented.
  </Typography>,
  <Typography>We already have a clear remedy logic.</Typography>
]

const phaseGlobalDealDesk: PhaseInstance = {
  name: 'global_deal_desk',
  label: 'Global Deal Desk',
  isfinal: false,
  isoptional: false,
  getFields: phaseGlobalDealDeskFields,
  fieldList: [
    {
      label: 'Cluster Billing (US dollar)',
      name: 'cluster_billing'
    },
    {
      label: 'Total Compensation (US dollar)',
      name: 'total_compensation'
    }
  ],
  approvalInfo: phaseGlobalDealDeskApprovalInfo,
  checkItems: phaseGlobalDealDeskCheckItems
}

// phase 6(optional): phase commercial operation
const phaseCommercialOperationFields = (form?: FormInstance) => {
  return <Typography></Typography>
}

const phaseCommercialOperationApprovalInfo = () => {
  return <Typography></Typography>
}

const phaseCommercialOperationCheckItems = [
  <Typography>The Extra Remediation Percent is OK.</Typography>
]

const phaseCommercialOperation: PhaseInstance = {
  name: 'commercial_operation',
  label: 'Commercial Operation',
  isfinal: false,
  isoptional: true,
  getFields: phaseCommercialOperationFields,
  approvalInfo: phaseCommercialOperationApprovalInfo,
  checkItems: phaseCommercialOperationCheckItems
}

// Phase 7: phase regional GM
const phaseRegionalGMFields = (
  form?: FormInstance,
  ticket?: EntityRemediationTicket
) => {
  return (
    <Typography>No further info needed. Click "Submit" to proceed.</Typography>
  )
}

const phaseRegionGMApprovalInfo = () => {
  return <Typography></Typography>
}

const phaseRegionalGMCheckItems = [
  <Typography>
    The compensation value(Service Credit Value) is consistent with the SLA term
    and it's acceptable.
  </Typography>,
  <Typography>Extra compensation value is ok.</Typography>
]

const phaseRegionalGM: PhaseInstance = {
  name: 'regional_gm',
  label: 'Regional GM',
  isfinal: false,
  isoptional: false,
  getFields: phaseRegionalGMFields,
  approvalInfo: phaseRegionGMApprovalInfo,
  checkItems: phaseRegionalGMCheckItems
}

// Succeed phase
const phaseSucceed: PhaseInstance = {
  name: 'succeed',
  label: 'Succeed',
  icon: <SmileOutlined />,
  isfinal: true
}

// Closed phase
const phaseClosed: PhaseInstance = {
  name: 'closed',
  label: 'Closed',
  isfinal: true
}

const phaseSequence = [
  phaseCreated,
  phaseRegionTSELeader,
  phaseRDGSLAOwner,
  phaseGlobalDealDesk,
  phaseRDGFinalDecisionMaker,
  phaseCommercialOperation,
  phaseRegionalGM,
  phaseSucceed,
  phaseClosed
]

const phaseMap = new Map<string, PhaseInstance>([
  ['created', phaseCreated],
  ['region_tse_leader', phaseRegionTSELeader],
  ['rdg_sla_owner', phaseRDGSLAOwner],
  ['rdg_final_decision_maker', phaseRDGFinalDecisionMaker],
  ['global_deal_desk', phaseGlobalDealDesk],
  ['commercial_operation', phaseCommercialOperation],
  ['regional_gm', phaseRegionalGM],
  ['succeed', phaseSucceed],
  ['closed', phaseClosed]
])

export function getPhaseSequence(): PhaseInstance[] {
  return phaseSequence
}

export function getConfiguredPhaseSequence(
  approvalFlow?: EntityRemediationApprovalFlow
): PhaseInstance[] {
  const flowNodes = approvalFlow?.nodes
  if (!flowNodes?.length) return phaseSequence

  const configuredPhaseSequence: PhaseInstance[] = []
  flowNodes.forEach((node) => {
    const phaseName = node.phase
    if (!phaseName) return

    const phase = phaseMap.get(phaseName)
    if (!phase) return

    configuredPhaseSequence.push({
      ...phase,
      label: node.label || phase.label,
      isoptional: node.conditional ?? phase.isoptional
    })
  })

  return configuredPhaseSequence
}

export function getPhaseLabel(
  phaseName?: string,
  approvalFlow?: EntityRemediationApprovalFlow
): string | undefined {
  if (!phaseName) return undefined

  const configuredPhase = getConfiguredPhaseSequence(approvalFlow).find(
    (phase) => phase.name === phaseName
  )
  if (configuredPhase) return configuredPhase.label

  return getPhaseByName(phaseName)?.label
}

export function getPhaseNo(
  phaseName: string,
  approvalFlow?: EntityRemediationApprovalFlow
): number {
  const configuredPhaseSequence = getConfiguredPhaseSequence(approvalFlow)
  for (let [index, phase] of configuredPhaseSequence.entries()) {
    if (phaseName === phase.name) return index + 1
  }
  return 0
}

export function getPhaseByName(phaseName: string): PhaseInstance | undefined {
  return phaseMap.get(phaseName)
}
