---
import { Icon } from 'astro-icon/components'

import { cn } from '../lib/cn'
import { makeOverallScoreInfo } from '../lib/overallScore'
import { type ServicesFiltersObject } from '../pages/index.astro'

import Button from './Button.astro'
import PillsRadioGroup from './PillsRadioGroup.astro'
import Tooltip from './Tooltip.astro'

import type { ServicesFiltersOptions } from '../lib/searchFiltersOptions'
import type { HTMLAttributes } from 'astro/types'

export type Props = HTMLAttributes<'form'> & {
  filters: ServicesFiltersObject
  hasDefaultFilters: boolean
  options: ServicesFiltersOptions
  searchResultsId: string
  showFiltersId: string
}

const {
  filters,
  hasDefaultFilters,
  options,
  searchResultsId,
  showFiltersId,
  class: className,
  ...formProps
} = Astro.props
---

<form
  method="GET"
  hx-get={Astro.url.pathname}
  hx-trigger={// NOTE: I need to do the [data-trigger-on-change] hack, because HTMX doesnt suport the :not() selector, and I need to exclude the Show more buttons, and not trigger for inputs outside the form
  "input delay:500ms from:([data-services-filters-form] input[type='text']), keyup[key=='Enter'], change from:([data-services-filters-form] [data-trigger-on-change])"}
  hx-target={`#${searchResultsId}`}
  hx-select={`#${searchResultsId}`}
  hx-push-url="true"
  hx-indicator="#search-indicator"
  hx-swap="outerHTML"
  data-services-filters-form
  data-default-verification-filter={options.verification
    .filter((verification) => verification.default)
    .map((verification) => verification.slug)}
  {...formProps}
  class={cn(
    // Check the scam filter when there is a text quey and the user has checked verified and approved
    'has-[input[name=q]:not(:placeholder-shown)]:has-[&_input[name=verification][value=verified]:checked]:has-[&_input[name=verification][value=approved]:checked]:[&_input[name=verification][value=scam]]:checkbox-force-checked',
    'has-[input[name=q]:placeholder-shown]:[&_[data-hide-if-q-is-empty]]:hidden has-[input[name=q]:not(:placeholder-shown)]:[&_[data-hide-if-q-is-filled]]:hidden',
    className
  )}
