import {
  UploadOutlined,
  MinusCircleOutlined,
  PlusOutlined
} from '@ant-design/icons'
import {
  Button,
  Form,
  Input,
  Steps,
  Upload,
  Space,
  Select,
  InputNumber,
  List,
  Image
} from 'antd'
import { FormInstance } from 'antd/es/form/Form'
import dayjs from 'dayjs'
import { useEffect, useState } from 'react'

import {
  FormsSupportPlan,
  FormsSupportPlanInput
} from 'apiClient/api/interface'
import auth from 'apiClient/auth'
import { dbaasUrl } from 'apiClient/endpoint'
import { createMspOrg, updateMspOrg } from 'apiClient/services/account'
import { FormsMspOrg } from 'apiClient/services/account/interface'
import { setupPaymentMethodV1 } from 'apiClient/services/billing'
import {
  tenantBindPrivateSupportPlan,
  useGetPublicSupportPlan
} from 'apiClient/services/billing'
import ModalForm from 'components/ModalForm'
import {
  PlanLevels,
  convertMonthlyUsage
} from 'pages/Tenants/TenantDetail/BusinessInfo/SupportPlan'
import { SupportPlanCostType } from 'pages/Tenants/TenantDetail/BusinessInfo/SupportPlan'
import { formatSupportPlanType } from 'pages/Tenants/TenantDetail/BusinessInfo/SupportPlan'
import { formatMonthlyUsage } from 'pages/Tenants/TenantDetail/BusinessInfo/SupportPlan'

const { Step } = Steps

const CREATE_STEPS = {
  INITIAL: 0,
  CREATE: 1,
  DONE: 2
} as const

export interface MSPConfig extends FormsMspOrg {
  support_plan: FormsSupportPlanInput
  logo_url?: string
}

const { TextArea } = Input

const MSPPreview: React.FC<React.PropsWithChildren<{ data: MSPConfig }>> = ({
  data
}) => {
  const style: React.CSSProperties = {
    width: 200,
    display: 'inline-block',
    textAlign: 'right'
  }

  return (
    <Space direction="vertical">
      <Space>
        <span style={style}>Contact Email: </span>
        <span>{data.email}</span>
      </Space>
      <Space>
        <span style={style}>Custom URL:</span>
        <span>https://tidbcloud.com/signup?msp={data.name}</span>
      </Space>
      <Space>
        <span style={style}>Name: </span>
        <span>{data.name}</span>
      </Space>
      <Space>
        <span style={style}>Logo:</span>
        <Image
          width={80}
          height={80}
          src={data.logo_url ?? 'error'}
          fallback="data:image/png;base64,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"
        ></Image>
      </Space>
      <Space align="start">
        <span style={style}>Support Plan level: </span>
        <div>
          <div>
            <span>{data.support_plan.level}</span>
          </div>
          <div style={{ marginTop: 4 }}>
            <span>Support Plan Type: </span>
            <span>{formatSupportPlanType(data.support_plan.type || '')}</span>
          </div>
          <div style={{ marginTop: 4 }}>
            <span>Minimum cost per month basis: </span>
            <span>{data.support_plan.fixed_charge_price}</span>
          </div>
          <div style={{ marginTop: 4 }}>
            <span>Percentage of monthly usage: </span>
            <span>
              {formatMonthlyUsage(
                data.support_plan.support_price_percentage || '0'
              )}
              %
            </span>
          </div>
        </div>
      </Space>
      <Space>
        <span style={style}>Disclaimers: </span>
        <span>{data.disclaimers}</span>
      </Space>
      <div style={{ display: 'flex', gap: 8 }}>
        <span style={style}>Advertising Texts: </span>
        <List itemLayout="horizontal" style={{ flex: 1 }}>
          {(data.advertising_arr || []).map((text, index) => {
            return (
              <List.Item
                key={index}
                style={{ paddingTop: index === 0 ? 0 : undefined }}
              >
                <List.Item.Meta
                  title={text.heading}
                  description={text.body}
                ></List.Item.Meta>
              </List.Item>
            )
          })}
        </List>
      </div>
    </Space>
  )
}

export const CreateOrUpdateMSP: React.FC<
  React.PropsWithChildren<{
    onComplete?: () => void
    action: 'add' | 'update'
    initValues?: MSPConfig
    title?: string
    actionText?: string
  }>
