import type {FunctionComponent} from 'react'
import {useLayoutEffect, useState} from 'react'
import {useNavigation} from 'expo-router'
import {Input, InputField} from '@/components/ui/input'
import {Button, ButtonIcon} from '@/components/ui/button'
import {CheckIcon} from 'lucide-react-native'
import {VStack} from '@/components/ui/vstack'
import {Heading} from '@/components/ui/heading'
import {Checkbox, CheckboxIcon, CheckboxIndicator, CheckboxLabel} from '@/components/ui/checkbox'
import {LegendList} from '@legendapp/list'
import {useCreateTask, useGetTask, useUpdateTask} from '@/db/tasksAPI'
import {useGetLabels} from '@/db/labelsAPI'

interface TaskFormProps {
  id?: number
}

const TaskForm: FunctionComponent<TaskFormProps> = ({id}) => {
  const {mutate: createTask} = useCreateTask()
  const {mutate: updateTask} = useUpdateTask()
  const {data: activeTask} = useGetTask(id)
  const {data: labels} = useGetLabels()
  const [name, setName] = useState(activeTask?.name ?? '')
  const [selectedLabels, setSelectedLabels] = useState<Set<number>>(new Set(activeTask?.labels?.map(l => l.id) ?? []))
  const navigation = useNavigation()

  const toggleLabel = (id: number) => {
    setSelectedLabels(old => {
      const newSet = new Set(old)

      if (newSet.has(id)) {
        newSet.delete(id)
      } else {
        newSet.add(id)
      }

      return newSet
    })
  }

  // De linting regels heeft geen zin omdat de functie toch veranderd met elke aanpassing aan name.
  // Aangezien elke render een gevolg is van een aanpassing aan name, is een useCallback enkel overhead.
  // eslint-disable-next-line react-hooks/exhaustive-deps
  const handleCreateUpdate = () => {
    if (id) {
      updateTask({id, name, completed: activeTask!.completed, labels: labels.filter(l => selectedLabels.has(l.id))})
    } else {
      createTask({
        name,
        labels: labels.filter(l => selectedLabels.has(l.id)),
      })
    }
    navigation.goBack()
  }

  useLayoutEffect(() => {
    navigation.setOptions({
      headerRight: ({tintColor}: {tintColor: string}) => (
        <Button className="rounded-full p-3.5" variant="link" onPress={handleCreateUpdate}>
          <ButtonIcon as={CheckIcon} color={tintColor} size="xl" />
        </Button>
      ),
    })
  }, [navigation, handleCreateUpdate])

  return (
    <>
      <VStack className="m-4 gap-4 h-full">
        <Input variant="outline">
          <InputField placeholder="Task name" value={name} onChangeText={setName} />
        </Input>

        <Heading>Labels</Heading>

        <LegendList
          extraData={selectedLabels}
          renderItem={item => (
            <Checkbox
              value={item.item.id.toString()}
              size="lg"
              className="my-2"
              isChecked={selectedLabels.has(item.item.id)}
              onChange={() => toggleLabel(item.item.id)}>
              <CheckboxIndicator
                style={[
                  selectedLabels.has(item.item.id) && {backgroundColor: item.item.color, borderColor: item.item.color},
                ]}>
                <CheckboxIcon as={CheckIcon} />
              </CheckboxIndicator>
              <CheckboxLabel style={[{color: item.item.color}]} className="ms-4 text-2xl">
                {item.item.name}
              </CheckboxLabel>
            </Checkbox>
          )}
          data={labels}
          keyExtractor={l => l.id.toString()}
        />
      </VStack>
    </>
  )
}

export default TaskForm