>
  <div class="mb-4 flex items-center justify-between">
    <h2 class="font-title text-xl text-green-500">FILTERS</h2>
    <a
      href={Astro.url.pathname}
      class={cn('text-sm text-green-500 hover:text-green-400', hasDefaultFilters && 'hidden')}
      id="clear-filters-button">Clear all</a
    >
  </div>

  <!-- Sort Selector -->
  <fieldset class="mb-6">
    <legend class="font-title mb-3 leading-none text-green-500">
      <label for="sort">Sort By</label>
    </legend>
    <select
      name="sort"
      id="sort"
      class="border-night-600 bg-night-900 w-full rounded-md border p-2 text-white focus:border-green-500 focus:outline-hidden"
      data-trigger-on-change
    >
      {
        options.sort.map((option) => (
          <option value={option.value} selected={filters.sort === option.value}>
            {option.label}
          </option>
        ))
      }
    </select>
    <p class="text-day-500 mt-1.5 text-center text-sm" data-hide-if-q-is-filled>
      <Icon name="ri:shuffle-line" class="inline-block size-3.5 align-[-0.125em]" />
      Ties randomly sorted
    </p>
    <p class="text-day-500 mt-1.5 text-center text-sm" data-hide-if-q-is-empty>
      <Icon name="ri:seo-line" class="inline-block size-3.5 align-[-0.125em]" />
      Sorted by match first
    </p>
  </fieldset>

  <!-- Text Search -->
  <fieldset class="mb-6">
    <legend class="font-title mb-3 leading-none text-green-500">
      <label for="q">Name</label>
    </legend>
    <input
      type="text"
      name="q"
      id="q"
      value={filters?.q}
      placeholder="Search..."
      class="placeholder-day-500 border-night-600 bg-night-900 w-full rounded-md border p-2 text-white focus:border-green-500 focus:outline-hidden"
    />
  </fieldset>

  <!-- Type Filter -->
  <fieldset class="mb-6">
    <legend class="font-title mb-3 leading-none text-green-500">Type</legend>
    <ul class="[&:not(:has(~_.peer:checked))]:[&>li:not([data-show-always])]:hidden">
      {
        options.categories.map((category) => (
          <li data-show-always={category.showAlways ? '' : undefined}>
            <label class="flex cursor-pointer items-center gap-2 text-sm text-white">
              <input
                type="checkbox"
                class="peer text-green-500"
                name="categories"
                value={category.slug}
                checked={category.checked}
                data-trigger-on-change
              />
              <Icon name={category.icon} class="size-4" />
              <span class="peer-checked:font-bold">
                {category.name}
                <span class="text-day-500 font-normal">{category._count.services}</span>
              </span>
            </label>
          </li>
        ))
      }
    </ul>
    {
      options.categories.filter((category) => category.showAlways).length < options.categories.length && (
        <>
          <input type="checkbox" id="show-more-categories" class="peer sr-only" hx-preserve />
          <label
            for="show-more-categories"
            class="peer-focus-visible:ring-offset-night-700 mt-2 block cursor-pointer rounded-sm text-sm text-green-500 peer-checked:hidden peer-focus-visible:ring-2 peer-focus-visible:ring-blue-500 peer-focus-visible:ring-offset-2"
          >
            + Show more
          </label>
          <label
            for="show-more-categories"
            class="peer-focus-visible:ring-offset-night-700 mt-2 hidden cursor-pointer rounded-sm text-sm text-green-500 peer-checked:block peer-focus-visible:ring-2 peer-focus-visible:ring-blue-500 peer-focus-visible:ring-offset-2"
          >
            - Show less
          </label>
        </>
      )
    }
  </fieldset>

  <!-- Verification Filter -->
  <fieldset class="mb-6">
    <legend class="font-title mb-3 leading-none text-green-500">Verification</legend>
    <div>
      {
        options.verification.map((verification) => (
          <label class="flex cursor-pointer items-center gap-2 text-sm text-white">
            <input
              type="checkbox"
              class="peer text-green-500"
              name="verification"
              value={verification.slug}
              checked={filters.verification.includes(verification.value)}
              data-trigger-on-change
            />
            <Icon name={verification.icon} class={cn('size-4', verification.classNames.icon)} />
            <span class="peer-checked:font-bold">{verification.labelShort}</span>
          </label>
        ))
      }
    </div>
  </fieldset>

  <!-- Accepted currencies Filter -->
  <fieldset class="mb-6">
    <div class="mb-3 flex items-center justify-between">
      <legend class="font-title leading-none text-green-500">Currencies</legend>
      <PillsRadioGroup
        name="currency-mode"
        options={options.modeOptions}
        selectedValue={filters['currency-mode']}
        class="-my-2"
        inputProps={{
          'data-trigger-on-change': true,
        }}
      />
    </div>
    <div>
      {
        options.currencies.map((currency) => (
          <label class="flex cursor-pointer items-center gap-2 text-sm text-white">
            <input
              type="checkbox"
              class="peer text-green-500"
              name="currencies"
              value={currency.slug}
              checked={filters.currencies?.some((id) => id === currency.id)}
              data-trigger-on-change
            />
            <Icon name={currency.icon} class="size-4" />
            <span class="peer-checked:font-bold">{currency.name}</span>
          </label>
        ))
      }
    </div>
  </fieldset>

  <!-- Network Filter -->
  <fieldset class="mb-6">
    <legend class="font-title mb-3 leading-none text-green-500">Networks</legend>
    <div>
      {
        options.network.map((network) => (
          <label class="flex cursor-pointer items-center gap-2 text-sm text-white">
            <input
              type="checkbox"
              class="peer text-green-500"
              name="networks"
              value={network.slug}
              checked={filters.networks?.some((slug) => slug === network.slug)}
              data-trigger-on-change
            />
            <Icon name={network.icon} class="size-4" />
            <span class="peer-checked:font-bold">{network.name}</span>
          </label>
        ))
      }
    </div>
  </fieldset>

  <!-- KYC Level Filter -->
  <fieldset class="mb-6">
    <legend class="font-title mb-3 leading-none text-green-500">
      <label for="max-kyc">KYC Level (max)</label>
    </legend>
    <div class="flex items-center gap-2">
      <input
        type="range"
        min="0"
        max="4"
        name="max-kyc"
        id="max-kyc"
        value={filters['max-kyc'] ?? 4}
        class="w-full accent-green-500"
        data-trigger-on-change
      />
    </div>
    <div class="text-day-400 mt-1 flex justify-between px-1 text-xs">
      {
        options.kycLevels.map((level) => (
          <span class="flex w-0 items-center justify-center text-center whitespace-nowrap">
            {level.value}
            <Icon name={level.icon} class="ms-1 size-3 shrink-0" />
          </span>
        ))
      }
    </div>
  </fieldset>

  <!-- User Score Filter -->
  <fieldset class="mb-6">
    <legend class="font-title mb-3 leading-none text-green-500">
      <label for="user-rating">User Rating (min)</label>
    </legend>
    <div class="flex items-center gap-2">
      <input
        type="range"
        min={0}
        max={4}
        name="user-rating"
        id="user-rating"
        value={filters['user-rating']}
        class="w-full accent-green-500"
        data-trigger-on-change
      />
    </div>
    <div class="text-day-400 mt-1 flex justify-between px-2 text-xs">
      <span class="flex w-0 items-center justify-center text-center whitespace-nowrap">-</span>
      <span class="flex w-0 items-center justify-center text-center whitespace-nowrap">
        1<Icon name="ri:star-line" class="size-3 shrink-0" />
      </span>
      <span class="flex w-0 items-center justify-center text-center whitespace-nowrap">
        2<Icon name="ri:star-line" class="size-3 shrink-0" />
      </span>
      <span class="flex w-0 items-center justify-center text-center whitespace-nowrap">
        3<Icon name="ri:star-line" class="size-3 shrink-0" />
      </span>
      <span class="flex w-0 items-center justify-center text-center whitespace-nowrap">
        4<Icon name="ri:star-line" class="size-3 shrink-0" />
      </span>
    </div>
  </fieldset>

  <!-- Attributes Filter -->
  <fieldset class="mb-6 min-w-0 space-y-2">
    <div class="mb-3 flex items-center justify-between">
      <legend class="font-title leading-none text-green-500">Attributes</legend>
      <PillsRadioGroup
        name="attribute-mode"
        options={options.modeOptions}
        selectedValue={filters['attribute-mode']}
        class="-my-2"
        inputProps={{
          'data-trigger-on-change': true,
        }}
      />
    </div>
    {
      options.attributesByCategory.map(({ categoryInfo, attributes }) => (
        <fieldset class="min-w-0">
          <legend class="font-title mb-0.5 inline-flex items-center gap-1 text-[0.8125rem] tracking-wide text-white uppercase">
            <Icon
              name={categoryInfo.icon}
              class={cn('size-4 shrink-0 opacity-80', categoryInfo.classNames.icon)}
              aria-hidden="true"
            />
            {categoryInfo.label}
          </legend>

          <ul class="[:not(:has(~_.peer:checked))]:[&>li:not([data-show-always])]:hidden">
            {attributes.map((attribute) => {
              const inputName = `attr-${attribute.id}` as const
              const yesId = `attr-${attribute.id}=yes` as const
              const noId = `attr-${attribute.id}=no` as const
              const emptyId = `attr-${attribute.id}=empty` as const
              const isPositive = attribute.type === 'GOOD' || attribute.type === 'INFO'

              return (
                <li data-show-always={attribute.showAlways ? '' : undefined} class="cursor-pointer">
                  <fieldset class="relative flex max-w-full min-w-0 cursor-pointer items-center text-sm text-white">
                    <legend class="sr-only">
                      {attribute.title} ({attribute._count.services})
                    </legend>
                    <input
                      type="radio"
                      class="peer/empty sr-only"
                      id={emptyId}
                      name={inputName}
                      value=""
                      checked={!attribute.value}
                      aria-label="Ignore"
                      data-trigger-on-change
                    />
                    <input
                      type="radio"
                      name={inputName}
                      value="yes"
                      id={yesId}
                      class="peer/yes sr-only"
                      checked={attribute.value === 'yes'}
                      aria-label="Include"
                      data-trigger-on-change
                    />
                    <input
                      type="radio"
                      name={inputName}
                      value="no"
                      id={noId}
                      class="peer/no sr-only"
                      checked={attribute.value === 'no'}
                      aria-label="Exclude"
                      data-trigger-on-change
                    />

                    <div class="pointer-events-none absolute inset-y-0 -left-[2px] hidden w-[calc(var(--spacing)*4.5*2+1px)] rounded-md border-2 border-blue-500 peer-focus-visible/empty:block peer-focus-visible/no:block peer-focus-visible/yes:block" />

                    <label
                      for={yesId}
                      class="border-night-500 bg-night-600 relative flex size-4 shrink-0 cursor-pointer items-center justify-center rounded-l-sm border border-r-0 peer-checked/yes:hidden before:absolute before:-inset-[3px] before:-right-[0.5px]"
                      aria-hidden="true"
                    >
                      <Icon name="ri:check-line" class="size-3" />
                    </label>
                    <label
                      for={emptyId}
                      class="relative hidden h-4 w-[calc(var(--spacing)*4+0.5px)] shrink-0 cursor-pointer items-center justify-center rounded-l-sm bg-green-600 peer-checked/yes:flex before:absolute before:-inset-[2px] before:-right-[0.5px]"
                      aria-hidden="true"
                    >
                      <Icon name="ri:check-line" class="size-3" />
                    </label>

                    <span
                      class="bg-night-400 border-night-500 before:bg-night-400 before:border-night-600 pointer-events-none block h-4 w-px border-y peer-checked/no:w-[0.5px] peer-checked/yes:w-[0.5px] before:h-full before:w-px before:border-y-2"
                      aria-hidden="true"
                    />

                    <label
                      for={noId}
                      class="border-night-500 bg-night-600 relative flex size-4 shrink-0 cursor-pointer items-center justify-center rounded-r-sm border border-l-0 peer-checked/no:hidden before:absolute before:-inset-[3px] before:-left-[0.5px]"
                      aria-hidden="true"
                    >
                      <Icon name="ri:close-line" class="size-3" />
                    </label>
                    <label
                      for={emptyId}
                      class="relative hidden size-4 w-[calc(var(--spacing)*4+0.5px)] shrink-0 cursor-pointer items-center justify-center rounded-r-sm bg-red-600 peer-checked/no:flex before:absolute before:-inset-[2px] before:-left-[0.5px]"
                      aria-hidden="true"
                    >
                      <Icon name="ri:close-line" class="size-3" />
                    </label>

                    <label
                      for={isPositive ? yesId : noId}
                      class="ml-2 flex min-w-0 cursor-pointer items-center font-normal peer-checked/no:hidden peer-checked/yes:hidden"
                      aria-hidden="true"
                    >
                      <Icon
                        name={attribute.typeInfo.icon}
                        class={cn('mr-2 size-3 shrink-0 opacity-80', attribute.typeInfo.classNames.icon)}
                        aria-hidden="true"
                      />
                      <span class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap">
                        {attribute.title}
                      </span>
                      <span class="text-day-500 ml-2 font-normal">{attribute._count.services}</span>
                    </label>
                    <label
                      for={emptyId}
                      class="ml-2 hidden min-w-0 cursor-pointer items-center font-bold peer-checked/no:flex peer-checked/yes:flex"
                      aria-hidden="true"
                    >
                      <Icon
                        name={attribute.typeInfo.icon}
                        class={cn('mr-2 size-3 shrink-0 opacity-100', attribute.typeInfo.classNames.icon)}
                        aria-hidden="true"
                      />
                      <span class="flex-1 overflow-hidden text-ellipsis whitespace-nowrap">
                        {attribute.title}
                      </span>
                      <span class="text-day-500 ml-2 font-normal">{attribute._count.services}</span>
                    </label>
                  </fieldset>
                </li>
              )
            })}
          </ul>

          {attributes.filter((attribute) => attribute.showAlways).length < attributes.length && (
            <>
              <input
                type="checkbox"
                id={`show-more-attributes-${categoryInfo.slug}`}
                class="peer sr-only"
                hx-preserve
              />
              <label
                for={`show-more-attributes-${categoryInfo.slug}`}
                class="peer-focus-visible:ring-offset-night-700 mt-2 block cursor-pointer rounded-sm text-sm text-green-500 peer-checked:hidden peer-focus-visible:ring-2 peer-focus-visible:ring-blue-500 peer-focus-visible:ring-offset-2"
              >
                + Show more
              </label>
              <label
                for={`show-more-attributes-${categoryInfo.slug}`}
                class="peer-focus-visible:ring-offset-night-700 mt-2 hidden cursor-pointer rounded-sm text-sm text-green-500 peer-checked:block peer-focus-visible:ring-2 peer-focus-visible:ring-blue-500 peer-focus-visible:ring-offset-2"
              >
                - Show less
              </label>
            </>
          )}
        </fieldset>
      ))
    }
  </fieldset>

  <!-- Score Filter -->
  <fieldset class="mb-6">
    <legend class="font-title mb-3 leading-none text-green-500">
      <label for="min-score">Score (min)</label>
    </legend>
    <div class="flex items-center gap-2">
      <input
        type="range"
        min="0"
        max="10"
        name="min-score"
        id="min-score"
        value={filters['min-score']}
        class="w-full accent-green-500"
        data-trigger-on-change
      />
    </div>
    <div class="-mx-1.5 mt-2 flex justify-between px-1">
      {
        [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map((score) => {
          const info = makeOverallScoreInfo(score)
          return (
            <Tooltip
              text={info.text}
              position="bottom"
              class={cn(
                'flex h-4 w-full max-w-4 min-w-0 cursor-default items-center justify-center rounded-xs text-xs font-bold tracking-tighter',
                info.classNameBg
              )}
            >
              {score.toLocaleString()}
            </Tooltip>
          )
        })
      }
    </div>
  </fieldset>

  <input type="hidden" name="sort-seed" value={filters['sort-seed']} />

  <div
    class="sm:js:hidden bg-night-700 sticky inset-x-0 bottom-0 mt-4 block rounded-t-md pb-4 shadow-[0_0_16px_16px_var(--color-night-700)]"
  >
    <Button type="submit" label="Apply" size="lg" class="w-full" color="success" shadow />
  </div>
</form>

<script>
  document.addEventListener('astro:page-load', () => {
    const forms = document.querySelectorAll<HTMLFormElement>('form[data-services-filters-form]')

    forms.forEach((form) => {
      form.addEventListener('input', () => {
        form.querySelectorAll<HTMLAnchorElement>('a#clear-filters-button').forEach((button) => {
          button.classList.remove('hidden')
        })

        const verificationInputs = form.querySelectorAll<HTMLInputElement>('input[name="verification"]')
        const noVerificationChecked = Array.from(verificationInputs).every((input) => !input.checked)
        if (noVerificationChecked) {
          verificationInputs.forEach((input) => {
            if (form.dataset.defaultVerificationFilter?.includes(input.value)) {
              input.checked = true
            }
          })
        }
      })
    })
  })
</script>
