'use client'

import { createUrl } from '@/utilities/createUrl'
import { updateShopSearchParams } from '@/utilities/shopParams'
import clsx from 'clsx'
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import { useId, useState } from 'react'

type TaxonomyFilterMode = 'category' | 'multi' | 'segment'
type TaxonomyFilterPresentation = 'chips' | 'detailList' | 'list' | 'segmentGrid' | 'softChips'
type TaxonomyFilterDisplayStyle = 'auto' | TaxonomyFilterPresentation
type TaxonomyZeroCountBehavior = 'disabled' | 'hidden' | 'visible'

type TaxonomyFilterItem = {
  count?: number
  description?: null | string
  id: string
  segments?: string[]
  title: string
}

type Props = {
  displayStyle?: TaxonomyFilterDisplayStyle
  emptyLabel?: string
  items: TaxonomyFilterItem[]
  maxVisibleItems?: null | number
  mode: TaxonomyFilterMode
  queryKey: 'attribute' | 'category' | 'segment' | 'size' | 'usecase'
  showLessLabel?: null | string
  showMoreLabel?: null | string
  title: string
  zeroCountBehavior?: null | TaxonomyZeroCountBehavior
}

export function TaxonomyFilterSection({
  displayStyle = 'auto',
  emptyLabel = 'No options available.',
  items,
  maxVisibleItems,
  mode,
  queryKey,
  showLessLabel,
  showMoreLabel,
  title,
  zeroCountBehavior = 'visible',
}: Props) {
  const listID = useId()
  const pathname = usePathname()
  const router = useRouter()
  const searchParams = useSearchParams()
  const [isCollapsed, setIsCollapsed] = useState(true)

  const activeSegment = searchParams.get('segment')
  const sourceVisibleItems =
    queryKey === 'category' && activeSegment
      ? items.filter((item) => !item.segments?.length || item.segments.includes(activeSegment))
      : items
  const defaultPresentation: TaxonomyFilterPresentation =
    queryKey === 'category'
      ? 'list'
      : queryKey === 'size'
        ? 'detailList'
        : queryKey === 'segment'
          ? 'segmentGrid'
          : queryKey === 'usecase'
            ? 'softChips'
            : 'chips'
  const presentation: TaxonomyFilterPresentation =
    displayStyle === 'auto' ? defaultPresentation : displayStyle
  const resolvedMaxVisibleItems =
    typeof maxVisibleItems === 'number' && Number.isFinite(maxVisibleItems)
      ? Math.max(0, Math.floor(maxVisibleItems))
      : 0

  const isActive = (id: string): boolean => {
    if (mode === 'multi') {
      return searchParams.getAll(queryKey).includes(id)
    }

    return searchParams.get(queryKey) === id
  }

  const isZeroCountInactive = (item: TaxonomyFilterItem): boolean => {
    return typeof item.count === 'number' && item.count === 0 && !isActive(item.id)
  }

  const isDisabled = (item: TaxonomyFilterItem): boolean => {
    return zeroCountBehavior === 'disabled' && isZeroCountInactive(item)
  }

  const visibleItems =
    zeroCountBehavior === 'hidden'
      ? sourceVisibleItems.filter((item) => !isZeroCountInactive(item))
      : sourceVisibleItems

  const onSelect = (id: string): void => {
    const nextParams =
      mode === 'multi'
        ? updateShopSearchParams(searchParams, {
            key:
              queryKey === 'attribute' || queryKey === 'size' || queryKey === 'usecase'
                ? queryKey
                : 'attribute',
            type: 'multi',
            value: id,
          })
        : mode === 'segment'
          ? updateShopSearchParams(searchParams, {
              type: 'segment',
              value: id,
            })
          : updateShopSearchParams(searchParams, {
              key: 'category',
              type: 'single',
              value: id,
            })

    router.push(createUrl(pathname, nextParams))
  }

  const shouldLimitItems =
    resolvedMaxVisibleItems > 0 && visibleItems.length > resolvedMaxVisibleItems
  const renderedItems =
    shouldLimitItems && isCollapsed
      ? visibleItems.filter((item, index) => index < resolvedMaxVisibleItems || isActive(item.id))
      : visibleItems
  const hasHiddenItems = renderedItems.length < visibleItems.length

  return (
    <section className="border-t border-[#dbe8d7] pt-4 first:border-t-0 first:pt-0">
      <h3 className="mb-2.5 text-[11px] font-semibold uppercase tracking-[0.18em] text-[#607668]">
        {title}
      </h3>

      {visibleItems.length === 0 ? (
        <p className="rounded-2xl border border-dashed border-[#dbe8d7] bg-white px-3 py-2.5 text-sm text-[#607668]">
          {emptyLabel}
        </p>
      ) : (
        <ul
          className={clsx({
            'grid grid-cols-2 gap-2': presentation === 'segmentGrid',
            'flex flex-wrap gap-2': presentation === 'chips' || presentation === 'softChips',
            'space-y-1.5': presentation === 'list',
            'space-y-2': presentation === 'detailList',
          })}
          id={listID}
        >
          {renderedItems.map((item) => (
            <li
              className={
                presentation === 'chips' ||
                presentation === 'softChips' ||
                presentation === 'segmentGrid'
                  ? 'flex'
                  : undefined
              }
              key={item.id}
            >
              <button
                className={clsx(
                  'group transition duration-200 hover:cursor-pointer',
                  {
                    'flex min-h-10 w-full items-center justify-center gap-1.5 rounded-lg border px-3 py-2 text-center text-xs font-semibold':
                      presentation === 'segmentGrid',
                    'inline-flex min-h-8 items-center justify-center gap-1.5 rounded-full border px-3 py-1.5 text-xs font-semibold':
                      presentation === 'chips',
                    'inline-flex min-h-8 items-center justify-center gap-1.5 rounded-full px-3 py-1.5 text-xs font-semibold':
                      presentation === 'softChips',
                    'flex w-full items-center justify-between gap-3 rounded-lg px-1 py-1.5 text-left text-sm hover:translate-x-0.5':
                      presentation === 'list',
                    'flex w-full items-start justify-between gap-3 rounded-xl border px-3 py-2 text-left text-sm hover:border-[#8aac95] hover:bg-[#f2f7ee]':
                      presentation === 'detailList',
                  },
                  {
                    'border-[#dbe8d7] bg-white text-[#20392c] hover:border-[#8aac95] hover:bg-[#f2f7ee] hover:text-[#063f2b]':
                      (presentation === 'chips' ||
                        presentation === 'detailList' ||
                        presentation === 'segmentGrid') &&
                      !isActive(item.id),
                    'bg-[#edf5e8] text-[#405846] hover:bg-[#e3efdc] hover:text-[#063f2b]':
                      presentation === 'softChips' && !isActive(item.id),
                    'border-[#003b29] bg-[#003b29] text-white shadow-sm':
                      (presentation === 'chips' ||
                        presentation === 'detailList' ||
                        presentation === 'segmentGrid') &&
                      isActive(item.id),
                    'bg-[#003b29] text-white shadow-sm':
                      presentation === 'softChips' && isActive(item.id),
                    'text-[#607668] hover:text-[#063f2b]':
                      presentation === 'list' && !isActive(item.id),
                    'font-semibold text-[#063f2b]': presentation === 'list' && isActive(item.id),
                    'opacity-45 hover:cursor-not-allowed hover:translate-x-0 hover:border-[#dbe8d7] hover:bg-white hover:text-[#607668]':
                      isDisabled(item),
                  },
                )}
                disabled={isDisabled(item)}
                onClick={() => onSelect(item.id)}
                type="button"
              >
                <span
                  className={clsx({
                    'flex min-w-0 items-center gap-2': presentation === 'list',
                  })}
                >
                  {presentation === 'list' ? (
                    <span
                      aria-hidden="true"
                      className={clsx('h-1.5 w-1.5 shrink-0 rounded-full transition', {
                        'bg-[#003b29]': isActive(item.id),
                        'bg-[#b8c7b8] group-hover:bg-[#8aac95]': !isActive(item.id),
                      })}
                    />
                  ) : null}
                  <span
                    className={clsx('block leading-snug', {
                      'font-semibold': presentation !== 'list',
                      truncate: presentation === 'list',
                    })}
                  >
                    {item.title}
                  </span>
                  {item.description ? (
                    <span
                      className={clsx('mt-1 block text-xs leading-snug', {
                        'text-[#728172]': !isActive(item.id),
                        'text-[rgba(255,255,255,0.72)]': isActive(item.id),
                      })}
                    >
                      {item.description}
                    </span>
                  ) : null}
                </span>
                {typeof item.count === 'number' ? (
                  <span
                    className={clsx(
                      'rounded-full text-[11px] font-semibold tabular-nums transition',
                      {
                        'px-2 py-0.5': presentation !== 'list',
                        'px-0 py-0 text-[#8a978c]': presentation === 'list' && !isActive(item.id),
                        'px-0 py-0 text-[#063f2b]': presentation === 'list' && isActive(item.id),
                        'bg-[#edf5e8] text-[#607668] group-hover:bg-white':
                          presentation !== 'list' &&
                          presentation !== 'softChips' &&
                          !isActive(item.id),
                        'bg-white/70 text-[#607668]':
                          presentation === 'softChips' && !isActive(item.id),
                        'bg-[rgba(255,255,255,0.16)] text-white':
                          presentation !== 'list' && isActive(item.id),
                      },
                    )}
                  >
                    {item.count}
                  </span>
                ) : null}
              </button>
            </li>
          ))}
        </ul>
      )}
      {shouldLimitItems && (hasHiddenItems || !isCollapsed) ? (
        <button
          aria-controls={listID}
          aria-expanded={!isCollapsed}
          className="mt-3 text-xs font-semibold text-[#063f2b] underline underline-offset-4 transition hover:text-[#125238]"
          onClick={() => setIsCollapsed((current) => !current)}
          type="button"
        >
          {isCollapsed ? showMoreLabel || 'Show more' : showLessLabel || 'Show less'}
        </button>
      ) : null}
    </section>
  )
}
