import {
  ActionIcon,
  Box,
  Button,
  Card,
  Flex,
  Group,
  SegmentedControl,
  Stack,
  TextInput,
  Typography
} from '@tidbcloud/uikit'
import { FormSelect, FormTextInput } from '@tidbcloud/uikit/biz'
import { IconCornerDownRight, IconPlus, IconTrash01 } from '@tidbcloud/uikit/icons'
import { useState } from 'react'
import { Controller, useFieldArray, useFormContext } from 'react-hook-form'

import { partitionDistributionOptions } from 'dbaas/features/Changefeed/constants'
import { DataflowPartitionDispatcher, DataflowPartitionDispatcherConfig } from 'dbaas/services/dataflow/interface'

export function FormPartitionDistribution({ name, target }: { name: string; target: 'Kafka' | 'Pulsar' }) {
  const { control, watch } = useFormContext()
  const partitionDispatcher = watch(name) as DataflowPartitionDispatcherConfig[]
  const [partitionDispatcherType, setPartitionDispatcherType] = useState<'single' | 'multiple'>(() => {
    if (partitionDispatcher.length === 1) {
      return 'single'
    }
    return 'multiple'
  })
  const { fields, append, remove } = useFieldArray({
    control,
    name
  })

  const FIXED_COLUMN_LEFT_WIDTH = 200

  return (
    <>
      <SegmentedControl
        data={[
          {
            label: 'A single partition dispatcher for all tables',
            value: 'single'
          },
          {
            label: 'Different partition dispatchers for different tables',
            value: 'multiple'
          }
        ]}
        value={partitionDispatcherType}
        onChange={(value) => setPartitionDispatcherType(value as 'single' | 'multiple')}
      />

      <Card>
        <Card.Section>
          <Group p={16} bg="carbon.3" wrap="nowrap">
            <Typography variant="body-lg" c="carbon.7" w={FIXED_COLUMN_LEFT_WIDTH}>
              Tables Matching
            </Typography>
            <Typography variant="body-lg" c="carbon.7">
              Distribute change events to {target} partitions using the following rule
            </Typography>
          </Group>
        </Card.Section>

        <Card.Section>
          <Stack p={16} gap={16}>
            {fields.map((field, index) => (
              <Box
                key={field.id}
                sx={(theme) => ({
                  '&:not(:last-child)': {
                    borderBottom: `1px solid ${theme.colors.carbon[3]}`,
                    paddingBottom: 16
                  }
                })}
              >
                <Group wrap="nowrap">
                  <Controller
                    name={`${name}.${index}.matcher`}
                    render={({ field }) => (
                      <TextInput
                        {...field}
                        value={field.value.join(',')}
                        onChange={(e) => field.onChange(e.target.value.split(','))}
                        size="sm"
                        placeholder="Enter tables matching"
                        w={FIXED_COLUMN_LEFT_WIDTH}
                      />
                    )}
                  />

                  <FormSelect
                    name={`${name}.${index}.partition_type`}
                    data={partitionDistributionOptions.map((i) => ({
                      value: i.value,
                      label: i.text
                    }))}
                    placeholder="Select partition dispatcher"
                    size="sm"
                    sx={{ flex: 1 }}
                  />

                  {partitionDispatcherType === 'multiple' && (
                    <ActionIcon
                      variant="default"
                      size={32}
                      onClick={() => remove(index)}
                      sx={partitionDispatcher.length <= 1 ? { visibility: 'hidden' } : undefined}
                    >
                      <IconTrash01 />
                    </ActionIcon>
                  )}
                </Group>

                {partitionDispatcher[index].partition_type === DataflowPartitionDispatcher.COLUMNS && (
                  <Flex gap={16} mt={8}>
                    <Flex align="center" justify="flex-end" gap={8} w={FIXED_COLUMN_LEFT_WIDTH}>
                      <Box component={IconCornerDownRight} size={24} c="carbon.5" mr={8} />
                      <Typography variant="label-md" c="carbon.7" span>
                        Column Values
                      </Typography>
                    </Flex>

                    <Controller
                      name={`${name}.${index}.columns`}
                      render={({ field }) => (
                        <TextInput
                          {...field}
                          placeholder="Enter column values, separated by commas"
                          size="sm"
                          sx={{ flex: 1 }}
                          value={field.value?.join(',') ?? ''}
                          onChange={(e) => field.onChange(e.target.value.split(','))}
                        />
                      )}
                    />

                    <ActionIcon sx={{ visibility: 'hidden' }} size={32}>
                      <IconTrash01 />
                    </ActionIcon>
                  </Flex>
                )}

                {partitionDispatcher[index].partition_type === DataflowPartitionDispatcher.INDEX_VALUE && (
                  <Flex gap={16} mt={8}>
                    <Flex align="center" justify="flex-end" gap={8} w={FIXED_COLUMN_LEFT_WIDTH}>
                      <Box component={IconCornerDownRight} size={24} c="carbon.5" mr={8} />
                      <Typography variant="label-md" c="carbon.7" span>
                        Index Name
                      </Typography>
                    </Flex>

                    <FormTextInput
                      name={`${name}.${index}.index_name`}
                      placeholder="Enter index name, this is optional"
                      size="sm"
                      sx={{ flex: 1 }}
                    />

                    <ActionIcon sx={{ visibility: 'hidden' }} size={32}>
                      <IconTrash01 />
                    </ActionIcon>
                  </Flex>
                )}
              </Box>
            ))}
          </Stack>
        </Card.Section>

        {partitionDispatcherType === 'multiple' && (
          <div>
            <Button
              variant="default"
              size="sm"
              leftSection={<IconPlus strokeWidth={3} />}
              onClick={() =>
                append({
                  matcher: ['*.*'],
                  partition_type: DataflowPartitionDispatcher.INDEX_VALUE
                })
              }
            >
              Add New
            </Button>
          </div>
        )}
      </Card>
    </>
  )
}