> = ({
  onComplete,
  action = 'add',
  initValues,
  title = 'Create MSP',
  actionText = 'Create'
}) => {
  const [visible, setVisible] = useState(false)
  const [steps, setSteps] = useState<number>(CREATE_STEPS.INITIAL)
  const [value, setValue] = useState<MSPConfig | null>(null)
  const [selectedType, setSelectedType] = useState<string>(
    SupportPlanCostType.PERCENTAGE_PRICE
  )
  const [selectedLevel, setSelectedLevel] = useState<string>(
    PlanLevels.ENTERPRISE
  )
  const [logo, setLogo] = useState('')

  const { data, isFetched } = useGetPublicSupportPlan()

  const onSubmit = async (data: MSPConfig) => {
    if (steps === CREATE_STEPS.INITIAL) {
      if (data.support_plan.support_price_percentage) {
        data.support_plan.support_price_percentage = convertMonthlyUsage(
          data?.support_plan.support_price_percentage || ''
        )
      }
      setValue(data)
      setSteps(CREATE_STEPS.CREATE)
      return
    }
    if (steps === CREATE_STEPS.CREATE && value) {
      if (action === 'add') {
        const res = await createMspOrg(value)
        await setupPaymentMethodV1(res.data.org_id || '', 'wire_transfer')
        await tenantBindPrivateSupportPlan(res.data.org_id || '', {
          ...value.support_plan,
          active_date: dayjs().format('YYYY-MM-DD') + 'T00:00:00Z'
        })
        setSteps(CREATE_STEPS.DONE)
        return
      } else {
        await updateMspOrg({
          org_id: initValues?.org_id,
          logo_name: value.logo_name || undefined,
          website: value.website,
          disclaimers: value.disclaimers,
          advertising_arr: value.advertising_arr
        })
      }
    }
    onComplete?.()
    onClose(true)
  }

  const onClose = (close = false) => {
    if (!close && steps === CREATE_STEPS.CREATE) {
      setSteps(CREATE_STEPS.INITIAL)
      return
    }
    setValue(null)
    setSteps(CREATE_STEPS.INITIAL)
    setVisible(false)
  }

  useEffect(() => {
    if (action === 'update' && initValues) {
      setSelectedLevel(initValues.support_plan.level || PlanLevels.ENTERPRISE)
    }
  }, [action, initValues])

  const publicPlans = (data?.data || []).reduce<
    Record<string, FormsSupportPlan>
  >((prev, next) => {
    prev[next.level || ''] = next
    return prev
  }, {})

  const readOnly = action === 'update'

  const renderFields = (form: FormInstance) => {
    return (
      <>
        <Steps current={steps} size="small" style={{ marginBottom: 16 }}>
          <Step title="Configure MSP Details" />
          <Step title="Confirm" />
          {action === 'add' && <Step title="Done" />}
        </Steps>
        {steps === CREATE_STEPS.INITIAL && (
          <>
            <Form.Item
              name="email"
              label="Contact Email"
              required
              rules={[
                { required: true, type: 'email', message: 'Invalid Email' }
              ]}
            >
              <Input type="email" disabled={readOnly} />
            </Form.Item>
            <Form.Item
              name="name"
              label="Name"
              required
              rules={[
                {
                  required: true,
                  message: 'Required'
                }
                // {
                //   validator: async (rule, value, callback) => {
                //     if (action === 'update') {
                //       return true
                //     }
                //     const data = await listTenants({ name: value })
                //     if (data.data.items?.length) {
                //       throw new Error('MSP name is used')
                //     }
                //     return true
                //   }
                // }
              ]}
            >
              <Input
                disabled={readOnly}
                addonBefore="https://tidbcloud.com/signup?msp="
              ></Input>
            </Form.Item>
            <Form.Item name="website" label="MSP Website">
              <Input></Input>
            </Form.Item>
            <Form.Item
              name={'logo_name'}
              label="MSP Logo"
              getValueFromEvent={(value) => {
                setLogo(value?.file?.response?.logo_url)
                return value?.file.response?.logo_name
              }}
              rules={[
                {
                  required: false,
                  message: 'Please upload file'
                }
              ]}
            >
              <Upload
                name={'file'}
                accept=".svg"
                multiple={false}
                headers={{
                  Authorization: `Bearer ${auth.getAuthToken()}`
                }}
                action={`${dbaasUrl}/api/v1/admin/partner/msp/upload-logo`}
              >
                <Button icon={<UploadOutlined />}>
                  Upload a logo, only SVG is allowed
                </Button>
              </Upload>
            </Form.Item>
            <Form.Item label="Support Plan">
              <Form.Item name={['support_plan', 'level']}>
                {selectedLevel}
              </Form.Item>
              <Form.Item
                name={['support_plan', 'type']}
                label="Support Plan Type"
                rules={[{ required: true, message: 'Required' }]}
              >
                <Select
                  onChange={(value) => setSelectedType(value as string)}
                  disabled={readOnly}
                >
                  {[
                    SupportPlanCostType.FIXED_PRICE,
                    SupportPlanCostType.PERCENTAGE_PRICE
                  ].map((pl) => (
                    <Select.Option key={pl} value={pl || ''}>
                      {formatSupportPlanType(pl)}
                    </Select.Option>
                  ))}
                </Select>
              </Form.Item>
              <Form.Item label="Minimum cost per month basis" required>
                <Form.Item
                  name={['support_plan', 'fixed_charge_price']}
                  noStyle
                  rules={[{ required: true, message: 'Required' }]}
                >
                  <InputNumber
                    min="0"
                    stringMode
                    disabled={readOnly}
                    step="0.01"
                    style={{ display: 'inline-block', width: '90%' }}
                  ></InputNumber>
                </Form.Item>
                <span> $</span>
              </Form.Item>
              {selectedType === SupportPlanCostType.PERCENTAGE_PRICE && (
                <Form.Item label="Percentage of monthly usage" required>
                  <Form.Item
                    name={['support_plan', 'support_price_percentage']}
                    noStyle
                    rules={[{ required: true, message: 'Required' }]}
                  >
                    <InputNumber<string>
                      stringMode
                      disabled={readOnly}
                      min="0"
                      max="100"
                      step="0.01"
                      style={{ display: 'inline-block', width: '90%' }}
                    ></InputNumber>
                  </Form.Item>
                  <span> %</span>
                </Form.Item>
              )}
            </Form.Item>
            {/* <Form.Item name="disclaimers" label="Disclaimers">
              <Input></Input>
            </Form.Item> */}
            <Form.Item label="Advertising Texts">
              <Form.List
                name="advertising_arr"
                rules={[
                  {
                    validator: async (_, texts) => {
                      if (texts && texts.length > 4) {
                        return Promise.reject(
                          new Error('No more than 4 paragraph')
                        )
                      }
                    }
                  }
                ]}
              >
                {(fields, { add, remove }) => (
                  <>
                    {fields.map(({ key, name, ...restField }, index) => (
                      <Form.Item key={index}>
                        <Form.Item
                          {...restField}
                          name={[name, 'heading']}
                          rules={[
                            { required: true, message: 'Missing heading' },
                            { max: 40, message: 'No more than 40 characters' }
                          ]}
                        >
                          <Input placeholder="Heading" />
                        </Form.Item>
                        <div style={{ display: 'flex', alignItems: 'center' }}>
                          <Form.Item
                            {...restField}
                            name={[name, 'body']}
                            rules={[
                              { required: true, message: 'Missing body' },
                              {
                                max: 200,
                                message: 'No more than 200 characters'
                              }
                            ]}
                            noStyle
                          >
                            <TextArea
                              placeholder={'Body'}
                              style={{ flex: 1, marginRight: 4 }}
                            />
                          </Form.Item>
                          <MinusCircleOutlined onClick={() => remove(name)} />
                        </div>
                      </Form.Item>
                    ))}

                    {fields.length < 4 && (
                      <Form.Item>
                        <Button
                          type="dashed"
                          onClick={() => add()}
                          block
                          icon={<PlusOutlined />}
                        >
                          Add
                        </Button>
                      </Form.Item>
                    )}
                  </>
                )}
              </Form.List>
            </Form.Item>
          </>
        )}
        {steps === CREATE_STEPS.CREATE && !!value && (
          <MSPPreview
            data={{ ...value, logo_url: logo || initValues?.logo_url }}
          ></MSPPreview>
        )}
        {steps === CREATE_STEPS.DONE && (
          <div style={{ marginTop: 24 }}>
            An initial API Key with role "MSP owner" is sent to{' '}
            <a>{value?.email}</a>. MSP can start MSP management form the initial
            API Key
          </div>
        )}
      </>
    )
  }

  return (
    <div>
      <Button type="primary" onClick={() => setVisible(true)}>
        {actionText}
      </Button>
      {isFetched && (
        <ModalForm
          width={750}
          initValues={{
            support_plan: {
              ...publicPlans[selectedLevel],
              support_price_percentage: formatMonthlyUsage(
                publicPlans[selectedLevel]?.support_price_percentage || '0'
              ).toString()
            },
            ...initValues
          }}
          name="create-msp-form"
          title={title}
          visible={visible}
          onSubmit={onSubmit}
          onCancel={() => onClose(false)}
          getFields={renderFields}
          cancelText={steps === CREATE_STEPS.CREATE ? 'Prev' : 'Cancel'}
          okText={steps === CREATE_STEPS.INITIAL ? 'Next' : 'Confirm'}
          destoryOnClose
        ></ModalForm>
      )}
    </div>
  )
}
