import React, { useEffect } from 'react';
import {
  Paper,
  TextInput,
  Select,
  MultiSelect,
  NumberInput,
  Textarea,
  JsonInput,
  Button,
  Group,
  Stack,
  Title,
  ActionIcon,
  ScrollArea,
  Box,
  Text,
} from '@mantine/core';
import { IconX } from '@tabler/icons-react';
import { useForm } from '@mantine/form';
import { notifications } from '@mantine/notifications';
import { FormField, NotificationConfig } from '../../types';

export interface FormSidebarProps {
  opened: boolean;
  onClose: () => void;
  onSuccess: () => void;
  title: string;
  editMode?: boolean;
  editItem?: any;
  fields: FormField[];
  onSubmit: (values: any) => Promise<void>;
  width?: number;
  initialValues?: Record<string, any>;
  validateOnSubmit?: boolean;
}

const FormSidebar: React.FC<FormSidebarProps> = ({
  opened,
  onClose,
  onSuccess,
  title,
  editMode = false,
  editItem,
  fields,
  onSubmit,
  width = 450,
  initialValues = {},
  validateOnSubmit = true,
}) => {
  const isEditing = editMode && !!editItem;

  // Build initial form values from fields
  const buildInitialValues = () => {
    const values: Record<string, any> = {};
    fields.forEach(field => {
      values[field.name] = field.defaultValue ?? (field.type === 'multiselect' ? [] : '');
    });
    return { ...values, ...initialValues };
  };

  // Build validation rules from fields
  const buildValidation = () => {
    const validation: Record<string, (value: any) => string | null> = {};
    fields.forEach(field => {
      validation[field.name] = (value: any) => {
        if (field.required && (!value || (typeof value === 'string' && value.trim() === ''))) {
          return `${field.label} is required`;
        }
        if (field.validation?.email && value && !/^\S+@\S+$/.test(value)) {
          return 'Invalid email format';
        }
        if (field.validation?.url && value && !/^https?:\/\/.+/.test(value)) {
          return 'Invalid URL format';
        }
        if (field.validation?.minLength && value && value.length < field.validation.minLength) {
          return `${field.label} must be at least ${field.validation.minLength} characters`;
        }
        if (field.validation?.maxLength && value && value.length > field.validation.maxLength) {
          return `${field.label} must be no more than ${field.validation.maxLength} characters`;
        }
        if (field.validation?.pattern && value && !field.validation.pattern.test(value)) {
          return `${field.label} format is invalid`;
        }
        if (field.validation?.custom) {
          return field.validation.custom(value);
        }
        return null;
      };
    });
    return validation;
  };

  const form = useForm({
    initialValues: buildInitialValues(),
    validate: buildValidation(),
  });

  // Update form values when editItem changes
  useEffect(() => {
    if (isEditing && editItem) {
      const updatedValues: Record<string, any> = {};
      fields.forEach(field => {
        updatedValues[field.name] = editItem[field.name] ?? field.defaultValue ?? '';
      });
      form.setValues(updatedValues);
    } else if (!isEditing) {
      form.setValues(buildInitialValues());
    }
  }, [editItem, opened, isEditing]);

  const handleSubmit = async (values: typeof form.values) => {
    try {
      await onSubmit(values);
      
      const successNotification: NotificationConfig = {
        title: 'Success',
        message: `${title} ${isEditing ? 'updated' : 'created'} successfully`,
        color: 'green',
      };
      
      notifications.show(successNotification);
      onSuccess();
      onClose();
      form.reset();
    } catch (error: any) {
      console.error(`Error ${isEditing ? 'updating' : 'creating'} ${title.toLowerCase()}:`, error);
      
      const errorNotification: NotificationConfig = {
        title: 'Error',
        message: error.message || `Failed to ${isEditing ? 'update' : 'create'} ${title.toLowerCase()}`,
        color: 'red',
      };
      
      notifications.show(errorNotification);
    }
  };

  const renderField = (field: FormField) => {
    const inputProps = form.getInputProps(field.name);
    const commonProps = {
      key: field.name,
      label: field.label,
      placeholder: field.placeholder,
      description: field.description,
      required: field.required,
      disabled: field.disabled || (isEditing && field.name === 'id'),
      ...inputProps,
    };

    switch (field.type) {
      case 'email':
        return <TextInput {...commonProps} type="email" />;
      
      case 'number':
        return <NumberInput {...commonProps} />;
      
      case 'textarea':
        return <Textarea {...commonProps} autosize minRows={3} maxRows={6} />;
      
      case 'select':
        return (
          <Select
            {...commonProps}
            data={field.options || []}
          />
        );
      
      case 'multiselect':
        return (
          <MultiSelect
            {...commonProps}
            data={field.options || []}
          />
        );
      
      case 'json':
        return (
          <JsonInput
            {...commonProps}
            validationError="Invalid JSON format"
            formatOnBlur
            autosize
            minRows={3}
          />
        );
      
      default:
        return <TextInput {...commonProps} />;
    }
  };

  return (
    <Paper
      style={{
        position: 'fixed',
        top: 60,
        right: opened ? 0 : `-${width}px`,
        bottom: 0,
        width: `${width}px`,
        zIndex: 1000,
        borderRadius: 0,
        display: 'flex',
        flexDirection: 'column',
        borderLeft: '1px solid var(--mantine-color-gray-3)',
        backgroundColor: 'var(--mantine-color-body)',
        transition: 'right 0.3s ease',
      }}
    >
      {/* Header */}
      <Group justify="space-between" p="md" style={{ borderBottom: '1px solid var(--mantine-color-gray-3)' }}>
        <Title order={4}>
          {isEditing ? `Edit ${title}` : `Create New ${title}`}
        </Title>
        <ActionIcon
          variant="subtle"
          color="gray"
          onClick={onClose}
        >
          <IconX size={18} />
        </ActionIcon>
      </Group>

      {/* Content */}
      <ScrollArea style={{ flex: 1 }}>
        <Box p="md">
          <form onSubmit={form.onSubmit(handleSubmit)}>
            <Stack gap="md">
              {fields.map(renderField)}

              <Group justify="flex-end" mt="md">
                <Button variant="light" onClick={onClose}>
                  Cancel
                </Button>
                <Button type="submit">
                  {isEditing ? 'Update' : 'Create'} {title}
                </Button>
              </Group>
            </Stack>
          </form>
        </Box>
      </ScrollArea>
    </Paper>
  );
};

export default FormSidebar;