// components/ui/RadioGroup.tsx
'use client';

import * as React from 'react';
import clsx from 'clsx';

export type RadioGroupOption = {
  value: string;
  label: React.ReactNode;
  description?: React.ReactNode;
  disabled?: boolean;
  className?: string;
};

export type RadioGroupVariant =
  | 'simple'          // Radio links, Label rechts
  | 'withDescription' // Label + Description untereinander
  | 'right'           // Label links, Radio rechts
  | 'panel';          // Segment-Panel (Pricing/Privacy-Style)

type RadioGroupProps = {
  name?: string;
  legend?: React.ReactNode;
  helpText?: React.ReactNode;
  options: RadioGroupOption[];

  /** Kontrollierter Wert (oder null für nichts gewählt) */
  value: string | null;
  onChange: (value: string) => void;

  orientation?: 'vertical' | 'horizontal'; // nur relevant für simple
  variant?: RadioGroupVariant;

  className?: string;
  optionClassName?: string;
  idPrefix?: string;
};

const baseRadioClasses =
  'relative size-4 appearance-none rounded-full border border-gray-300 bg-white ' +
  'before:absolute before:inset-1 before:rounded-full before:bg-white ' +
  'not-checked:before:hidden checked:border-indigo-600 checked:bg-indigo-600 ' +
  'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 ' +
  'disabled:border-gray-300 disabled:bg-gray-100 disabled:before:bg-gray-400 ' +
  'dark:border-white/10 dark:bg-white/5 dark:checked:border-indigo-500 dark:checked:bg-indigo-500 ' +
  'dark:focus-visible:outline-indigo-500 dark:disabled:border-white/5 dark:disabled:bg-white/10 ' +
  'dark:disabled:before:bg-white/20 forced-colors:appearance-auto forced-colors:before:hidden';

