import React, { useState, useEffect, useRef } from 'react';
import { View, Text, TouchableOpacity, ScrollView, Alert } from 'react-native';
import { tw, BottomDialog, RawBottomDialog } from 'common-ui';
import { useQueryClient } from '@tanstack/react-query';
import AddressForm from '@/src/components/AddressForm';
import LocationAttacher from '@/src/components/LocationAttacher';
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
import { trpc } from '@/src/trpc-client';
import { useAuth } from '@/src/contexts/AuthContext';
import * as Location from 'expo-location';

interface AddressSelectorProps {
  selectedAddress: number | null;
  onAddressSelect: (addressId: number) => void;
}

const CheckoutAddressSelector: React.FC<AddressSelectorProps> = ({
  selectedAddress,
  onAddressSelect,
}) => {
  const [showAddAddress, setShowAddAddress] = useState(false);
  const [editingLocationAddressId, setEditingLocationAddressId] = useState<number | null>(null);
  const [locationLoading, setLocationLoading] = useState(false);
  const queryClient = useQueryClient();
  const scrollViewRef = useRef<ScrollView>(null);
  const { isAuthenticated } = useAuth();
  const { data: addresses } = trpc.user.address.getUserAddresses.useQuery(
    undefined,
    { enabled: isAuthenticated }
  );

  const updateAddressMutation = trpc.user.address.updateAddress.useMutation({
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['user.address.getUserAddresses'] });
      setEditingLocationAddressId(null);
      Alert.alert('Success', 'Location attached successfully');
    },
    onError: (error: any) => {
      setEditingLocationAddressId(null);
      Alert.alert('Error', error.message || 'Failed to attach location');
    },
  });

  // Sort addresses with selected first, then default, then others
  const sortedAddresses = React.useMemo(() => {
    if (!addresses?.data) return [];
    return [...addresses.data].sort((a, b) => {
      // Selected address comes first
      if (selectedAddress === a.id && selectedAddress !== b.id) return -1;
      if (selectedAddress === b.id && selectedAddress !== a.id) return 1;

      // Then default address (if not already selected)
      if (a.isDefault && !b.isDefault) return -1;
      if (!a.isDefault && b.isDefault) return 1;

      // Maintain stable sort by id for other addresses
      return a.id - b.id;
    });
  }, [addresses?.data, selectedAddress]);

  // Auto-select default address when addresses are loaded and none is selected
  useEffect(() => {
    if (sortedAddresses.length > 0 && selectedAddress === null) {
      const defaultAddress = sortedAddresses.find(addr => addr.isDefault);
      if (defaultAddress) {
        onAddressSelect(defaultAddress.id);
      }
    }
  }, [sortedAddresses, selectedAddress, onAddressSelect]);

  // Reset scroll to left when address is selected
  const resetScrollToLeft = () => {
    scrollViewRef.current?.scrollTo({ x: 0, y: 0, animated: true });
  };

  const handleAttachLocation = async (address: any) => {
    setEditingLocationAddressId(address.id);
    setLocationLoading(true);
    try {
      const { status } = await Location.requestForegroundPermissionsAsync();

      if (status !== 'granted') {
        Alert.alert('Permission Denied', 'Location permission is required to attach your current location');
        setLocationLoading(false);
        setEditingLocationAddressId(null);
        return;
      }

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

      const { latitude, longitude } = location.coords;

      updateAddressMutation.mutate({
        id: address.id,
        name: address.name,
        phone: address.phone,
        addressLine1: address.addressLine1,
        addressLine2: address.addressLine2 || '',
        city: address.city,
        state: address.state,
        pincode: address.pincode,
        isDefault: address.isDefault,
        latitude,
        longitude,
      });
    } catch (error) {
      Alert.alert('Error', 'Unable to fetch location. Please check your GPS settings.');
      setLocationLoading(false);
      setEditingLocationAddressId(null);
    }
  };

  return (
    <>
      <View style={tw`bg-white p-5 rounded-2xl shadow-sm mb-4 border border-gray-100`}>
        <View style={tw`flex-row justify-between items-center mb-3`}>
          <View style={tw`flex-row items-center`}>
            <View
              style={tw`w-8 h-8 bg-blue-50 rounded-full items-center justify-center mr-3`}
            >
              <MaterialIcons name="location-on" size={18} color="#3B82F6" />
            </View>
            <Text style={tw`text-base font-bold text-gray-900`}>
              Delivery Address
            </Text>
          </View>
          <TouchableOpacity onPress={() => setShowAddAddress(true)}>
            <Text style={tw`text-brand500 font-bold text-sm`}>+ Add New</Text>
          </TouchableOpacity>
        </View>

        {(!sortedAddresses || sortedAddresses.length === 0) ? (
          <View style={tw`bg-gray-50 p-6 rounded-xl border border-gray-200 border-dashed items-center justify-center`}>
            <MaterialIcons name="location-off" size={32} color="#9CA3AF" />
            <Text style={tw`text-gray-500 mt-2`}>No addresses found</Text>
            <TouchableOpacity onPress={() => setShowAddAddress(true)} style={tw`mt-3 bg-brand500 px-4 py-2 rounded-lg`}>
              <Text style={tw`text-white font-bold text-sm`}>Add Address</Text>
            </TouchableOpacity>
          </View>
        ) : (
          <ScrollView
            ref={scrollViewRef}
            horizontal
            showsHorizontalScrollIndicator={false}
            style={tw`pb-2`}
          >
            {sortedAddresses.map((address) => (
              <TouchableOpacity
                key={address.id}
                onPress={() => {
                  onAddressSelect(address.id);
                  resetScrollToLeft();
                }}
                style={tw`w-72 p-4 mr-3 bg-gray-50 rounded-xl border-2 ${selectedAddress === address.id ? 'border-brand500 bg-blue-50' : 'border-gray-200'
                  } shadow-sm`}
              >
                <View style={tw`flex-row justify-between items-start mb-2`}>
                  <View style={tw`flex-row items-center`}>
                    <MaterialIcons
                      name={address.name.toLowerCase().includes('home') ? 'home' : address.name.toLowerCase().includes('work') ? 'work' : 'location-on'}
                      size={20}
                      color={selectedAddress === address.id ? '#EC4899' : '#6B7280'}
                    />
                    <Text style={tw`font-bold ml-2 ${selectedAddress === address.id ? 'text-brand500' : 'text-gray-900'}`}>
                      {address.name}
                    </Text>
                  </View>
                  {selectedAddress === address.id && (
                    <View style={tw`bg-brand500 w-5 h-5 rounded-full items-center justify-center`}>
                      <MaterialIcons name="check" size={14} color="white" />
                    </View>
                  )}
                </View>
                <Text style={tw`text-gray-600 text-sm leading-5 mb-1`} numberOfLines={2}>
                  {address.addressLine1}{address.addressLine2 ? `, ${address.addressLine2}` : ''}
                </Text>
                <Text style={tw`text-gray-600 text-sm mb-1`}>
                  {address.city}, {address.state} - {address.pincode}
                </Text>
                <Text style={tw`text-gray-500 text-xs mt-2`}>
                  Phone: {address.phone}
                </Text>
              </TouchableOpacity>
            ))}
          </ScrollView>
        )}

        {/* Attach Location for selected address - outside the white box */}
        {selectedAddress && (() => {
          const selectedAddr = sortedAddresses.find(a => a.id === selectedAddress);
          return selectedAddr && !selectedAddr.latitude && !selectedAddr.longitude ? (
            <TouchableOpacity
              onPress={() => handleAttachLocation(selectedAddr)}
              disabled={locationLoading && editingLocationAddressId === selectedAddr.id}
              style={tw`mt-3 py-2 px-3 bg-blue-50 rounded-lg self-start`}
            >
              <Text style={tw`text-blue-600 text-sm font-bold`}>
                {locationLoading && editingLocationAddressId === selectedAddr.id ? 'Attaching...' : '+ Attach Current Location'}
              </Text>
            </TouchableOpacity>
          ) : null;
        })()}
      </View>


      {/* <BottomDialog open={showAddAddress} onClose={() => setShowAddAddress(false)}> */}
      <RawBottomDialog open={showAddAddress} onClose={() => setShowAddAddress(false)}>

        <AddressForm
          onSuccess={(addressId) => {
            setShowAddAddress(false);
            // Auto-select the newly added address
            if (addressId) {
              onAddressSelect(addressId);
            }
            queryClient.invalidateQueries();
          }}
        />
      </RawBottomDialog>
      {/* </BottomDialog> */}
    </>
  );
};

export default CheckoutAddressSelector;
