import React, { useState, useEffect } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { useTranslation } from 'react-i18next'
import {
  Box,
  Heading,
  Button,
  Input,
  VStack,
  HStack,
  Text,
  Field,
  Badge,
  IconButton,
  Flex,
} from '@chakra-ui/react'
import {
  useGetChainQuery,
  useGetTasksQuery,
  useCreateChainMutation,
  useUpdateChainMutation,
} from '../../__data__/api/api'
import { URLs } from '../../__data__/urls'
import { LoadingSpinner } from '../../components/LoadingSpinner'
import { ErrorAlert } from '../../components/ErrorAlert'
import { toaster } from '../../components/ui/toaster'
import type { ChallengeTask } from '../../types/challenge'

export const ChainFormPage: React.FC = () => {
  const { id } = useParams<{ id: string }>()
  const navigate = useNavigate()
  const isEdit = !!id
  const { t } = useTranslation()

  const { data: chain, isLoading: isLoadingChain, error: loadError } = useGetChainQuery(id!, {
    skip: !id,
  })
  const { data: allTasks, isLoading: isLoadingTasks } = useGetTasksQuery()
  const [createChain, { isLoading: isCreating }] = useCreateChainMutation()
  const [updateChain, { isLoading: isUpdating }] = useUpdateChainMutation()

  const [name, setName] = useState('')
  const [selectedTasks, setSelectedTasks] = useState<ChallengeTask[]>([])
  const [searchQuery, setSearchQuery] = useState('')
  const [isActive, setIsActive] = useState(true)

  useEffect(() => {
    if (chain) {
      setName(chain.name)
      setSelectedTasks(chain.tasks)
      setIsActive(chain.isActive !== false)
    }
  }, [chain])

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()

    if (!name.trim()) {
      toaster.create({
        title: t('challenge.admin.common.validation.error'),
        description: t('challenge.admin.chains.validation.enter.name'),
        type: 'error',
      })
      return
    }

    if (selectedTasks.length === 0) {
      toaster.create({
        title: t('challenge.admin.common.validation.error'),
        description: t('challenge.admin.chains.validation.add.task'),
        type: 'error',
      })
      return
    }

    try {
      const taskIds = selectedTasks.map((task) => task.id)

      if (isEdit && id) {
        await updateChain({
          id,
          data: {
            name: name.trim(),
            taskIds: taskIds,
            isActive,
          },
        }).unwrap()
        toaster.create({
          title: t('challenge.admin.common.success'),
          description: t('challenge.admin.chains.updated'),
          type: 'success',
        })
      } else {
        await createChain({
          name: name.trim(),
          taskIds: taskIds,
          isActive,
        }).unwrap()
        toaster.create({
          title: t('challenge.admin.common.success'),
          description: t('challenge.admin.chains.created'),
          type: 'success',
        })
      }
      navigate(URLs.chains)
    } catch (err: unknown) {
      const errorMessage = 
        (err && typeof err === 'object' && 'data' in err && 
         err.data && typeof err.data === 'object' && 'error' in err.data &&
         err.data.error && typeof err.data.error === 'object' && 'message' in err.data.error &&
         typeof err.data.error.message === 'string')
          ? err.data.error.message
          : t('challenge.admin.chains.save.error')
      
      toaster.create({
        title: t('challenge.admin.common.error'),
        description: errorMessage,
        type: 'error',
      })
    }
  }

  const handleAddTask = (task: ChallengeTask) => {
    if (!selectedTasks.find((t) => t.id === task.id)) {
      setSelectedTasks([...selectedTasks, task])
    }
  }

  const handleRemoveTask = (taskId: string) => {
    setSelectedTasks(selectedTasks.filter((t) => t.id !== taskId))
  }

  const handleMoveUp = (index: number) => {
    if (index === 0) return
    const newTasks = [...selectedTasks]
    ;[newTasks[index - 1], newTasks[index]] = [newTasks[index], newTasks[index - 1]]
    setSelectedTasks(newTasks)
  }

  const handleMoveDown = (index: number) => {
    if (index === selectedTasks.length - 1) return
    const newTasks = [...selectedTasks]
    ;[newTasks[index], newTasks[index + 1]] = [newTasks[index + 1], newTasks[index]]
    setSelectedTasks(newTasks)
  }

  if (isEdit && isLoadingChain) {
    return <LoadingSpinner message={t('challenge.admin.chains.loading')} />
  }

  if (isEdit && loadError) {
    return <ErrorAlert message={t('challenge.admin.chains.load.error')} />
  }

  if (isLoadingTasks) {
    return <LoadingSpinner message={t('challenge.admin.common.loading.tasks')} />
  }

  if (!allTasks) {
    return <ErrorAlert message={t('challenge.admin.chains.tasks.load.error')} />
  }

  const isLoading = isCreating || isUpdating

  const availableTasks = allTasks.filter(
    (task) =>
      !selectedTasks.find((t) => t.id === task.id) &&
      task.title.toLowerCase().includes(searchQuery.toLowerCase())
  )

  return (
    <Box>
      <Heading mb={6}>{isEdit ? t('challenge.admin.chains.edit.title') : t('challenge.admin.chains.create.title')}</Heading>

      <Box
        as="form"
        onSubmit={handleSubmit}
        bg="white"
        p={6}
        borderRadius="lg"
        boxShadow="sm"
        borderWidth="1px"
        borderColor="gray.200"
      >
        <VStack gap={6} align="stretch">
          {/* Name */}
          <Field.Root required>
            <Field.Label>{t('challenge.admin.chains.field.name')}</Field.Label>
            <Input
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder={t('challenge.admin.chains.field.name.placeholder')}
              maxLength={255}
              disabled={isLoading}
            />
          </Field.Root>

          {/* Active flag */}
          <Field.Root>
            <HStack justify="space-between" align="flex-start">
              <HStack gap={2}>
                <input
                  type="checkbox"
                  checked={isActive}
                  onChange={(e) => setIsActive(e.target.checked)}
                  disabled={isLoading}
                  style={{ cursor: isLoading ? 'not-allowed' : 'pointer' }}
                />
                <Text>{t('challenge.admin.chains.field.isActive')}</Text>
              </HStack>
              <Text fontSize="sm" color="gray.500" maxW="md">
                {t('challenge.admin.chains.field.isActive.helper')}
              </Text>
            </HStack>
          </Field.Root>

          {/* Selected Tasks */}
          <Box>
            <Text fontWeight="bold" mb={3}>
              {t('challenge.admin.chains.selected.tasks')} ({selectedTasks.length})
            </Text>
            {selectedTasks.length === 0 ? (
              <Box
                p={6}
                borderWidth="2px"
                borderStyle="dashed"
                borderColor="gray.200"
                borderRadius="md"
                textAlign="center"
              >
                <Text color="gray.500">{t('challenge.admin.chains.selected.tasks.empty')}</Text>
              </Box>
            ) : (
              <VStack gap={2} align="stretch">
                {selectedTasks.map((task, index) => (
                  <Flex
                    key={task.id}
                    p={3}
                    bg="teal.50"
                    borderWidth="1px"
                    borderColor="teal.200"
                    borderRadius="md"
                    align="center"
                    justify="space-between"
                  >
                    <HStack gap={3} flex={1}>
                      <Badge colorPalette="teal" variant="solid">
                        #{index + 1}
                      </Badge>
                      <Text fontWeight="medium">{task.title}</Text>
                    </HStack>
                    <HStack gap={1}>
                      <IconButton
                        size="sm"
                        variant="ghost"
                        onClick={() => navigate(URLs.taskEdit(task.id))}
                        disabled={isLoading}
                        aria-label="Edit task"
                      >
                        ✎
                      </IconButton>
                      <IconButton
                        size="sm"
                        variant="ghost"
                        onClick={() => handleMoveUp(index)}
                        disabled={index === 0 || isLoading}
                        aria-label="Move up"
                      >
                        ↑
                      </IconButton>
                      <IconButton
                        size="sm"
                        variant="ghost"
                        onClick={() => handleMoveDown(index)}
                        disabled={index === selectedTasks.length - 1 || isLoading}
                        aria-label="Move down"
                      >
                        ↓
                      </IconButton>
                      <IconButton
                        size="sm"
                        variant="ghost"
                        colorPalette="red"
                        onClick={() => handleRemoveTask(task.id)}
                        disabled={isLoading}
                        aria-label="Remove"
                      >
                        ✕
                      </IconButton>
                    </HStack>
                  </Flex>
                ))}
              </VStack>
            )}
          </Box>

          {/* Available Tasks */}
          <Box>
            <Text fontWeight="bold" mb={3}>
              {t('challenge.admin.chains.available.tasks')}
            </Text>
            <Input
              placeholder={t('challenge.admin.chains.search.placeholder')}
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              mb={3}
            />
            {availableTasks.length === 0 ? (
              <Box
                p={6}
                borderWidth="1px"
                borderColor="gray.200"
                borderRadius="md"
                textAlign="center"
              >
                <Text color="gray.500">
                  {allTasks.length === selectedTasks.length
                    ? t('challenge.admin.chains.all.tasks.added')
                    : t('challenge.admin.common.not.found')}
                </Text>
              </Box>
            ) : (
              <VStack gap={2} align="stretch" maxH="400px" overflowY="auto">
                {availableTasks.map((task) => (
                  <Flex
                    key={task.id}
                    p={3}
                    bg="gray.50"
                    borderWidth="1px"
                    borderColor="gray.200"
                    borderRadius="md"
                    align="center"
                    justify="space-between"
                    cursor="pointer"
                    _hover={{ bg: 'gray.100' }}
                    onClick={() => handleAddTask(task)}
                  >
                    <Text>{task.title}</Text>
                    <Button size="sm" colorPalette="teal" variant="ghost">
                      {t('challenge.admin.chains.button.add')}
                    </Button>
                  </Flex>
                ))}
              </VStack>
            )}
          </Box>

          {/* Actions */}
          <HStack gap={3} justify="flex-end">
            <Button variant="outline" onClick={() => navigate(URLs.chains)} disabled={isLoading}>
              {t('challenge.admin.common.cancel')}
            </Button>
            <Button type="submit" colorPalette="teal" disabled={isLoading}>
              {isEdit ? t('challenge.admin.chains.button.save') : t('challenge.admin.chains.button.create')}
            </Button>
          </HStack>
        </VStack>
      </Box>
    </Box>
  )
}

