import {
  Alert,
  Button,
  Card,
  Group,
  notifier,
  Select,
  Stack,
  TextInput
} from '@tidbcloud/uikit'
import { useCallback, useEffect, useMemo, useState } from 'react'

import {
  cloudConfigControllerCreateConfigurationTemplateChange,
  cloudConfigControllerListParameterVersions
} from 'apiClient/services/devops'
import {
  CloudconfigChangeFileReq,
  CloudconfigCreateConfigurationTemplateChangeReq,
  CloudConfigControllerListTemplatesClusterType,
  CloudconfigClusterType,
  CloudconfigParameterApplyPolicy,
  CloudconfigTemplateType
} from 'apiClient/services/devops/interface'

import ParameterManager, { ParameterValue } from './ParameterManager'

const CONFIG_TYPES = ['tidb', 'tikv', 'tiflash', 'INIT_SQL']

interface CreateCustomTemplateFormProps {
  onSuccess: () => void
  onCancel: () => void
}

const getErrorContent = (error: any) =>
  error?.response?.data?.errmsg ||
  error?.response?.data?.message ||
  error?.message ||
  String(error)

const buildChangeFiles = (
  parameters: Record<string, Record<string, ParameterValue>>
): CloudconfigChangeFileReq[] =>
  Object.entries(parameters).reduce<CloudconfigChangeFileReq[]>(
    (files, [configType, params]) => {
      const customParameters = Object.entries(params).map(([name, value]) => ({
        name,
        value: value.value
      }))

      if (customParameters.length === 0) {
        return files
      }

      files.push({
        config_type: configType,
        custom_parameters: customParameters,
        filename: configType
      })

      return files
    },
    []
  )

const CreateCustomTemplateForm = ({
  onSuccess,
  onCancel
}: CreateCustomTemplateFormProps) => {
  const [currentConfigType, setCurrentConfigType] = useState('tidb')
  const [versions, setVersions] = useState<string[]>([])
  const [templateName, setTemplateName] = useState('')
  const [selectedVersion, setSelectedVersion] = useState('')
  const [submitting, setSubmitting] = useState(false)
  const [parameters, setParameters] = useState<
    Record<string, Record<string, ParameterValue>>
  >({
    INIT_SQL: {},
    tidb: {},
    tiflash: {},
    tikv: {}
  })

  useEffect(() => {
    const fetchVersions = async () => {
      try {
        const resp = await cloudConfigControllerListParameterVersions({
          cluster_type: CloudconfigClusterType.DEDICATED_TIDB
        })
        setVersions(resp.data.versions || [])
      } catch (error) {
        notifier.error(getErrorContent(error), {
          title: 'Failed to fetch versions'
        })
      }
    }
    void fetchVersions()
  }, [])

  const handleParameterChange = useCallback(
    (type: string, name: string, value: ParameterValue) => {
      setParameters((prev) => ({
        ...prev,
        [type]: {
          ...prev[type],
          [name]: value
        }
      }))
    },
    []
  )

  const handleParameterRemove = useCallback((type: string, name: string) => {
    setParameters((prev) => {
      const newParams = { ...prev[type] }
      delete newParams[name]
      return { ...prev, [type]: newParams }
    })
  }, [])

  const versionOptions = useMemo(
    () => versions.map((version) => ({ label: version, value: version })),
    [versions]
  )

  const handleSubmit = useCallback(async () => {
    if (!templateName.trim()) {
      notifier.error('Template name is required')
      return
    }

    if (!selectedVersion) {
      notifier.error('Version is required')
      return
    }

    setSubmitting(true)
    try {
      const req: CloudconfigCreateConfigurationTemplateChangeReq = {
        apply_policy: CloudconfigParameterApplyPolicy.RollingRestart,
        change_type: 'fulltidb',
        cluster_type:
          CloudConfigControllerListTemplatesClusterType.DEDICATED_TIDB,
        files: buildChangeFiles(parameters),
        reason: templateName.trim(),
        template_type: CloudconfigTemplateType.custom,
        version: {
          to_version: selectedVersion
        }
      }

      const resp = await cloudConfigControllerCreateConfigurationTemplateChange(
        req
      )

      notifier.success('Template create request submitted successfully', {
        title: 'Create Template'
      })
      onSuccess()
      window.open(`/confighistories/${resp.data.change_id}`, '_blank')
    } catch (error) {
      notifier.error(getErrorContent(error), {
        title: 'Failed to create template'
      })
    } finally {
      setSubmitting(false)
    }
  }, [onSuccess, parameters, selectedVersion, templateName])

  return (
    <Stack gap="lg">
      <Card withBorder shadow="xs" padding="md" radius="sm">
        <Stack gap="md">
          <TextInput
            label="Template Name"
            placeholder="Enter template name"
            required
            value={templateName}
            onChange={(event) => setTemplateName(event.target.value)}
          />

          <Select
            data={versionOptions}
            label="Version"
            placeholder="Select version"
            required
            searchable
            value={selectedVersion || null}
            onChange={(value) => setSelectedVersion(value || '')}
          />
        </Stack>
      </Card>

      <Card withBorder shadow="xs" padding="md" radius="sm">
        <Stack gap="md">
          <Group gap={4}>
            {CONFIG_TYPES.map((type) => {
              const active = currentConfigType === type

              return (
                <Button
                  key={type}
                  variant="subtle"
                  size="sm"
                  onClick={() => setCurrentConfigType(type)}
                  style={{
                    borderBottom: active
                      ? '2px solid var(--mantine-color-peacock-6, #0b6fcb)'
                      : '2px solid transparent',
                    borderRadius: 0,
                    color: active
                      ? 'var(--mantine-color-carbon-9, #1f2d3d)'
                      : 'var(--mantine-color-carbon-6, #5f6b7a)',
                    fontWeight: active ? 600 : 400,
                    paddingLeft: 12,
                    paddingRight: 12
                  }}
                >
                  {type.toUpperCase()}
                </Button>
              )
            })}
          </Group>

          {selectedVersion ? (
            <ParameterManager
              clusterType={CloudconfigClusterType.DEDICATED_TIDB}
              configType={currentConfigType}
              version={selectedVersion}
              selectedParams={parameters[currentConfigType]}
              onParameterChange={(name, value) =>
                handleParameterChange(currentConfigType, name, value)
              }
              onParameterRemove={(name) =>
                handleParameterRemove(currentConfigType, name)
              }
            />
          ) : (
            <Alert color="blue" variant="light" title="Version required">
              Please select a version first.
            </Alert>
          )}
        </Stack>
      </Card>

      <Group justify="flex-end">
        <Button variant="default" onClick={onCancel} disabled={submitting}>
          Cancel
        </Button>
        <Button loading={submitting} onClick={handleSubmit}>
          Create
        </Button>
      </Group>
    </Stack>
  )
}

export default CreateCustomTemplateForm
