import {
  ActionIcon,
  Box,
  Button,
  Card,
  Collapse,
  Divider,
  Group,
  HoverCard,
  Input,
  Stack,
  Typography
} from '@tidbcloud/uikit'
import { FormCheckbox, FormSwitch, FormTextInput } from '@tidbcloud/uikit/biz'
import { IconBeaker02, IconChevronRight, IconInfoCircle, IconPlus, IconTrash01 } from '@tidbcloud/uikit/icons'
import { useState } from 'react'
import { useFieldArray, useFormContext } from 'react-hook-form'

import FormErrorMessage from 'dbaas/components/Form/FormErrorMessage'
import { useCreateImportIntoTask } from 'dbaas/services/dataflow'
import { Adminapiv1beta2ImportTargetTableInfo, V1beta2CSVFormat } from 'dbaas/services/dataflow/interface'
import { getErrorMessage } from 'dbaas/services/errorCodes'

import { LearnHowMappingWorks } from './shared'
import { ImportFromCloudFormData } from './types'

export type ConfigureMappingFormData = {
  csv_format: V1beta2CSVFormat
  use_tidb_dumpling_naming_conventions: boolean
  job_name: string
  ignore_compatibility_checks: boolean
  target_table_infos: Adminapiv1beta2ImportTargetTableInfo[]
}

