import {
  TextField,
  FormControl,
  InputLabel,
  OutlinedInput,
  InputAdornment,
  IconButton,
  Select,
  MenuItem,
  Checkbox,
  FormControlLabel,
  RadioGroup,
  Radio,
  FormGroup,
  Chip,
  Box,
  FormHelperText,
  FormLabel,
  Switch,
  Slider,
  Autocomplete,
  Rating,
} from '@mui/material'
import Visibility from '@mui/icons-material/Visibility'
import VisibilityOff from '@mui/icons-material/VisibilityOff'
import CloudUploadIcon from '@mui/icons-material/CloudUpload'
import { useState } from 'react'

/**
 * MuiDynamicInput - A comprehensive reusable input component
 * 
 * Supported types:
 * - text, email, number, tel, url (standard text inputs)
 * - password (with optional show/hide toggle)
 * - select (single selection dropdown)
 * - multiselect (multiple selection dropdown)
 * - tags (chip-style multi-select)
 * - radio (radio button group)
 * - checkbox (checkbox group or single)
 * - switch (toggle switch)
 * - date, time, datetime-local (date/time pickers)
 * - textarea (multi-line text)
 * - file (file upload)
 * - slider (range slider)
 * - autocomplete (searchable dropdown)
 * - rating (star rating)
 */

