import { Group, HoverCard, Slider, Stack, Typography } from '@tidbcloud/uikit'
import { FormRadioGroup, FormSelect, FormSwitch, FormTextInput } from '@tidbcloud/uikit/biz'
import { IconInfoCircle } from '@tidbcloud/uikit/icons'
import { useMemo } from 'react'
import { Controller, useFormContext } from 'react-hook-form'

import { showTidbExtension } from 'dbaas/features/Changefeed'
import { canConfigureEventSplitting } from 'dbaas/features/Changefeed/helpers'
import { getChangefeedClusterMetadata } from 'dbaas/features/Changefeed/types'
import { CardSection } from 'dbaas/screens/Changefeed/CreateOrEditChangefeed/step2/CardSection'
import { FormEventSplit } from 'dbaas/screens/Changefeed/CreateOrEditChangefeed/step2/FormEventSplit'
import type { SharedTiDB } from 'dbaas/screens/NextGen/shared/model/shared-tidb-state'
import {
  ConsoleapiDescribeSchemaTableResp,
  DataflowBinaryEncodingMethod,
  DataflowS3Protocol
} from 'dbaas/services/dataflow/interface'

import { FormStartPosition } from './FormStartPosition'

export function FormS3OrGCS({
  schemaTableData,
  path,
  cluster
}: {
  cluster: SharedTiDB
  schemaTableData?: ConsoleapiDescribeSchemaTableResp
  path: 's3_info' | 'gcs_info'
}) {
  const { watch, control, setValue } = useFormContext()
  const protocol: DataflowS3Protocol = watch(`${path}.data_format.protocol`)
  const flushInterval = watch(`${path}.storage_flush_config.flush_interval`) as string
  const fileSize = watch(`${path}.storage_flush_config.file_size`) as string
  const { version } = useMemo(() => getChangefeedClusterMetadata(cluster), [cluster])

  return (
    <>
      <CardSection title="Start Replication Position">
        <FormStartPosition name={`${path}.start_position`} schemaTableData={schemaTableData} />
      </CardSection>

      <CardSection
        title="Data Format"
        tooltip={
          <Typography fz={14}>
            Data format parameters.{' '}
            <a
              href="https://docs.pingcap.com/tidb/stable/ticdc-open-api-v2#parameter-descriptions"
              target="_blank"
              rel="noreferrer"
            >
              See doc for instructions
            </a>
            .
          </Typography>
        }
      >
        <FormRadioGroup
          name={`${path}.data_format.protocol`}
          data={[
            {
              label: 'CSV',
              value: DataflowS3Protocol.S3_PROTOCOL_CSV
            },
            {
              label: 'Canal-JSON',
              value: DataflowS3Protocol.S3_PROTOCOL_CANAL_JSON
            }
          ]}
          label="Protocol"
        />

        {protocol === DataflowS3Protocol.S3_PROTOCOL_CSV && (
          <FormRadioGroup
            name={`${path}.data_format.binary_encoding_method`}
            data={[
              {
                label: 'Base64',
                value: DataflowBinaryEncodingMethod.BASE64
              },
              {
                label: 'Hex',
                value: DataflowBinaryEncodingMethod.HEX
              }
            ]}
            label="Binary Encoding Method"
          />
        )}

        <FormSelect
          label="Date Separator"
          name={`${path}.data_format.date_separator`}
          data={[
            {
              label: 'None',
              value: 'none'
            },
            {
              label: 'Day',
              value: 'day'
            },
            {
              label: 'Month',
              value: 'month'
            },
            {
              label: 'Year',
              value: 'year'
            }
          ]}
        />

        {protocol === DataflowS3Protocol.S3_PROTOCOL_CSV && (
          <>
            <FormTextInput name={`${path}.data_format.delimiter`} label="Delimiter" />
            <FormTextInput name={`${path}.data_format.quote`} label="Quote" />
            <FormTextInput name={`${path}.data_format.null`} label="Null" />
            <FormSwitch name={`${path}.data_format.include_commit_ts`} label="Include Commit Ts" />
          </>
        )}

        {showTidbExtension(protocol) && (
          <>
            <FormSwitch
              name={`${path}.data_format.enable_tidb_extension`}
              label={
                <Group gap={4}>
                  <Typography>Enable TiDB Extension</Typography>
                  <HoverCard>
                    <HoverCard.Target>
                      <IconInfoCircle size={14} />
                    </HoverCard.Target>
                    <HoverCard.Dropdown>
                      <Typography variant="body-lg">
                        TiDB extension field.{' '}
                        <a
                          href="https://docs.pingcap.com/tidb/stable/ticdc-canal-json#tidb-extension-field"
                          target="_blank"
                          rel="noreferrer"
                        >
                          See doc for instructions.
                        </a>
                      </Typography>
                    </HoverCard.Dropdown>
                  </HoverCard>
                </Group>
              }
            />
          </>
        )}

        <Group gap={8}>
          <Typography variant="headline-sm">Flush Parameters</Typography>
          <HoverCard shadow="md" withArrow>
            <HoverCard.Target>
              <IconInfoCircle size={14} />
            </HoverCard.Target>
            <HoverCard.Dropdown>
              <Typography fz={14}>
                refer to{' '}
                <a
                  href="https://docs.pingcap.com/tidb/stable/ticdc-sink-to-cloud-storage#configure-sink-uri"
                  target="_blank"
                  rel="noreferrer"
                >
                  here
                </a>{' '}
                to learn more about flush parameters
              </Typography>
            </HoverCard.Dropdown>
          </HoverCard>
        </Group>

        <Stack gap={0} maw={800}>
          <Typography variant="label-lg">Flush Interval: {flushInterval}</Typography>
          <Slider
            value={parseInt(flushInterval, 10)}
            label={(val) => `${val}s`}
            onChange={(val) => setValue(`${path}.storage_flush_config.flush_interval`, `${val}s`)}
            min={2}
            max={600}
            marks={[
              { value: 60, label: '1m' },
              { value: 180, label: '3m' },
              { value: 300, label: '5m' },
              { value: 600, label: '10m' }
            ]}
          />
          <Controller
            name={`${path}.storage_flush_config.flush_interval`}
            control={control}
            render={({ field }) => <input {...field} hidden />}
          />
        </Stack>
        <Stack gap={0} maw={800} mt={32} pb={16}>
          <Typography variant="label-lg">File Size: {parseInt(fileSize, 10) / 1024 / 1024}MB</Typography>
          <Slider
            value={parseInt(fileSize, 10) / 1024 / 1024}
            label={(val) => `${val}MB`}
            onChange={(val) => setValue(`${path}.storage_flush_config.file_size`, `${val * 1024 * 1024}`)}
            min={1}
            max={512}
            marks={[
              { value: 64, label: '64MB' },
              { value: 128, label: '128MB' },
              { value: 256, label: '256MB' },
              { value: 512, label: '512MB' }
            ]}
          />
          <Controller
            name={`${path}.storage_flush_config.file_size`}
            control={control}
            render={({ field }) => <input {...field} hidden />}
          />
        </Stack>
      </CardSection>

      {canConfigureEventSplitting(version) && (
        <CardSection title="Event Splitting">
          <FormEventSplit name={`${path}.data_format.output_raw_change_event`} />
        </CardSection>
      )}
    </>
  )
}
