import * as React from 'react';
import {
  Box,
  TextField,
  Button,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  FormControlLabel,
  Checkbox,
  Typography,
  Divider,
} from '@mui/material';
import { ResourceConfig, ResourceField } from '../types/config';
import { useUpload } from '../providers/UploadProvider';
import ImageUploadField from './fields/ImageUploadField';

interface GenericFormProps {
  config: ResourceConfig;
  initialData?: any;
  onSave: (data: any) => Promise<void>;
  onCancel: () => void;
  loading?: boolean;
}

export default function GenericForm({
  config,
  initialData = {},
  onSave,
  onCancel,
  loading: saving,
}: GenericFormProps) {
  const [formData, setFormData] = React.useState(initialData);
  const { uploadFile, uploading } = useUpload();

  const handleChange = (key: string, value: any) => {
    setFormData((prev: any) => ({ ...prev, [key]: value }));
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    onSave(formData);
  };

  return (
    <Box component="form" onSubmit={handleSubmit} sx={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
      <Typography variant="h5">
        {initialData[config.primaryKey] ? `Edit ${config.label}` : `New ${config.label}`}
      </Typography>
      <Divider />

      {Object.entries(config.fields).map(([key, field]) => (
        <FormField
          key={key}
          name={key}
          field={field}
          value={formData[key]}
          onChange={(val: any) => handleChange(key, val)}
          disabled={field.readOnly}
          uploadFile={uploadFile}
          uploading={uploading}
        />
      ))}

      <Box sx={{ display: 'flex', justifyContent: 'flex-end', gap: 2, mt: 4 }}>
        <Button variant="outlined" onClick={onCancel} disabled={saving}>
          Cancel
        </Button>
        <Button variant="contained" type="submit" loading={saving} disabled={saving || uploading}>
          Save {config.label}
        </Button>
      </Box>
    </Box>
  );
}

function FormField({ name, field, value, onChange, disabled, uploadFile, uploading }: any) {
  const label = field.label;

  if (field.type === 'image') {
    return (
      <ImageUploadField
        label={label}
        value={value}
        onUpload={async (file) => {
          const url = await uploadFile(file);
          if (url) onChange(url);
        }}
        uploading={uploading}
      />
    );
  }

  if (field.type === 'boolean') {
    return (
      <FormControlLabel
        control={
          <Checkbox
            checked={!!value}
            onChange={(e) => onChange(e.target.checked)}
            disabled={disabled}
          />
        }
        label={label}
      />
    );
  }

  if (field.type === 'enum' && field.options) {
    return (
      <FormControl fullWidth>
        <InputLabel>{label}</InputLabel>
        <Select
          value={value || ''}
          label={label}
          onChange={(e) => onChange(e.target.value)}
          disabled={disabled}
        >
          {field.options.map((opt: string) => (
            <MenuItem key={opt} value={opt}>
              {opt}
            </MenuItem>
          ))}
        </Select>
      </FormControl>
    );
  }

  if (field.type === 'datetime') {
    return (
      <TextField
        fullWidth
        label={label}
        type="datetime-local"
        InputLabelProps={{ shrink: true }}
        value={value ? new Date(value).toISOString().slice(0, 16) : ''}
        onChange={(e) => onChange(e.target.value)}
        disabled={disabled}
        required={field.required}
      />
    );
  }

  if (field.type === 'date') {
    return (
      <TextField
        fullWidth
        label={label}
        type="date"
        InputLabelProps={{ shrink: true }}
        value={value ? new Date(value).toISOString().split('T')[0] : ''}
        onChange={(e) => onChange(e.target.value)}
        disabled={disabled}
        required={field.required}
      />
    );
  }

  if (field.type === 'markdown' || field.type === 'string') {
    return (
      <TextField
        fullWidth
        label={label}
        value={value || ''}
        multiline={field.type === 'markdown'}
        rows={field.type === 'markdown' ? 4 : 1}
        onChange={(e) => onChange(e.target.value)}
        disabled={disabled}
        required={field.required}
      />
    );
  }

  if (field.type === 'number') {
    return (
      <TextField
        fullWidth
        label={label}
        type="number"
        value={value || 0}
        onChange={(e) => onChange(Number(e.target.value))}
        disabled={disabled}
        required={field.required}
      />
    );
  }

  return (
    <TextField
      fullWidth
      label={label}
      value={JSON.stringify(value)}
      disabled
    />
  );
}