export default function MuiDynamicInput({
  type = 'text',
  name = '',
  label = '',
  value,
  onChange,
  options = [],
  error = '',
  helperText = '',
  fullWidth = true,
  autoFocus = false,
  showPasswordToggle = true,
  placeholder = '',
  disabled = false,
  required = false,
  size = 'medium', // 'small' | 'medium'
  variant = 'outlined', // 'outlined' | 'filled' | 'standard'
  margin = 'normal', // 'none' | 'dense' | 'normal'
  multiline = false,
  rows = 4,
  min = 0,
  max = 100,
  step = 1,
  accept = '*', // for file input
  multiple = false, // for file input
  color = 'primary', // 'primary' | 'secondary' | 'success' | 'error' | 'warning'
  sx = {},
}) {
  const [showPassword, setShowPassword] = useState(false)
  const [fileName, setFileName] = useState('')

  const handleTogglePassword = () => setShowPassword((prev) => !prev)

  const handleFileChange = (event) => {
    const files = event.target.files
    if (files && files.length > 0) {
      const names = Array.from(files).map(f => f.name).join(', ')
      setFileName(names)
    }
    onChange && onChange(event)
  }

  // Common props for TextField-based inputs
  const commonTextFieldProps = {
    name,
    label,
    value,
    onChange,
    error: !!error,
    helperText: error || helperText,
    fullWidth,
    autoFocus,
    placeholder,
    disabled,
    required,
    size,
    variant,
    margin,
    color,
    sx,
  }

  switch (type) {
    // ==================== PASSWORD ====================
    case 'password':
      return (
        <FormControl 
          variant={variant} 
          fullWidth={fullWidth} 
          margin={margin} 
          error={!!error}
          disabled={disabled}
          required={required}
          size={size}
          sx={sx}
        >
          <InputLabel color={color}>{label}</InputLabel>
          <OutlinedInput
            name={name}
            type={showPassword ? 'text' : 'password'}
            value={value}
            onChange={onChange}
            autoFocus={autoFocus}
            placeholder={placeholder}
            color={color}
            endAdornment={
              showPasswordToggle && (
                <InputAdornment position="end">
                  <IconButton 
                    onClick={handleTogglePassword} 
                    edge="end"
                    disabled={disabled}
                    sx={{ color: '#034E08' }}
                  >
                    {showPassword ? <VisibilityOff /> : <Visibility />}
                  </IconButton>
                </InputAdornment>
              )
            }
            label={label}
          />
          {(error || helperText) && (
            <FormHelperText>{error || helperText}</FormHelperText>
          )}
        </FormControl>
      )

    // ==================== SELECT ====================
    case 'select':
      return (
        <FormControl 
          fullWidth={fullWidth} 
          margin={margin} 
          error={!!error}
          disabled={disabled}
          required={required}
          size={size}
          variant={variant}
          sx={sx}
        >
          <InputLabel color={color}>{label}</InputLabel>
          <Select 
            name={name}
            value={value} 
            onChange={onChange} 
            label={label}
            color={color}
          >
            {options.map((opt) => (
              <MenuItem key={opt.value} value={opt.value}>
                {opt.label}
              </MenuItem>
            ))}
          </Select>
          {(error || helperText) && (
            <FormHelperText>{error || helperText}</FormHelperText>
          )}
        </FormControl>
      )

    // ==================== MULTISELECT ====================
    case 'multiselect':
      return (
        <FormControl 
          fullWidth={fullWidth} 
          margin={margin} 
          error={!!error}
          disabled={disabled}
          required={required}
          size={size}
          variant={variant}
          sx={sx}
        >
          <InputLabel color={color}>{label}</InputLabel>
          <Select
            name={name}
            multiple
            value={value || []}
            onChange={onChange}
            label={label}
            color={color}
            renderValue={(selected) => selected.map(v => 
              options.find(o => o.value === v)?.label || v
            ).join(', ')}
          >
            {options.map((opt) => (
              <MenuItem key={opt.value} value={opt.value}>
                <Checkbox checked={(value || []).includes(opt.value)} color={color} />
                {opt.label}
              </MenuItem>
            ))}
          </Select>
          {(error || helperText) && (
            <FormHelperText>{error || helperText}</FormHelperText>
          )}
        </FormControl>
      )

    // ==================== TAGS (Chips) ====================
    case 'tags':
      return (
        <FormControl 
          fullWidth={fullWidth} 
          margin={margin} 
          error={!!error}
          disabled={disabled}
          required={required}
          size={size}
          variant={variant}
          sx={sx}
        >
          <InputLabel color={color}>{label}</InputLabel>
          <Select
            name={name}
            multiple
            value={value || []}
            onChange={onChange}
            label={label}
            color={color}
            renderValue={(selected) => (
              <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
                {selected.map((val) => (
                  <Chip 
                    key={val} 
                    label={options.find(o => o.value === val)?.label || val}
                    size="small"
                    color={color}
                    onDelete={disabled ? undefined : () => {
                      const newValue = (value || []).filter(v => v !== val)
                      onChange({ target: { name, value: newValue } })
                    }}
                    onMouseDown={(e) => e.stopPropagation()}
                  />
                ))}
              </Box>
            )}
          >
            {options.map((opt) => (
              <MenuItem key={opt.value} value={opt.value}>
                <Checkbox checked={(value || []).includes(opt.value)} color={color} />
                {opt.label}
              </MenuItem>
            ))}
          </Select>
          {(error || helperText) && (
            <FormHelperText>{error || helperText}</FormHelperText>
          )}
        </FormControl>
      )

    // ==================== RADIO ====================
    case 'radio':
      return (
        <FormControl 
          component="fieldset" 
          margin={margin} 
          error={!!error}
          disabled={disabled}
          required={required}
          fullWidth={fullWidth}
          sx={sx}
        >
          <FormLabel component="legend" color={color}>{label}</FormLabel>
          <RadioGroup 
            name={name}
            value={value} 
            onChange={onChange}
            row={options.length <= 4}
          >
            {options.map((opt) => (
              <FormControlLabel
                key={opt.value}
                value={opt.value}
                control={<Radio color={color} size={size} />}
                label={opt.label}
              />
            ))}
          </RadioGroup>
          {(error || helperText) && (
            <FormHelperText>{error || helperText}</FormHelperText>
          )}
        </FormControl>
      )

    // ==================== CHECKBOX ====================
    case 'checkbox':
      // Single checkbox (boolean value)
      if (options.length === 0) {
        return (
          <FormControl 
            margin={margin} 
            error={!!error}
            disabled={disabled}
            sx={sx}
          >
            <FormControlLabel
              control={
                <Checkbox
                  name={name}
                  checked={!!value}
                  onChange={(e) => onChange({ 
                    target: { name, value: e.target.checked } 
                  })}
                  color={color}
                  size={size}
                />
              }
              label={label}
            />
            {(error || helperText) && (
              <FormHelperText>{error || helperText}</FormHelperText>
            )}
          </FormControl>
        )
      }
      // Multiple checkboxes (array value)
      return (
        <FormControl 
          component="fieldset" 
          margin={margin} 
          error={!!error}
          disabled={disabled}
          fullWidth={fullWidth}
          sx={sx}
        >
          <FormLabel component="legend" color={color}>{label}</FormLabel>
          <FormGroup row={options.length <= 4}>
            {options.map((opt) => (
              <FormControlLabel
                key={opt.value}
                control={
                  <Checkbox
                    checked={(value || []).includes(opt.value)}
                    onChange={(e) => {
                      const currentValue = value || []
                      const newValue = e.target.checked
                        ? [...currentValue, opt.value]
                        : currentValue.filter((v) => v !== opt.value)
                      onChange({ target: { name, value: newValue } })
                    }}
                    color={color}
                    size={size}
                  />
                }
                label={opt.label}
              />
            ))}
          </FormGroup>
          {(error || helperText) && (
            <FormHelperText>{error || helperText}</FormHelperText>
          )}
        </FormControl>
      )

    // ==================== SWITCH ====================
    case 'switch':
      return (
        <FormControl 
          margin={margin} 
          error={!!error}
          disabled={disabled}
          sx={sx}
        >
          <FormControlLabel
            control={
              <Switch
                name={name}
                checked={!!value}
                onChange={(e) => onChange({ 
                  target: { name, value: e.target.checked } 
                })}
                color={color}
                size={size}
              />
            }
            label={label}
          />
          {(error || helperText) && (
            <FormHelperText>{error || helperText}</FormHelperText>
          )}
        </FormControl>
      )

    // ==================== DATE / TIME / DATETIME ====================
    case 'date':
    case 'time':
    case 'datetime-local':
      return (
        <TextField
          {...commonTextFieldProps}
          type={type}
          InputLabelProps={{ shrink: true }}
        />
      )

    // ==================== TEXTAREA ====================
    case 'textarea':
      return (
        <TextField
          {...commonTextFieldProps}
          multiline
          rows={rows}
        />
      )

    // ==================== FILE ====================
    case 'file':
      return (
        <FormControl 
          fullWidth={fullWidth} 
          margin={margin} 
          error={!!error}
          disabled={disabled}
          sx={sx}
        >
          <OutlinedInput
            name={name}
            type="file"
            onChange={handleFileChange}
            disabled={disabled}
            inputProps={{ accept, multiple }}
            startAdornment={
              <InputAdornment position="start">
                <CloudUploadIcon color={error ? 'error' : color} />
              </InputAdornment>
            }
            sx={{
              '& input::file-selector-button': {
                display: 'none',
              },
            }}
          />
          <FormHelperText>
            {error || helperText || (fileName ? `Selected: ${fileName}` : 'Choose file(s)')}
          </FormHelperText>
        </FormControl>
      )

    // ==================== SLIDER ====================
    case 'slider':
      return (
        <FormControl 
          fullWidth={fullWidth} 
          margin={margin}
          disabled={disabled}
          sx={sx}
        >
          <FormLabel color={color}>{label}</FormLabel>
          <Slider
            name={name}
            value={value || min}
            onChange={(_, newValue) => onChange({ 
              target: { name, value: newValue } 
            })}
            min={min}
            max={max}
            step={step}
            valueLabelDisplay="auto"
            disabled={disabled}
            color={color}
            size={size}
          />
          {(error || helperText) && (
            <FormHelperText error={!!error}>{error || helperText}</FormHelperText>
          )}
        </FormControl>
      )

    // ==================== AUTOCOMPLETE ====================
    case 'autocomplete':
      return (
        <Autocomplete
          options={options}
          getOptionLabel={(option) => option.label || ''}
          value={options.find(o => o.value === value) || null}
          onChange={(_, newValue) => onChange({ 
            target: { name, value: newValue?.value || '' } 
          })}
          disabled={disabled}
          fullWidth={fullWidth}
          size={size}
          sx={sx}
          renderInput={(params) => (
            <TextField
              {...params}
              name={name}
              label={label}
              error={!!error}
              helperText={error || helperText}
              required={required}
              variant={variant}
              margin={margin}
              color={color}
              placeholder={placeholder}
            />
          )}
        />
      )

    // ==================== RATING ====================
    case 'rating':
      return (
        <FormControl 
          margin={margin}
          disabled={disabled}
          sx={sx}
        >
          <FormLabel color={color}>{label}</FormLabel>
          <Rating
            name={name}
            value={value || 0}
            onChange={(_, newValue) => onChange({ 
              target: { name, value: newValue } 
            })}
            disabled={disabled}
            size={size}
            max={max || 5}
          />
          {(error || helperText) && (
            <FormHelperText error={!!error}>{error || helperText}</FormHelperText>
          )}
        </FormControl>
      )

    // ==================== DEFAULT (text, email, number, tel, url) ====================
    default:
      return (
        <TextField
          {...commonTextFieldProps}
          type={type}
          multiline={multiline}
          rows={multiline ? rows : undefined}
          inputProps={type === 'number' ? { min, max, step } : undefined}
        />
      )
  }
}

