import React from 'react';
import FormControl from '@mui/material/FormControl';
import InputLabel from '@mui/material/InputLabel';
import OutlinedInput from '@mui/material/OutlinedInput';
import type { OutlinedInputProps } from '@mui/material/OutlinedInput';
import FormHelperText from '@mui/material/FormHelperText';
import InputAdornment from '@mui/material/InputAdornment';
import type { Theme } from '@mui/material/styles';

// ─── Types ───────────────────────────────────────────────────────────────────

/** Props for the FA Input component */
export interface InputProps extends Omit<OutlinedInputProps, 'notched' | 'label'> {
  /** Label text displayed above the input */
  label?: string;
  /** Helper/description text displayed below the input */
  helperText?: React.ReactNode;
  /** Show success validation state (green border and helper text) */
  success?: boolean;
  /** Icon element to show at the start (left) of the input */
  startIcon?: React.ReactNode;
  /** Icon element to show at the end (right) of the input */
  endIcon?: React.ReactNode;
  /** Whether the input takes full width of its container */
  fullWidth?: boolean;
}

// ─── Component ───────────────────────────────────────────────────────────────

/**
 * Text input component for the FA design system.
 *
 * Wraps MUI OutlinedInput with an external label pattern, FA brand tokens,
 * two sizes (small/medium), and success/error validation states.
 *
 * Features:
 * - External label with required asterisk indicator
 * - Helper text that contextually colours for error/success
 * - Leading and trailing icon slots (via `startIcon`/`endIcon`)
 * - Branded focus ring (warm gold double-ring from Figma)
 * - Two sizes: `medium` (48px, default) and `small` (40px)
 * - Multiline/textarea support via `multiline` + `rows`/`minRows`
 *
 * State mapping from Figma design:
 * - Default → resting state, neutral border
 * - Hover → darker border (CSS :hover)
 * - Focus → brand.500 border + double focus ring
 * - Error → `error` prop — red border + red helper text
 * - Success → `success` prop — green border + green helper text
 * - Disabled → `disabled` prop — grey background, muted text
 */
export const Input = React.forwardRef<HTMLDivElement, InputProps>(
  (
    {
      label,
      helperText,
      success = false,
      error = false,
      required = false,
      disabled = false,
      fullWidth = true,
      startIcon,
      endIcon,
      startAdornment,
      endAdornment,
      id,
      size = 'medium',
      sx,
      ...props
    },
    ref,
  ) => {
    const autoId = React.useId();
    const inputId = id || autoId;
    const helperId = helperText ? `${inputId}-helper` : undefined;

    // Prefer convenience icon props; fall back to raw adornment props
    const resolvedStart = startIcon ? (
      <InputAdornment position="start">{startIcon}</InputAdornment>
    ) : (
      startAdornment
    );

    const resolvedEnd = endIcon ? (
      <InputAdornment position="end">{endIcon}</InputAdornment>
    ) : (
      endAdornment
    );

    return (
      <FormControl
        ref={ref}
        fullWidth={fullWidth}
        error={error}
        disabled={disabled}
        required={required}
      >
        {label && (
          <InputLabel
            htmlFor={inputId}
            shrink
            sx={{
              position: 'static',
              transform: 'none',
              maxWidth: 'none',
              pointerEvents: 'auto',
              mb: 2.5,
              // labelLg typography
              fontFamily: (theme) => theme.typography.labelLg.fontFamily,
              fontSize: (theme) => theme.typography.labelLg.fontSize,
              fontWeight: (theme) => theme.typography.labelLg.fontWeight,
              lineHeight: (theme) => theme.typography.labelLg.lineHeight,
              letterSpacing: (theme) =>
                (theme.typography.labelLg as { letterSpacing?: string }).letterSpacing ?? 'normal',
              color: 'text.secondary',
              // Label stays neutral on error/focus/success (per Figma design)
              '&.Mui-focused': { color: 'text.secondary' },
              '&.Mui-error': { color: 'text.secondary' },
              '&.Mui-disabled': { color: 'text.disabled' },
              // Required asterisk in error red
              '& .MuiInputLabel-asterisk': { color: 'error.main' },
            }}
          >
            {label}
          </InputLabel>
        )}

        <OutlinedInput
          id={inputId}
          size={size}
          error={error}
          disabled={disabled}
          required={required}
          notched={false}
          startAdornment={resolvedStart}
          endAdornment={resolvedEnd}
          aria-describedby={helperId}
          sx={[
            // Success border + focus ring (not a native MUI state)
            success &&
              !error && {
                '& .MuiOutlinedInput-notchedOutline': {
                  borderColor: 'success.main',
                },
                '&.Mui-focused .MuiOutlinedInput-notchedOutline': {
                  borderColor: 'success.main',
                },
                '&.Mui-focused': {
                  boxShadow: (theme: Theme) =>
                    `0 0 0 3px ${theme.palette.common.white}, 0 0 0 5px ${theme.palette.success.main}`,
                },
              },
            ...(Array.isArray(sx) ? sx : [sx]),
          ]}
          {...props}
        />

        {helperText && (
          <FormHelperText
            id={helperId}
            error={error}
            disabled={disabled}
            role={error ? 'alert' : undefined}
            sx={{
              mx: 0,
              mt: 1.5,
              // caption typography
              fontFamily: (theme) => theme.typography.caption.fontFamily,
              fontSize: (theme) => theme.typography.caption.fontSize,
              fontWeight: (theme) => theme.typography.caption.fontWeight,
              lineHeight: (theme) => theme.typography.caption.lineHeight,
              letterSpacing: (theme) => theme.typography.caption.letterSpacing,
              // Contextual colour: error > success > secondary
              ...(error
                ? { color: 'error.main' }
                : success
                  ? { color: 'success.main' }
                  : { color: 'text.secondary' }),
            }}
          >
            {helperText}
          </FormHelperText>
        )}
      </FormControl>
    );
  },
);

Input.displayName = 'Input';
export default Input;
