import React, { forwardRef, useState, useEffect, useMemo } from 'react';
import { View, TouchableOpacity, Alert } from 'react-native';
import { Formik } from 'formik';
import * as Yup from 'yup';
import { MyTextInput, BottomDropdown, MyText, tw, ImageUploaderNeo } from 'common-ui';
import ProductsSelector from './ProductsSelector';
import { trpc } from '../src/trpc-client';
import usePickImage from 'common-ui/src/components/use-pick-image';
import { useUploadToObjectStorage } from '../hooks/useUploadToObjectStorage';

export interface StoreFormData {
  name: string;
  description: string;
  imageUrl?: string;
  owner: number;
  products: number[];
}

interface StoreImage {
  uri: string;
  mimeType: string;
  isExisting: boolean;
}

export interface StoreFormRef {
  // Add methods if needed
}

interface StoreFormProps {
  mode: 'create' | 'edit';
  initialValues: StoreFormData;
  onSubmit: (values: StoreFormData) => void;
  isLoading: boolean;
  storeId?: number;
}

// Extend Formik values with images array
interface FormikStoreValues extends StoreFormData {
  images: StoreImage[];
}

const validationSchema = Yup.object().shape({
  name: Yup.string().required('Name is required'),
  description: Yup.string(),
  imageUrl: Yup.string(),
  owner: Yup.number().required('Owner is required'),
  products: Yup.array().of(Yup.number()),
});

const StoreForm = forwardRef<StoreFormRef, StoreFormProps>((props, ref) => {
  const { mode, initialValues, onSubmit, isLoading, storeId } = props;
  const { data: staffData } = trpc.admin.staffUser.getStaff.useQuery();
  const { data: productsData } = trpc.admin.product.getProducts.useQuery();

  // Build initial form values with images array
  const buildInitialValues = (): FormikStoreValues => {
    const images: StoreImage[] = [];
    if (initialValues.imageUrl) {
      images.push({
        uri: initialValues.imageUrl,
        mimeType: 'image/jpeg',
        isExisting: true,
      });
    }
    return {
      ...initialValues,
      images,
    };
  };

  const [formInitialValues, setFormInitialValues] = useState<FormikStoreValues>(buildInitialValues());

  // For edit mode, pre-select products belonging to this store
  const initialSelectedProducts = useMemo(() => {
    if (mode !== 'edit' || !productsData?.products) return [];
    return productsData.products
      .filter(p => p.storeId === storeId)
      .map(p => p.id);
  }, [mode, productsData?.products, storeId]);

  useEffect(() => {
    setFormInitialValues({
      ...buildInitialValues(),
      products: initialSelectedProducts,
    });
  }, [initialValues, initialSelectedProducts]);

  const staffOptions = staffData?.staff.map(staff => ({
    label: staff.name,
    value: staff.id,
  })) || [];

  const { uploadSingle, isUploading } = useUploadToObjectStorage();

  return (
    <Formik
      initialValues={formInitialValues}
      validationSchema={validationSchema}
      onSubmit={onSubmit}
      enableReinitialize
    >
      {({ handleChange, handleSubmit, values, setFieldValue, errors, touched }) => {
        // Image picker that adds to Formik field
        const handleImagePick = usePickImage({
          setFile: async (assets: any) => {
            if (!assets || (Array.isArray(assets) && assets.length === 0)) {
              return;
            }

            const files = Array.isArray(assets) ? assets : [assets];
            const newImages: StoreImage[] = files.map((asset) => ({
              uri: asset.uri,
              mimeType: asset.mimeType || 'image/jpeg',
              isExisting: false,
            }));

            // Add to Formik images field
            const currentImages = values.images || [];
            setFieldValue('images', [...currentImages, ...newImages]);
          },
          multiple: false,
        });

        // Remove image - works for both existing and new
        const handleRemoveImage = (image: { uri: string; mimeType: string }) => {
          const currentImages = values.images || [];
          const removedImage = currentImages.find(img => img.uri === image.uri);
          const newImages = currentImages.filter(img => img.uri !== image.uri);
          
          setFieldValue('images', newImages);
          
          // If we removed an existing image, also clear the imageUrl
          if (removedImage?.isExisting) {
            setFieldValue('imageUrl', undefined);
          }
        };

        const submit = async () => {
          try {
            let imageUrl: string | undefined;

            // Get new images that need to be uploaded
            const newImages = values.images.filter(img => !img.isExisting);

            if (newImages.length > 0) {
              // Upload the first new image (single image for stores)
              const image = newImages[0];
              const response = await fetch(image.uri);
              const imageBlob = await response.blob();
              const { key } = await uploadSingle(imageBlob, image.mimeType, 'store');
              imageUrl = key;
            } else {
              // Check if there's an existing image remaining
              const existingImage = values.images.find(img => img.isExisting);
              if (existingImage) {
                imageUrl = existingImage.uri;
              }
            }

            // Submit form with imageUrl (without images array)
            const { images, ...submitValues } = values;
            onSubmit({ ...submitValues, imageUrl });
          } catch (error) {
            console.error('Upload error:', error);
            Alert.alert('Error', error instanceof Error ? error.message : 'Failed to upload image');
          }
        };

        // Prepare images for ImageUploaderNeo (convert to expected format)
        const imagesForUploader = (values.images || []).map(img => ({
          uri: img.uri,
          mimeType: img.mimeType,
        }));

        return (
          <View>
            <MyTextInput
              topLabel="Store Name"
              placeholder="Enter store name"
              value={values.name}
              onChangeText={handleChange('name')}
              error={!!(touched.name && errors.name)}
              style={{ marginBottom: 16 }}
            />
            <MyTextInput
              topLabel="Description"
              placeholder="Enter store description"
              multiline
              numberOfLines={3}
              value={values.description}
              onChangeText={handleChange('description')}
              error={!!(touched.description && errors.description)}
              style={{ marginBottom: 16 }}
            />
            <BottomDropdown
              label="Owner"
              value={values.owner}
              options={staffOptions}
              onValueChange={(value) => setFieldValue('owner', value)}
              placeholder="Select owner"
              error={!!(touched.owner && errors.owner)}
              style={{ marginBottom: 16 }}
            />
            <ProductsSelector
              value={values.products || []}
              onChange={(value) => setFieldValue('products', value)}
              multiple={true}
              label="Products"
              placeholder="Select products"
              isDisabled={(product) => product.storeId !== null && product.storeId !== storeId}
              labelFormat={(product) => `${product.name} - ₹${product.price}`}
            />
            <View style={tw`mb-6`}>
              <MyText style={tw`text-sm font-bold text-gray-700 mb-3 uppercase tracking-wider`}>Store Image</MyText>
              
              <ImageUploaderNeo
                images={imagesForUploader}
                onUploadImage={handleImagePick}
                onRemoveImage={handleRemoveImage}
                allowMultiple={false}
              />
            </View>
            <TouchableOpacity
              onPress={submit}
              disabled={isLoading || isUploading}
              style={tw`px-4 py-2 rounded-lg shadow-lg items-center mt-2 ${isLoading || isUploading ? 'bg-gray-400' : 'bg-blue-500'}`}
            >
              <MyText style={tw`text-white text-lg font-bold`}>
                {isUploading ? 'Uploading...' : isLoading ? (mode === 'create' ? 'Creating...' : 'Updating...') : (mode === 'create' ? 'Create Store' : 'Update Store')}
              </MyText>
            </TouchableOpacity>
          </View>
        );
      }}
    </Formik>
  );
});

StoreForm.displayName = 'StoreForm';

export default StoreForm;
