'use client'

import React, { useState } from 'react'
import Select from 'react-select'
import Tooltip from './Tooltip'
import { useClientFetch } from '@/app/hooks/useClientFetch'

export interface Option {
  id: number
  value: string
  label: string
}

export interface DataItem {
  id: number
  [key: string]: unknown
}

export interface PaginatedResponse<T> {
  results: T[]
  count: number
  next: string | null
  previous: string | null
}

export interface SelectorProps<T extends DataItem> {
  name: string
  value?: Option | null
  handleChange: (e: {
    target: {
      id: string
      value: Option | null
      selectedOption?: Option
    }
  }) => void
  label?: string
  tooltip?: string | React.ReactNode
  placeholder?: string
  endpoint?: string
  mapDataToOptions: (data: T) => Option
  searchParam?: string
  staticOptions?: T[]
  config?: {
    params?: Record<string, string | number | boolean | undefined>
    queryOptions?: {
      enabled?: boolean
    }
  }
}

const Selector = <T extends DataItem>({
  name,
  value,
  handleChange,
  label,
  tooltip,
  placeholder,
  endpoint,
  mapDataToOptions,
  searchParam = 'search',
  staticOptions,
  config = {},
}: SelectorProps<T>) => {
  const [search, setSearch] = useState('')

  const { data, isLoading, error } = useClientFetch<PaginatedResponse<T>>(
    endpoint || '/404-no-endpoint',
    {
      config: {
        params: {
          ...(search ? { [searchParam]: search } : {}),
          ...(config.params || {}),
        },
      },
      queryOptions: {
        staleTime: 60 * 60 * 1000, // кешируем на час
        refetchOnWindowFocus: false,
        enabled: !staticOptions && endpoint !== undefined && config.queryOptions?.enabled !== false, // отключаем запрос если используем статические опции, нет endpoint или явно выключен в конфиге
      },
    }
  )

  let options: Option[] = []

  if (staticOptions) {
    // если есть статические опции используем их
    options = staticOptions.map(mapDataToOptions)
  } else {
    // иначе используем данные с бекенда
    const dataArray = Array.isArray(data) ? data : data?.results || []
    options = dataArray.map(mapDataToOptions)
  }

  if (error) {
    console.error(`Error fetching data from ${endpoint}:`, error)
  }

  return (
    <div>
      {label && (
        <div className="my-2 flex items-center gap-2">
          <label className="text-sm font-medium text-gray-500" htmlFor={name}>
            {label}
          </label>
          {tooltip && <Tooltip content={tooltip} />}
        </div>
      )}
      <Select<Option>
        inputId={name}
        name={name}
        options={options}
        value={options.find(opt => opt.id === value?.id)}
        onChange={selectedOption => {
          handleChange({
            target: {
              id: name,
              value: selectedOption
                ? {
                    ...selectedOption,
                  }
                : null,
              selectedOption: selectedOption || undefined,
            },
          })
        }}
        isLoading={isLoading}
        onInputChange={newValue => setSearch(newValue)}
        isSearchable
        isClearable
        placeholder={placeholder}
        noOptionsMessage={() => (isLoading ? 'Загрузка...' : 'Нет доступных вариантов')}
        classNamePrefix="select"
        className="rounded-lg"
        styles={{
          control: base => ({
            ...base,
            borderRadius: '0.75rem',
            backgroundColor: '#1B1E28',
            border: '1px solid #E5E7EB',
            padding: '2px',
            color: 'white',
            '&:hover': {
              borderColor: '#E5E7EB',
            },
            '&:focus-within': {
              backgroundColor: '#1B1E28',
              borderColor: '#E5E7EB',
              boxShadow: '0 0 0 2px rgba(59, 130, 246, 0.5)',
            },
          }),
          singleValue: base => ({
            ...base,
            color: 'white',
          }),
          input: base => ({
            ...base,
            color: 'white',
          }),
          menu: base => ({
            ...base,
            position: 'absolute',
            width: '100%',
            zIndex: 9999,
            marginTop: '4px',
            borderRadius: '0.75rem',
            overflow: 'hidden',
            backgroundColor: '#1B1E28',
            border: '1px solid #E5E7EB',
          }),
          option: (base, state) => ({
            ...base,
            fontSize: '0.875rem',
            padding: '8px 12px',
            backgroundColor: state.isSelected ? '#2563EB' : state.isFocused ? '#2D3139' : '#1B1E28',
            color: 'white',
            cursor: 'pointer',
            '&:active': {
              backgroundColor: '#2D3139',
            },
            '&:hover': {
              backgroundColor: state.isSelected ? '#2563EB' : '#2D3139',
            },
          }),
        }}
      />
    </div>
  )
}

export default Selector
