import * as React from 'react';
import {
  TextField,
  FormControl,
  InputLabel,
  Select,
  MenuItem,
  FormControlLabel,
  Checkbox,
  Typography,
  Box,
  Divider,
} from '@mui/material';
import { ResourceField } from '../../types/config';
import { getFieldOptions } from '../../utils/options';
import ImageUploadField from './ImageUploadField';

interface FormFieldProps {
  name: string;
  field: ResourceField;
  value: any;
  onChange: (val: any) => void;
  disabled?: boolean;
  uploadFile: (file: File) => Promise<string | null>;
  uploading: boolean;
  baseUrl: string;
  relationDataMap?: Record<string, any[]>; // Map of relation name to data array
}

export default function FormField({
  name,
  field,
  value,
  onChange,
  disabled,
  uploadFile,
  uploading,
  baseUrl,
  relationDataMap = {},
}: FormFieldProps) {
  const label = field.label;

  // 1. Recursive Rendering for Objects (Not Relations)
  if (field.type === 'object' && field.schema && !field.relation) {
    return (
      <Box sx={{ ml: 2, mt: 2, p: 2, borderLeft: '2px solid #e0e0e0' }}>
        <Typography variant="subtitle2" color="primary" gutterBottom>
          {label}
        </Typography>
        <Box sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
          {Object.entries(field.schema).map(([subKey, subField]) => (
            <FormField
              key={subKey}
              name={`${name}.${subKey}`}
              field={subField}
              value={value?.[subKey]}
              onChange={(newVal) => {
                const updated = { ...(value || {}), [subKey]: newVal };
                onChange(updated);
              }}
              disabled={disabled}
              uploadFile={uploadFile}
              uploading={uploading}
              baseUrl={baseUrl}
              relationDataMap={relationDataMap}
            />
          ))}
        </Box>
      </Box>
    );
  }

  // 2. Relation Handling (Select / Multi-Select)
  if (field.relation && relationDataMap[field.relation]) {
    const relationData = relationDataMap[field.relation].data;
    const isArrayRelation = field.type === 'array';
    const options = getFieldOptions(field, relationData);
    const keyField = field.enumOption?.key ?? 'id';

    // Normalize value: API returns whole objects on GET, but form uses key strings
    const normalizedValue = (() => {
      if (isArrayRelation && Array.isArray(value)) {
        return value.map((v: any) => (v != null && typeof v === 'object' ? String(v[keyField] ?? '') : String(v)));
      }
      if (value != null && typeof value === 'object') {
        return String(value[keyField] ?? '');
      }
      return value ?? (isArrayRelation ? [] : "");
    })();

    return (
      <FormControl fullWidth>
        <InputLabel shrink>{label}</InputLabel>
        <Select
          multiple={isArrayRelation}
          value={normalizedValue}
          label={label}
          displayEmpty
          onChange={(e) => onChange(e.target.value)}
          disabled={disabled}
          renderValue={(selected: any) => {
            if (isArrayRelation) {
              return (selected as string[]).map(k => options.find(o => o.key === k)?.value ?? k).join(', ');
            }
            return options.find(o => o.key === selected)?.value ?? selected;
          }}
        >
          {options.map((opt) => (
            <MenuItem key={opt.key} value={opt.key}>
              {opt.value}
            </MenuItem>
          ))}
        </Select>
      </FormControl>
    );
  }

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

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

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

  // 6. Common Text Fields
  if (field.type === 'datetime' || field.type === 'date') {
    return (
      <TextField
        fullWidth
        label={label}
        type={field.type === 'datetime' ? "datetime-local" : "date"}
        InputLabelProps={{ shrink: true }}
        value={value ? new Date(value).toISOString().slice(0, field.type === 'datetime' ? 16 : 10) : ''}
        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 === undefined || value === null ? '' : value}
        onChange={(e) => onChange(e.target.value === '' ? '' : Number(e.target.value))}
        disabled={disabled}
        required={field.required}
      />
    );
  }

  return (
    <TextField
      fullWidth
      label={label}
      value={typeof value === 'object' ? JSON.stringify(value) : value || ''}
      disabled
    />
  );
}