// ==================== USAGE EXAMPLE ====================
/*
import MuiDynamicInput from './MuiDynamicInput'

function MyForm() {
  const [formData, setFormData] = React.useState({
    email: '',
    password: '',
    country: '',
    skills: [],
    gender: '',
    newsletter: false,
    bio: '',
    birthDate: '',
    rating: 0,
  })

  const handleChange = (e) => {
    const { name, value } = e.target
    setFormData(prev => ({ ...prev, [name]: value }))
  }

  return (
    <Box sx={{ maxWidth: 600, mx: 'auto', p: 3 }}>
      <MuiDynamicInput
        type="email"
        name="email"
        label="Email Address"
        value={formData.email}
        onChange={handleChange}
        required
      />
      
      <MuiDynamicInput
        type="password"
        name="password"
        label="Password"
        value={formData.password}
        onChange={handleChange}
        showPasswordToggle
        required
      />
      
      <MuiDynamicInput
        type="select"
        name="country"
        label="Country"
        value={formData.country}
        onChange={handleChange}
        options={[
          { value: 'us', label: 'United States' },
          { value: 'uk', label: 'United Kingdom' },
          { value: 'in', label: 'India' },
        ]}
      />
      
      <MuiDynamicInput
        type="tags"
        name="skills"
        label="Skills"
        value={formData.skills}
        onChange={handleChange}
        options={[
          { value: 'react', label: 'React' },
          { value: 'vue', label: 'Vue' },
          { value: 'angular', label: 'Angular' },
        ]}
        color="success"
      />
      
      <MuiDynamicInput
        type="radio"
        name="gender"
        label="Gender"
        value={formData.gender}
        onChange={handleChange}
        options={[
          { value: 'male', label: 'Male' },
          { value: 'female', label: 'Female' },
          { value: 'other', label: 'Other' },
        ]}
      />
      
      <MuiDynamicInput
        type="checkbox"
        name="newsletter"
        label="Subscribe to newsletter"
        value={formData.newsletter}
        onChange={handleChange}
      />
      
      <MuiDynamicInput
        type="textarea"
        name="bio"
        label="Bio"
        value={formData.bio}
        onChange={handleChange}
        rows={4}
      />
      
      <MuiDynamicInput
        type="date"
        name="birthDate"
        label="Birth Date"
        value={formData.birthDate}
        onChange={handleChange}
      />
      
      <MuiDynamicInput
        type="rating"
        name="rating"
        label="Rate your experience"
        value={formData.rating}
        onChange={handleChange}
      />
      
      <MuiDynamicInput
        type="slider"
        name="volume"
        label="Volume"
        value={formData.volume}
        onChange={handleChange}
        min={0}
        max={100}
      />
      
      <MuiDynamicInput
        type="file"
        name="avatar"
        label="Upload Avatar"
        onChange={handleChange}
        accept="image/*"
      />
    </Box>
  )
}
*/