import AsyncSelect from 'react-select/async'
import { useEffect, useRef, useState } from 'react'

import { SelectOption } from '@/src/interfaces/select'
import { InputActionMeta, SingleValue } from 'react-select'
import { debounce } from 'lodash'
import { useUserStore } from '@/src/store/userStore'
import { useFetchStudents, useFindByIdStudent } from '@/src/hooks/user/students'

interface Props {
  onChange: (option: SelectOption) => void
}

export default function AsyncSelectStudent({ onChange }: Props) {
  const { paymentSelected } = useUserStore()
  const [optionSelected, setOptionSelected] = useState<SelectOption | null>(
    null,
  )
  const [defaultOptions, setDefaultOptions] = useState<SelectOption[]>([])
  const [searchText, setSearchText] = useState('')
  const setSearchTextDebounced = useRef(
    debounce(searchText => setSearchText(searchText), 500),
  ).current
  const [inputText, setInputText] = useState('')

  const { data: studentSelected } = useFindByIdStudent(
    paymentSelected?.student.id || '',
  )
  const { data, isLoading, isFetching } = useFetchStudents({
    page: 1,
    sort: 'name:asc',
    pageSize: 5,
    search: searchText,
  })

  const handleChange = (option: SingleValue<SelectOption>) => {
    if (option) {
      setOptionSelected(option)
      onChange(option.value)
    }
  }

  const handleInputChange = (newValue: string, event: InputActionMeta) => {
    if (event.action !== 'input-blur' && event.action !== 'menu-close') {
      setSearchTextDebounced(newValue)
      setInputText(newValue)
      if (newValue) {
        setOptionSelected(null)
      }
    }
  }

  const handleLoadOptions = (
    inputValue: string,
    callback: (options: SelectOption[]) => void,
  ) => {
    setSearchTextDebounced(inputValue)
    /* refetch()
      .then(({ data }) => {
        callback(
          data?.studyYears.map(sy => ({
            value: sy.id,
            label: sy.year,
          })) ?? [],
        )
      })
      .catch(e => console.error(e)) */

    callback(
      data?.students.map(st => ({
        value: st,
        label: `${st.code} - ${st.name} ${st.lastname}`,
      })) ?? [],
    )
  }

  useEffect(() => {
    setDefaultOptions(
      data?.students.map(st => ({
        value: st,
        label: `${st.code} - ${st.name} ${st.lastname}`,
      })) ?? [],
    )
  }, [])

  useEffect(() => {
    if (studentSelected) {
      setOptionSelected(
        studentSelected
          ? {
            value: studentSelected,
            label: `${studentSelected.code} - ${studentSelected.name} ${studentSelected.lastname}`,
          }
          : null,
      )
    }
  }, [studentSelected])

  return (
    <AsyncSelect
      placeholder="Busque estudiantes"
      noOptionsMessage={() => 'No hay estudiantes'}
      value={optionSelected}
      onChange={handleChange}
      isClearable={true}
      inputValue={inputText}
      isLoading={isLoading || isFetching}
      loadingMessage={() => 'Cargando...'}
      cacheOptions
      defaultOptions={defaultOptions}
      loadOptions={handleLoadOptions}
      onInputChange={handleInputChange}
      styles={{
        container: styles => ({
          ...styles,
          borderRadius: '0.5rem',
        }),
        control: styles => ({
          ...styles,
          padding: '2.5px',
          borderRadius: '0.5rem',
          backgroundColor: 'rgb(249 250 251 / var(--tw-bg-opacity))',
        }),
        multiValue: styles => ({
          ...styles,
          backgroundColor: '#c8cce0',
        }),
      }}
    />
  )
}
