'use client'

import React, { useState, type ReactElement, useEffect } from 'react'
import Label from '@/Components/Inputs/Label'
import Description from '@/Components/Inputs/Description'
import { makeClassName } from '@/utils'
import { IRadioGroupProps, type ISelectProps } from '@/Types/InputTypes'
import * as RadioGroup from '@radix-ui/react-radio-group'

export default function RadixRadioGroup({
  children,
  onChange,
  value,
  id,
  testId = 'select',
  options = [],
  label,
  description,
  before,
  after,
  size = 'med',
  defaultClassName = 'flex flex-col gap-2.5',
  disabled = false,
  className = '',
  error

}: IRadioGroupProps): ReactElement {
  const sizes: Record<string, string> = {
    xs: 'h-[12px] w-[12px]',
    sm: 'h-[15px] w-[15px]',
    med: 'w-[20px] h-[20px]',
    lg: 'h-[25px] w-[25px]',
    xlg: 'h-[30px] w-[30px]'
  }
  const defaultSize: string = size in sizes ? sizes[size] : sizes.med
  const defaultSelectorStyle = `bg-white ${defaultSize} rounded-full shadow-[0_2px_10px] shadow-blackA7 hover:bg-violet3 focus:shadow-[0_0_0_2px] focus:shadow-black outline-none cursor-default`

  const selectedSizes: Record<string, string> = {
    xs: 'after:w-[5px] after:h-[5px]',
    sm: 'after:w-[7px] after:h-[7px]',
    med: 'after:w-[9px] after:h-[9px]',
    lg: 'after:w-[11px] after:h-[11px]',
    xlg: 'after:w-[13px] after:h-[13px]'
  }

  const defaultSelectedSize: string = size in selectedSizes ? selectedSizes[size] : selectedSizes.med
  const defaultSelectedStyle = `flex items-center justify-center w-full h-full relative after:content-[''] after:block ${defaultSelectedSize} after:rounded-[50%] after:bg-slate-600`

  const labelSizes: Record<string, string> = {
    xs: 'text-[10px]',
    sm: 'text-[12px]',
    med: 'text-[14px]',
    lg: 'text-[16px]',
    xlg: 'text-[18px]'
  }
  const defaultLabelSize: string = size in labelSizes ? labelSizes[size] : labelSizes.med
  const defaultLabelStyle = `${defaultLabelSize} leading-none pl-[15px]`
  const optionsToUse = options.slice()
  const optionsMap = Object.fromEntries(optionsToUse.map(o => [o.value, o]))
  const onSelectChange = (newV: string): void => {
    setVal(newV)
    if (typeof onChange === 'function') {
      const op = optionsMap[newV]
      if (op === undefined || newV === '') {
        onChange(undefined)
      } else {
        onChange(op)
      }
    }
  }
  const [val, setVal] = useState<string | number | undefined>(value)
  const instanceId = (crypto !== undefined && typeof crypto.randomUUID === 'function') ? crypto.randomUUID() : `${Math.random().toString(36).substring(2, 15)}-${Math.random().toString(36).substring(2, 15)}`

  useEffect(() => {
    setVal(value)
  }, [value])
  return (
    <div>
      {
        before !== undefined ? before : ''
      }
      {
        typeof label === 'string'
          ? <Label label={label} disabled={disabled} />
          : label !== undefined ? label : ''
      }
      {
        typeof description === 'string'
          ? <Description description={description} disabled={disabled} />
          : description !== undefined ? description : ''
      }
      <div className="flex gap-2">

        <RadioGroup.Root
          className={`${makeClassName({

            defaultClassName,
            className,
            extras: [
              disabled ? 'cursor-not-allowed opacity-50' : undefined
            ]
          })}`}
          disabled={disabled}
          aria-label='Select from options'
          onValueChange={onSelectChange}
          defaultValue={value !== undefined ? String(value) : value}
          value={val !== undefined ? String(val) : val}
        >

          {
            options.map(option => {
              const optionId = `${option.value}.${instanceId}`
              return (
                <div className="flex items-center" key={option.value}>
                  <RadioGroup.Item
                    className={makeClassName({
                      defaultClassName: defaultSelectorStyle,
                      extras: [
                        disabled ? 'cursor-not-allowed' : undefined
                      ]
                    })}

                    id={optionId}
                    value={option.value !== undefined ? String(option.value) : option.value}
                  >
                    <RadioGroup.Indicator className={defaultSelectedStyle} />
                  </RadioGroup.Item>
                  <label className={makeClassName({
                    defaultClassName: defaultLabelStyle,
                    extras: [
                      disabled ? 'text-slate-600 cursor-not-allowed' : undefined
                    ]
                  })} htmlFor={optionId}>
                    {option.label}
                  </label>
                </div>
              )
            })
          }

        </RadioGroup.Root>
      </div>
      {
        after !== undefined ? after : ''
      }
    </div>

  )
}
