import React, { useState } from 'react';
import { View, Alert, ScrollView } from 'react-native';
import { useMutation } from '@tanstack/react-query';
import { Formik } from 'formik';
import * as Yup from 'yup';
import * as Location from 'expo-location';
import { tw, MyText, MyTouchableOpacity , Checkbox , MyTextInput , LoadingDialog } from 'common-ui';
import { trpc } from '../trpc-client';

interface AddressFormProps {
  onSuccess: () => void;
  initialValues?: {
    id?: number;
    name: string;
    phone: string;
    addressLine1: string;
    addressLine2: string;
    city: string;
    state: string;
    pincode: string;
    isDefault: boolean;
    latitude?: number;
    longitude?: number;
    googleMapsLocation?: string;
  };
  isEdit?: boolean;
}

const AddressForm: React.FC<AddressFormProps> = ({ onSuccess, initialValues, isEdit = false }) => {
  const [locationLoading, setLocationLoading] = useState(false);
  const [locationError, setLocationError] = useState<string | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [showGoogleMapsField, setShowGoogleMapsField] = useState(false);
  const [currentLocation, setCurrentLocation] = useState<{ latitude: number; longitude: number } | null>(
    initialValues?.latitude && initialValues?.longitude
      ? { latitude: initialValues.latitude, longitude: initialValues.longitude }
      : null
  );

  const createAddressMutation = trpc.user.address.createAddress.useMutation({
    onSuccess: () => {
      setIsSubmitting(false);
      setTimeout(() => onSuccess(), 100);
    },
    onError: (error: any) => {
      setIsSubmitting(false);
      Alert.alert('Error', error.message || 'Failed to save address');
    },
  });

  const updateAddressMutation = trpc.user.address.updateAddress.useMutation({
    onSuccess: () => {
      setIsSubmitting(false);
      setTimeout(() => onSuccess(), 100);
    },
    onError: (error: any) => {
      setIsSubmitting(false);
      Alert.alert('Error', error.message || 'Failed to update address');
    },
  });

  const attachCurrentLocation = async () => {
    setLocationLoading(true);
    setLocationError(null);

    try {
      const { status } = await Location.requestForegroundPermissionsAsync();

      if (status !== 'granted') {
        setLocationError('Location Permission denied');
        return;
      }

      const location = await Location.getCurrentPositionAsync({
        accuracy: Location.Accuracy.High,
      });

      const { latitude, longitude } = location.coords;
      setCurrentLocation({ latitude, longitude });
    } catch (error) {
      console.error('Location error:', error);
      setLocationError('Unable to fetch location. Please check your GPS settings.');
    } finally {
      setLocationLoading(false);
    }
  };

  const validationSchema = Yup.object({
    name: Yup.string().required('Name is required'),
    phone: Yup.string().required('Phone is required').matches(/^\d{10}$/, 'Phone must be 10 digits'),
    addressLine1: Yup.string().required('Address Line 1 is required'),
    addressLine2: Yup.string(),
    city: Yup.string().required('City is required'),
    state: Yup.string().required('State is required'),
    pincode: Yup.string().required('Pincode is required').matches(/^\d{6}$/, 'Pincode must be 6 digits'),
    isDefault: Yup.boolean(),
  });

  return (
    <ScrollView style={tw`p-4`}>
      <MyText style={tw`text-xl font-bold mb-4`}>{isEdit ? 'Edit Address' : 'Add Address'}</MyText>
      <Formik
        initialValues={initialValues || {
          name: '',
          phone: '',
          addressLine1: '',
          addressLine2: '',
          city: 'Mahabubnagar',
          state: 'Telangana',
          pincode: '509001',
          isDefault: false,
          latitude: undefined,
          longitude: undefined,
          googleMapsLocation: '',
        }}
        validationSchema={validationSchema}
        onSubmit={(values) => {
           setIsSubmitting(true);
           const payload = {
             ...values,
             latitude: currentLocation?.latitude,
             longitude: currentLocation?.longitude,
             googleMapsLocation: values.googleMapsLocation || undefined,
           };
           if (isEdit && initialValues?.id) {
             updateAddressMutation.mutate({ id: initialValues.id, ...payload });
           } else {
             createAddressMutation.mutate(payload);
           }
         }}
      >
        {({ handleChange, handleBlur, handleSubmit, values, errors, touched, setFieldValue }) => (
          <View style={tw`flex-col gap-2`}>
            <MyTextInput
              placeholder="Name"
              shrunkPadding={true}
              onChangeText={handleChange('name')}
              onBlur={handleBlur('name')}
              value={values.name}
            />
            {touched.name && errors.name && <MyText style={tw`text-red-500 mb-2`}>{errors.name}</MyText>}

            <MyTextInput
              placeholder="Phone"
              shrunkPadding={true}
              keyboardType="phone-pad"
              onChangeText={handleChange('phone')}
              onBlur={handleBlur('phone')}
              value={values.phone}
            />
            {touched.phone && errors.phone && <MyText style={tw`text-red-500 mb-2`}>{errors.phone}</MyText>}

            <MyTextInput
              placeholder="Address Line 1"
              shrunkPadding={true}
              onChangeText={handleChange('addressLine1')}
              onBlur={handleBlur('addressLine1')}
              value={values.addressLine1}
            />
            {touched.addressLine1 && errors.addressLine1 && <MyText style={tw`text-red-500 mb-2`}>{errors.addressLine1}</MyText>}

            <MyTextInput
              placeholder="Address Line 2 (Optional)"
              shrunkPadding={true}
              onChangeText={handleChange('addressLine2')}
              onBlur={handleBlur('addressLine2')}
              value={values.addressLine2}
            />

            <MyTextInput
              placeholder="City"
              shrunkPadding={true}
              onChangeText={handleChange('city')}
              onBlur={handleBlur('city')}
              value={values.city}
              disabled={true}
            />
            {touched.city && errors.city && <MyText style={tw`text-red-500 mb-2`}>{errors.city}</MyText>}

            <MyTextInput
              placeholder="State"
              shrunkPadding={true}
              onChangeText={handleChange('state')}
              onBlur={handleBlur('state')}
              value={values.state}
              disabled={true}
            />
            {touched.state && errors.state && <MyText style={tw`text-red-500 mb-2`}>{errors.state}</MyText>}

            <MyTextInput
              placeholder="Pincode"
              shrunkPadding={true}
              keyboardType="numeric"
              onChangeText={handleChange('pincode')}
              onBlur={handleBlur('pincode')}
              value={values.pincode}
              disabled={true}
            />
            {touched.pincode && errors.pincode && <MyText style={tw`text-red-500 mb-2`}>{errors.pincode}</MyText>}

            {locationLoading ? (
              <MyText style={tw`text-blue-500 text-sm mb-2`}>Fetching location...</MyText>
            ) : locationError ? (
              <MyText style={tw`text-red-500 text-sm mb-2`}>{locationError}</MyText>
            ) : currentLocation ? (
              <View style={tw`flex-row items-center mb-4`}>
                <MyText style={tw`text-green-600 text-sm font-medium`}>Current Location Attached</MyText>
                <MyTouchableOpacity
                  onPress={() => attachCurrentLocation()}
                  disabled={locationLoading}
                  style={tw`ml-4`}
                >
                  <MyText style={tw`text-blue-500 text-sm font-medium`}>Change</MyText>
                </MyTouchableOpacity>
              </View>
            ) : (
              <MyTouchableOpacity
                onPress={() => attachCurrentLocation()}
                disabled={locationLoading}
                style={tw`mb-4`}
              >
                <MyText style={tw`text-blue-500 text-sm font-medium`}>
                  Attach Current Location
                </MyText>
              </MyTouchableOpacity>
            )}

            <MyTouchableOpacity
              onPress={() => setShowGoogleMapsField(true)}
              disabled={false}
              style={tw`mb-1`}
            >
              <MyText style={tw`text-blue-500 text-sm font-medium`}>
                Attach with Google Maps
              </MyText>
            </MyTouchableOpacity>

            {showGoogleMapsField && (
              <View style={tw`mb-2`}>
                <MyText style={tw`text-gray-500 text-xs mb-2`}>
                  1. Open Google Maps and Find location{'\n'}
                  2. Long press the desired location{'\n'}
                  3. Click on Share and Click on Copy{'\n'}
                  4. Paste the copied url here in the field.
                </MyText>
                <MyTextInput
                  placeholder="Google Maps Shared URL"
                  shrunkPadding={true}
                  onChangeText={handleChange('googleMapsLocation')}
                  onBlur={handleBlur('googleMapsLocation')}
                  value={values.googleMapsLocation}
                />
              </View>
            )}

            <View style={tw`flex-row items-center mb-4`}>
              <Checkbox
                checked={values.isDefault}
                onPress={() => setFieldValue('isDefault', !values.isDefault)}
              />
              <MyText style={tw`ml-2`}>Set as default address</MyText>
            </View>

            <MyTouchableOpacity
              style={tw`bg-indigo-600 p-3 rounded ${isSubmitting ? 'opacity-50' : ''}`}
              onPress={() => handleSubmit()}
              disabled={isSubmitting}
            >
              <MyText style={tw`text-white text-center font-bold`}>
                {isSubmitting ? (isEdit ? 'Updating...' : 'Adding...') : (isEdit ? 'Update Address' : 'Add Address')}
              </MyText>
            </MyTouchableOpacity>
          </View>
        )}
      </Formik>

      <LoadingDialog
        open={isSubmitting}
        message={isEdit ? "Updating address..." : "Adding address..."}
      />
    </ScrollView>
  );
};

export default AddressForm;