export const ConfigureMapping = ({
  onCancel,
  onGoPrev,
  onFinish
}: {
  onCancel: () => void
  onGoPrev: () => void
  onFinish: (data: any) => void
}) => {
  const methods = useFormContext<ImportFromCloudFormData>()
  const sourceUri = methods.watch('source_uri')
  const followNamingConventions = methods.watch('use_tidb_dumpling_naming_conventions')

  const [showAdvancedOptions, setShowAdvancedOptions] = useState(false)
  const createImportIntoTask = useCreateImportIntoTask()
  const { fields, remove, append } = useFieldArray({
    control: methods.control,
    name: 'target_table_infos'
  })

  const onSubmit = async (data: ImportFromCloudFormData) => {
    onFinish(data)
  }

  return (
    <Card p={24}>
      <Stack component="form" onSubmit={methods.handleSubmit(onSubmit)}>
        <Typography variant="title-lg">Source Files Mapping</Typography>

        <Typography>
          Source Files URI: <b>{sourceUri}</b>
        </Typography>

        <FormCheckbox
          name="use_tidb_dumpling_naming_conventions"
          label={
            <Typography>
              Use{' '}
              <a
                href="https://docs.pingcap.com/tidbcloud/naming-conventions-for-data-import/?plan=premium"
                target="_blank"
                rel="noreferrer"
              >
                TiDB file naming conventions
              </a>{' '}
              for automatic mapping.
            </Typography>
          }
        />

        {followNamingConventions && <LearnHowMappingWorks />}

        {!followNamingConventions && (
          <Card>
            <Card.Section bg="carbon.2" p={16}>
              <Group gap={8} wrap="nowrap">
                <Typography c="carbon.7" sx={{ flex: 1 }}>
                  <Group gap={8} wrap="nowrap">
                    <span>Source</span>
                    <HoverCard>
                      <HoverCard.Target>
                        <IconInfoCircle />
                      </HoverCard.Target>
                      <HoverCard.Dropdown maw={400} fz="13px">
                        Specify the source file pattern as a relative path from your source URI.
                        <br />
                        <br />
                        Wildcards are supported:
                        <br />
                        <strong>?</strong> - matches one character
                        <br />
                        <strong>*</strong> - matches multiple characters
                        <br />
                        <br />
                        For example:
                        <br />• my-data.csv - matches my-data.csv
                        <br />• my-data?.csv - matches my-data1.csv, my-data2.csv, etc.
                        <br />• my-data*.csv - matches all CSV files starting with my-data
                      </HoverCard.Dropdown>
                    </HoverCard>
                  </Group>
                </Typography>
                <Typography c="carbon.7" sx={{ flexBasis: 150 }}>
                  Target Database
                </Typography>
                <Typography c="carbon.7" sx={{ flexBasis: 150 }}>
                  Target Table
                </Typography>
                <Box w={26} />
              </Group>
            </Card.Section>
            <Card.Section>
              <Divider />
            </Card.Section>
            <Card.Section p={16} component={Stack}>
              {fields.map((field, index) => {
                return (
                  <Group key={field.id} gap={8} wrap="nowrap" align="flex-start">
                    <FormTextInput
                      name={`target_table_infos.${index}.filesWildcard`}
                      size="xs"
                      sx={{ flex: 1 }}
                      placeholder="Enter source file pattern"
                      rules={{ required: true }}
                    />
                    <FormTextInput
                      name={`target_table_infos.${index}.database`}
                      size="xs"
                      placeholder="Enter database name"
                      sx={{ flexBasis: 150 }}
                      rules={{ required: true }}
                    />
                    <FormTextInput
                      name={`target_table_infos.${index}.table`}
                      size="xs"
                      placeholder="Enter table name"
                      sx={{ flexBasis: 150 }}
                      rules={{ required: true }}
                    />

                    {index === 0 ? (
                      <ActionIcon
                        variant="default"
                        onClick={() =>
                          append({
                            database: '',
                            table: '',
                            filesWildcard: ''
                          })
                        }
                      >
                        <IconPlus />
                      </ActionIcon>
                    ) : (
                      <ActionIcon variant="default" onClick={() => remove(index)}>
                        <IconTrash01 />
                      </ActionIcon>
                    )}
                  </Group>
                )
              })}
            </Card.Section>
          </Card>
        )}

        <Divider mx={-24} />

        <Typography variant="title-lg">Job Configuration</Typography>

        <FormTextInput name="job_name" label="Job Name" placeholder="Enter your job name" />

        <Card>
          <Card.Section>
            <Group
              px={16}
              py={12}
              justify="space-between"
              bg="carbon.2"
              sx={{ cursor: 'pointer' }}
              onClick={() => setShowAdvancedOptions(!showAdvancedOptions)}
            >
              <Group gap={8}>
                <IconBeaker02 />
                <Typography variant="label-md">Advanced Options</Typography>
              </Group>

              <IconChevronRight
                sx={{
                  transform: showAdvancedOptions ? 'rotate(90deg)' : 'rotate(0deg)',
                  transition: 'transform 0.3s ease-in-out'
                }}
              />
            </Group>
          </Card.Section>
          <Card.Section>
            <Collapse in={showAdvancedOptions}>
              <Stack px={16} py={12}>
                <Group justify="space-between">
                  <Input.Label>
                    <Group gap={8}>
                      <span>Ignore compatibility checks (advanced)</span>
                      <HoverCard>
                        <HoverCard.Target>
                          <IconInfoCircle cursor="pointer" size={14} color="carbon.8" />
                        </HoverCard.Target>
                        <HoverCard.Dropdown maw={480}>
                          <Typography variant="body-lg">
                            Bypasses pre-import safety checks ("precheck"). Only use when PITR or Changefeed are enabled
                            and you need to proceed despite conflicts. <br />
                            <b>Warning:</b> Ingested data will not be recorded in CDC or log backups. You must ensure no
                            operations access target tables during import. If PITR is enabled, either disable it during
                            import or perform a full table backup afterward.
                          </Typography>
                        </HoverCard.Dropdown>
                      </HoverCard>
                    </Group>
                  </Input.Label>
                  <FormSwitch name="ignore_compatibility_checks" />
                </Group>
              </Stack>
            </Collapse>
          </Card.Section>
        </Card>

        <Divider mx={-24} />

        <FormErrorMessage message={getErrorMessage(createImportIntoTask.error, true)} />

        <Group justify="flex-end">
          <Button variant="default" onClick={onCancel}>
            Cancel
          </Button>
          <Button variant="default" onClick={onGoPrev}>
            Previous
          </Button>

          <Button type="submit">Next</Button>
        </Group>
      </Stack>
    </Card>
  )
}
