import { memo, useCallback, useMemo } from 'react'
import * as Accordion from '@radix-ui/react-accordion'
import { useSearchParams } from 'react-router-dom'
import { ChevronDown } from 'lucide-react'

import type { DeviceNetworkStatus } from '../../../../entities/device/model/types'
import { DevicesOrganisationFilter } from '../DevicesOrganisationFilter/DevicesOrganisationFilter'

import './Datepicker.scss'
import './DevicesFiltersPanel.scss'

const networkStatusOptions: {
  value: DeviceNetworkStatus
  label: string
}[] = [
  {
    value: 'Online',
    label: 'В сети',
  },
  {
    value: 'Offline',
    label: 'Не в сети',
  },
  {
    value: 'Lost',
    label: 'Потерян',
  },
]

const maintenanceOptions = [
  {
    value: false,
    label: 'Исправно',
  },
  {
    value: true,
    label: 'Требует ТО',
  },
]

function isDeviceNetworkStatus(value: string): value is DeviceNetworkStatus {
  return networkStatusOptions.some((option) => option.value === value)
}

type DevicesFiltersPanelProps = {
  isOpen: boolean
}

export const DevicesFiltersPanel = memo(function DevicesFiltersPanel({
  isOpen,
}: DevicesFiltersPanelProps) {
  const [searchParams, setSearchParams] = useSearchParams()

  const selectedOrganisationIds = useMemo(
    () => searchParams.get('dOrgs')?.split(',').filter(Boolean) ?? [],
    [searchParams],
  )

  const networkStatusParam = searchParams.get('dNetwork')
  const selectedNetworkStatuses = useMemo<DeviceNetworkStatus[]>(
    () =>
      networkStatusParam === 'none'
        ? []
        : networkStatusParam
          ?.split(',')
          .filter(isDeviceNetworkStatus) ??
        networkStatusOptions.map((option) => option.value),
    [networkStatusParam],
  )

  const needMaintenanceParam = searchParams.get('dNeedMaintenance')
  const selectedMaintenanceStates = useMemo(
    () =>
      needMaintenanceParam === 'true'
        ? [true]
        : needMaintenanceParam === 'false'
          ? [false]
          : maintenanceOptions.map((option) => option.value),
    [needMaintenanceParam],
  )

  const updateSearchParams = useCallback((updates: Record<string, string | null>) => {
    const params = new URLSearchParams(searchParams)

    Object.entries(updates).forEach(([key, value]) => {
      if (value === null || value === '') {
        params.delete(key)
        return
      }

      params.set(key, value)
    })

    setSearchParams(params)
  }, [searchParams, setSearchParams])

  const handleNetworkStatusChange = useCallback((
    status: DeviceNetworkStatus,
    checked: boolean,
  ) => {
    const currentStatuses = new Set(selectedNetworkStatuses)

    if (checked) {
      currentStatuses.add(status)
    } else {
      currentStatuses.delete(status)
    }

    const nextStatuses = networkStatusOptions
      .map((option) => option.value)
      .filter((optionStatus) => currentStatuses.has(optionStatus))

    updateSearchParams({
      dNetwork:
        nextStatuses.length === networkStatusOptions.length
          ? null
          : nextStatuses.length === 0
            ? 'none'
            : nextStatuses.join(','),
      dPage: '0',
    })
  }, [selectedNetworkStatuses, updateSearchParams])

  const handleMaintenanceChange = useCallback((value: boolean, checked: boolean) => {
    const currentStates = new Set(selectedMaintenanceStates)

    if (checked) {
      currentStates.add(value)
    } else {
      currentStates.delete(value)
    }

    if (currentStates.size === 0) return

    const nextStates = maintenanceOptions
      .map((option) => option.value)
      .filter((optionValue) => currentStates.has(optionValue))

    updateSearchParams({
      dNeedMaintenance:
        nextStates.length === maintenanceOptions.length
          ? null
          : String(nextStates[0]),
      dPage: '0',
    })
  }, [selectedMaintenanceStates, updateSearchParams])

  const handleOrganisationsChange = useCallback((ids: string[]) => {
    updateSearchParams({
      dOrgs: ids.length > 0 ? ids.join(',') : null,
      dPage: '0',
    })
  }, [updateSearchParams])

  return (
    <aside
      className={`devices-filters ${isOpen ? 'devices-filters--open' : ''}`}
      aria-hidden={!isOpen}
    >
      <Accordion.Root
        className="devices-filters__accordion"
        type="multiple"
        defaultValue={['work-period']}
      >
        {/* <Accordion.Item className="devices-filter-item" value="work-period">
          <Accordion.Header className="devices-filter-item__header">
            <Accordion.Trigger className="devices-filter-item__trigger">
              <span>Период работы</span>
              <ChevronDown
                className="devices-filter-item__chevron"
                size={16}
              />
            </Accordion.Trigger>
          </Accordion.Header>

          <Accordion.Content className="devices-filter-item__content">
            <div className="devices-filter-item__inner">
              <div className="devices-period">
                <DevicesDateRangePicker
                  value={workPeriod}
                  onChange={setWorkPeriod}
                />
              </div>
            </div>
          </Accordion.Content>
        </Accordion.Item> */}

        <Accordion.Item
          className="devices-filter-item"
          value="organisations"
        >
          <Accordion.Header className="devices-filter-item__header">
            <Accordion.Trigger className="devices-filter-item__trigger">
              <span>Организации</span>
              <ChevronDown
                className="devices-filter-item__chevron"
                size={16}
              />
            </Accordion.Trigger>
          </Accordion.Header>

          <Accordion.Content className="devices-filter-item__content">
            <div className="devices-filter-item__inner">
              <DevicesOrganisationFilter
                selectedOrganisationIds={selectedOrganisationIds}
                onChange={handleOrganisationsChange}
              />
            </div>
          </Accordion.Content>
        </Accordion.Item>

        <Accordion.Item className="devices-filter-item" value="network">
          <Accordion.Header className="devices-filter-item__header">
            <Accordion.Trigger className="devices-filter-item__trigger">
              <span>Сеть</span>
              <ChevronDown
                className="devices-filter-item__chevron"
                size={16}
              />
            </Accordion.Trigger>
          </Accordion.Header>

          <Accordion.Content className="devices-filter-item__content">
            <div className="devices-filter-item__inner">
              <div className="devices-checkbox-list">
                {networkStatusOptions.map((option) => (
                  <label className="devices-checkbox" key={option.value}>
                    <input
                      type="checkbox"
                      checked={selectedNetworkStatuses.includes(option.value)}
                      onChange={(event) => {
                        handleNetworkStatusChange(
                          option.value,
                          event.target.checked,
                        )
                      }}
                    />
                    <span className="devices-checkbox__control" />
                    <span>{option.label}</span>
                  </label>
                ))}
              </div>
            </div>
          </Accordion.Content>
        </Accordion.Item>

        <Accordion.Item className="devices-filter-item" value="condition">
          <Accordion.Header className="devices-filter-item__header">
            <Accordion.Trigger className="devices-filter-item__trigger">
              <span>Состояние</span>
              <ChevronDown
                className="devices-filter-item__chevron"
                size={16}
              />
            </Accordion.Trigger>
          </Accordion.Header>

          <Accordion.Content className="devices-filter-item__content">
            <div className="devices-filter-item__inner">
              <div className="devices-checkbox-list">
                {maintenanceOptions.map((option) => (
                  <label className="devices-checkbox" key={String(option.value)}>
                    <input
                      type="checkbox"
                      checked={selectedMaintenanceStates.includes(option.value)}
                      onChange={(event) => {
                        handleMaintenanceChange(
                          option.value,
                          event.target.checked,
                        )
                      }}
                    />
                    <span className="devices-checkbox__control" />
                    <span>{option.label}</span>
                  </label>
                ))}
              </div>
            </div>
          </Accordion.Content>
        </Accordion.Item>
      </Accordion.Root>
    </aside>
  )
})
