/**
 * ResponsiveControl Component
 *
 * A reusable wrapper that adds responsive breakpoint toggles (desktop/tablet/mobile)
 * to any input control. Shows a button group to switch between breakpoints.
 */

import {useState, useCallback, ReactNode} from "react";
import {DesktopIcon, MobileIcon, LaptopIcon} from "@radix-ui/react-icons";
import type {Breakpoint, ResponsiveValue} from "@/types";
import {isResponsiveValue, createResponsiveValue} from "@/types";

// Breakpoint options for the toggle
const BREAKPOINT_OPTIONS: {
  value: Breakpoint;
  icon: ReactNode;
  label: string;
}[] = [
  {value: "desktop", icon: <DesktopIcon />, label: "Desktop"},
  {value: "tablet", icon: <LaptopIcon />, label: "Tablet"},
  {value: "mobile", icon: <MobileIcon />, label: "Mobile"},
];

interface ResponsiveControlProps<T> {
  /** Label for the control */
  label?: string;
  /** Current responsive value */
  value: ResponsiveValue<T> | T;
  /** Called when value changes for current breakpoint */
  onChange: (value: ResponsiveValue<T>) => void;
  /** Render the actual input control for a breakpoint */
  renderControl: (
    breakpointValue: T,
    onBreakpointChange: (value: T) => void,
    breakpoint: Breakpoint
  ) => ReactNode;
  /** Use compact styling */
  size?: "default" | "compact";
  /** Additional class name */
  className?: string;
  /** Show label inline with breakpoint toggle */
  inlineLabel?: boolean;
}

export function ResponsiveControl<T>({
  label,
  value,
  onChange,
  renderControl,
  size = "compact",
  className = "",
  inlineLabel = false,
}: ResponsiveControlProps<T>) {
  // Track current breakpoint
  const [activeBreakpoint, setActiveBreakpoint] =
    useState<Breakpoint>("desktop");

  // Ensure we have a responsive value structure
  const responsiveValue: ResponsiveValue<T> = isResponsiveValue(value)
    ? value
    : createResponsiveValue(value);

  // Get current breakpoint value
  const currentValue = responsiveValue[activeBreakpoint];

  // Handle value change for current breakpoint
  const handleValueChange = useCallback(
    (newValue: T) => {
      onChange({
        ...responsiveValue,
        [activeBreakpoint]: newValue,
      });
    },
    [onChange, responsiveValue, activeBreakpoint]
  );

  const labelClass =
    size === "compact" ? "floating-settings__label" : "settings-label";

  return (
    <div className={`responsive-control ${className}`}>
      {/* Header with label and breakpoint toggle */}
      <div
        className={`responsive-control__header ${
          inlineLabel ? "responsive-control__header--inline" : ""
        }`}
      >
        {label && <label className={labelClass}>{label}</label>}

        {/* Breakpoint toggle */}
        <div className="responsive-control__breakpoints">
          {BREAKPOINT_OPTIONS.map((option) => (
            <button
              key={option.value}
              type="button"
              className={`responsive-control__breakpoint-btn ${
                activeBreakpoint === option.value ? "active" : ""
              }`}
              onClick={() => setActiveBreakpoint(option.value)}
              title={option.label}
            >
              {option.icon}
            </button>
          ))}
        </div>
      </div>

      {/* Actual input control */}
      <div className="responsive-control__input">
        {renderControl(currentValue, handleValueChange, activeBreakpoint)}
      </div>
    </div>
  );
}

export default ResponsiveControl;
