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

import { cn } from '../lib/cn'

import InputWrapper from './InputWrapper.astro'

import type { MarkdownString } from '../lib/markdown'
import type { ComponentProps } from 'astro/types'

type Props<Multiple extends boolean = false> = Omit<
  ComponentProps<typeof InputWrapper>,
  'children' | 'inputId'
> & {
  options: {
    label: string
    value: string
    icon?: string
    iconClass?: string
    description?: MarkdownString
    disabled?: boolean
    noTransitionPersist?: boolean
  }[]
  disabled?: boolean
  selectedValue?: Multiple extends true ? string[] : string
  cardSize?: 'lg' | 'md' | 'sm'
  iconSize?: 'md' | 'sm'
  multiple?: Multiple
}

const {
  options,
  disabled,
  selectedValue = undefined as string[] | string | undefined,
  cardSize = 'sm',
  iconSize = 'sm',
  class: className,
  multiple = false as boolean,
  ...wrapperProps
} = Astro.props

const hasError = !!wrapperProps.error && wrapperProps.error.length > 0
---

{/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */}
<InputWrapper class={cn('@container', className)} {...wrapperProps}>
  <div
    class={cn(
      'grid grid-cols-[repeat(auto-fill,minmax(var(--card-min-size),1fr))] gap-2 rounded-lg',
      !multiple &&
        'has-focus-visible:ring-offset-night-900 has-focus-visible:ring-day-200 has-focus-visible:bg-night-900 has-focus-visible:ring-2 has-focus-visible:ring-offset-3',
      {
        '[--card-min-size:12rem] @max-[12rem]:grid-cols-1': cardSize === 'sm',
        '[--card-min-size:16rem] @max-[16rem]:grid-cols-1': cardSize === 'md',
        '[--card-min-size:32rem] @max-[32rem]:grid-cols-1': cardSize === 'lg',
      },
      hasError && 'border border-red-700 p-2'
    )}
  >
    {
      options.map((option) => (
        <label
          class={cn(
            'group border-night-400 bg-night-600 hover:bg-night-500 relative cursor-pointer items-start gap-3 rounded-lg border p-3 transition-all',
            'has-checked:border-green-700 has-checked:bg-green-700/20 has-checked:ring-1 has-checked:ring-green-700',
            multiple &&
              'has-focus-visible:border-day-300 has-focus-visible:ring-2 has-focus-visible:ring-green-700 has-focus-visible:ring-offset-1',
            'has-[input:disabled]:cursor-not-allowed has-[input:disabled]:opacity-50'
          )}
        >
          <input
            transition:persist={option.noTransitionPersist ? undefined : true}
            type={multiple ? 'checkbox' : 'radio'}
            name={wrapperProps.name}
            value={option.value}
            checked={
              Array.isArray(selectedValue)
                ? selectedValue.includes(option.value)
                : selectedValue === option.value
            }
            class="peer sr-only"
            disabled={disabled || option.disabled}
          />
          <div class="flex items-center gap-1.5">
            {option.icon && (
              <Icon
                name={option.icon}
                class={cn(
                  'text-day-200 group-peer-checked:text-day-300 size-8',
                  {
                    'size-4': iconSize === 'sm',
                    'size-8': iconSize === 'md',
                  },
                  option.iconClass
                )}
              />
            )}
            <p class="text-day-200 group-peer-checked:text-day-300 flex-1 text-sm leading-none font-medium text-pretty">
              {option.label}
            </p>
            <div class="self-stretch">
              <div
                class={cn(
                  'border-day-600 flex size-5 items-center justify-center border-2',
                  'group-has-checked:border-green-600 group-has-checked:bg-green-600',
                  multiple ? 'rounded-md' : 'rounded-full',
                  !!option.description && '-m-1'
                )}
              >
                <Icon
                  name="ri:check-line"
                  class="text-day-100 size-3 opacity-0 group-has-checked:opacity-100"
                />
              </div>
            </div>
          </div>
          {option.description && (
            <div class="prose prose-sm prose-invert text-day-400 mt-1 text-xs text-pretty">
              <Markdown content={option.description} />
            </div>
          )}
        </label>
      ))
    }
  </div>
</InputWrapper>