export function RadioGroup({
  name,
  legend,
  helpText,
  options,
  value,
  onChange,
  orientation = 'vertical',
  variant = 'simple',
  className,
  optionClassName,
  idPrefix = 'rg',
}: RadioGroupProps) {
  const internalName = React.useId();
  const groupName = name ?? internalName;

  const isHorizontal = orientation === 'horizontal';

  const handleChange = (nextValue: string) => {
    if (nextValue !== value) {
      onChange(nextValue);
    }
  };

  const renderSimple = () => (
    <div
      className={clsx(
        'mt-3',
        isHorizontal
          ? 'space-y-3 sm:flex sm:items-center sm:space-y-0 sm:space-x-8'
          : 'space-y-3',
      )}
    >
      {options.map((opt) => {
        const id = `${idPrefix}-${groupName}-${opt.value}`;
        return (
          <div
            key={opt.value}
            className={clsx('flex items-center', optionClassName, opt.className)}
          >
            <input
              id={id}
              name={groupName}
              type="radio"
              value={opt.value}
              checked={value === opt.value}
              disabled={opt.disabled}
              onChange={() => handleChange(opt.value)}
              className={baseRadioClasses}
            />
            <label
              htmlFor={id}
              className={clsx(
                'ml-3 block text-sm/6 font-medium',
                opt.disabled
                  ? 'text-gray-400 dark:text-gray-500'
                  : 'text-gray-900 dark:text-white',
              )}
            >
              {opt.label}
            </label>
          </div>
        );
      })}
    </div>
  );

  const renderWithDescription = () => (
    <div className="mt-3 space-y-5">
      {options.map((opt) => {
        const id = `${idPrefix}-${groupName}-${opt.value}`;
        const descId = opt.description ? `${id}-description` : undefined;
        return (
          <div
            key={opt.value}
            className={clsx(
              'relative flex items-start',
              optionClassName,
              opt.className,
            )}
          >
            <div className="flex h-6 items-center">
              <input
                id={id}
                name={groupName}
                type="radio"
                value={opt.value}
                checked={value === opt.value}
                disabled={opt.disabled}
                aria-describedby={descId}
                onChange={() => handleChange(opt.value)}
                className={baseRadioClasses}
              />
            </div>
            <div className="ml-3 text-sm/6">
              <label
                htmlFor={id}
                className={clsx(
                  'font-medium',
                  opt.disabled
                    ? 'text-gray-400 dark:text-gray-500'
                    : 'text-gray-900 dark:text-white',
                )}
              >
                {opt.label}
              </label>
              {opt.description && (
                <p
                  id={descId}
                  className={clsx(
                    'text-gray-500 dark:text-gray-400',
                    opt.disabled && 'opacity-70',
                  )}
                >
                  {opt.description}
                </p>
              )}
            </div>
          </div>
        );
      })}
    </div>
  );

  const renderRight = () => (
    <div className="mt-3 divide-y divide-gray-200 border-t border-b border-gray-200 dark:divide-white/10 dark:border-white/10">
      {options.map((opt, idx) => {
        const id = `${idPrefix}-${groupName}-${opt.value || idx}`;
        const descId = opt.description ? `${id}-description` : undefined;
        return (
          <div
            key={opt.value}
            className={clsx(
              'relative flex items-start py-4',
              optionClassName,
              opt.className,
            )}
          >
            <div className="min-w-0 flex-1 text-sm/6">
              <label
                htmlFor={id}
                className={clsx(
                  'font-medium select-none',
                  opt.disabled
                    ? 'text-gray-400 dark:text-gray-500'
                    : 'text-gray-900 dark:text-white',
                )}
              >
                {opt.label}
              </label>
              {opt.description && (
                <p
                  id={descId}
                  className="text-gray-500 dark:text-gray-400"
                >
                  {opt.description}
                </p>
              )}
            </div>
            <div className="ml-3 flex h-6 items-center">
              <input
                id={id}
                name={groupName}
                type="radio"
                value={opt.value}
                checked={value === opt.value}
                disabled={opt.disabled}
                aria-describedby={descId}
                onChange={() => handleChange(opt.value)}
                className={baseRadioClasses}
              />
            </div>
          </div>
        );
      })}
    </div>
  );

  const renderPanel = () => (
    <div className="-space-y-px rounded-md bg-white dark:bg-gray-800/50">
      {options.map((opt, index) => {
        const id = `${idPrefix}-${groupName}-${opt.value}`;
        return (
          <label
            key={opt.value}
            htmlFor={id}
            className={clsx(
              'group flex border border-gray-200 p-4 focus:outline-hidden',
              'first:rounded-tl-md first:rounded-tr-md last:rounded-br-md last:rounded-bl-md',
              'has-checked:relative has-checked:border-indigo-200 has-checked:bg-indigo-50',
              'dark:border-gray-700 dark:has-checked:border-indigo-800 dark:has-checked:bg-indigo-500/10',
              optionClassName,
              opt.className,
            )}
          >
            <input
              id={id}
              name={groupName}
              type="radio"
              value={opt.value}
              checked={value === opt.value}
              disabled={opt.disabled}
              onChange={() => handleChange(opt.value)}
              className={clsx(
                baseRadioClasses,
                'mt-0.5 shrink-0',
                opt.disabled && 'opacity-70',
              )}
            />
            <span className="ml-3 flex flex-col text-sm">
              <span
                className={clsx(
                  'font-medium',
                  'text-gray-900 group-has-checked:text-indigo-900',
                  'dark:text-white dark:group-has-checked:text-indigo-300',
                  opt.disabled && 'opacity-70',
                )}
              >
                {opt.label}
              </span>
              {opt.description && (
                <span
                  className={clsx(
                    'text-gray-500 group-has-checked:text-indigo-700',
                    'dark:text-gray-400 dark:group-has-checked:text-indigo-300/75',
                    opt.disabled && 'opacity-70',
                  )}
                >
                  {opt.description}
                </span>
              )}
            </span>
          </label>
        );
      })}
    </div>
  );

  return (
    <fieldset className={className}>
      {legend && (
        <legend className="text-sm/6 font-semibold text-gray-900 dark:text-white">
          {legend}
        </legend>
      )}

      {helpText && (
        <p className="mt-1 text-sm/6 text-gray-600 dark:text-gray-400">
          {helpText}
        </p>
      )}

      {variant === 'withDescription' && renderWithDescription()}
      {variant === 'right' && renderRight()}
      {variant === 'panel' && renderPanel()}
      {variant === 'simple' && renderSimple()}
    </fieldset>
  );
}
