import React, { useState, useMemo } from 'react';
import { View } from 'react-native';
import BottomDropdown, { DropdownOption } from 'common-ui/src/components/bottom-dropdown';
import { trpc } from '../src/trpc-client';
import { tw } from 'common-ui';

interface Product {
  id: number;
  name: string;
  price: number;
  unit?: string;
  shortDescription?: string | null;
  isOutOfStock?: boolean;
  isSuspended?: boolean;
  storeId?: number | null;
  unitNotation?: string;
}

interface Group {
  id: number;
  groupName: string;
  products: Product[];
}

interface ProductsSelectorProps {
  value: number | number[];
  onChange: (value: number | number[]) => void;
  multiple?: boolean;
  label?: string;
  placeholder?: string;
  disabled?: boolean;
  error?: boolean;
  isDisabled?: (product: Product) => boolean;
  labelFormat?: (product: Product) => string;
  groups?: Group[];
  selectedGroupIds?: number[];
  onGroupChange?: (groupIds: number[]) => void;
  showGroups?: boolean;
}

export default function ProductsSelector({
  value,
  onChange,
  multiple = true,
  label = 'Select Products',
  placeholder = 'Select products',
  disabled = false,
  error = false,
  isDisabled,
  labelFormat,
  groups = [],
  showGroups = true,
  selectedGroupIds = [],
  onGroupChange,
}: ProductsSelectorProps) {
  const { data: productsData } = trpc.common.product.getAllProductsSummary.useQuery({});
  const products = productsData?.products || [];
  const [searchQuery, setSearchQuery] = useState('');

  // Format product label: name (unit) (₹price)
  const formatProductLabel = (product: Product): string => {
    if (labelFormat) {
      return labelFormat(product);
    }
    const unit = product.unit ? ` (${product.unit})` : '';
    const price = ` (₹${product.price})`;
    return `${product.name}${unit}${price}`;
  };

  // Handle group selection changes
  const handleGroupChange = (newGroupIds: number[]) => {
    if (!onGroupChange) return;

    const previousGroupIds = selectedGroupIds;
    
    // Find which groups were added and which were removed
    const addedGroups = newGroupIds.filter(id => !previousGroupIds.includes(id));
    const removedGroups = previousGroupIds.filter(id => !newGroupIds.includes(id));

    // Get current selected products
    let currentProducts = Array.isArray(value) ? [...value] : value ? [value] : [];

    // Add products from newly selected groups
    const addedProducts = addedGroups.flatMap(groupId => {
      const group = groups.find(g => g.id === groupId);
      return group?.products.map(p => p.id) || [];
    });

    // Remove products from deselected groups
    const removedProducts = removedGroups.flatMap(groupId => {
      const group = groups.find(g => g.id === groupId);
      return group?.products.map(p => p.id) || [];
    });

    // Update product list: add new ones, remove deselected group ones
    currentProducts = [...new Set([...currentProducts, ...addedProducts])];
    currentProducts = currentProducts.filter(id => !removedProducts.includes(id));

    onGroupChange(newGroupIds);
    if (multiple) {
      onChange(currentProducts.length > 0 ? currentProducts : []);
    } else {
      onChange(currentProducts.length > 0 ? currentProducts[0] : 0);
    }
  };

  // Filter products based on search query
  const filteredProducts = useMemo(() => {
    if (!searchQuery.trim()) return products;
    
    const query = searchQuery.toLowerCase();
    return products.filter(product => 
      product.name.toLowerCase().includes(query) ||
      (product.shortDescription && product.shortDescription.toLowerCase().includes(query)) ||
      (product.unit && product.unit.toLowerCase().includes(query))
    );
  }, [products, searchQuery]);

  // Build dropdown options
  const productOptions: DropdownOption[] = useMemo(() => {
    return filteredProducts.map((product) => {
      const isFromGroup = selectedGroupIds.length > 0 && groups.some(group => 
        selectedGroupIds.includes(group.id) && group.products.some(p => p.id === product.id)
      );
      
      const isProductDisabled = isDisabled ? isDisabled(product as Product) : false;
      
      return {
        label: `${formatProductLabel(product as Product)}${isFromGroup ? ' (from group)' : ''}`,
        value: product.id.toString(),
        disabled: isProductDisabled,
      };
    });
  }, [filteredProducts, selectedGroupIds, groups, isDisabled, labelFormat]);

  // Build group options if groups are provided
  const groupOptions: DropdownOption[] = useMemo(() => {
    return groups.map(group => ({
      label: group.groupName,
      value: group.id.toString(),
    }));
  }, [groups]);

  return (
    <View style={tw`w-full`}>
      {/* Groups selector (if groups are provided and showGroups is true) */}
      {showGroups && groups.length > 0 && (
        <View style={tw`mb-4`}>
          <BottomDropdown
            testID="product-groups-dropdown"
            label="Select Product Groups"
            options={groupOptions}
            value={selectedGroupIds.map(id => id.toString())}
            onValueChange={(value) => {
              const selectedValues = Array.isArray(value) ? value : typeof value === 'string' ? [value] : [];
              const newGroupIds = selectedValues.map(v => parseInt(v as string));
              handleGroupChange(newGroupIds);
            }}
            placeholder="Select product groups (optional)"
            multiple={true}
          />
        </View>
      )}

      {/* Products selector */}
      <BottomDropdown
        label={label}
        options={productOptions}
        value={multiple 
          ? (Array.isArray(value) ? value.map(id => id.toString()) : [])
          : (value ? value.toString() : '')
        }
        onValueChange={(selectedValue) => {
          if (multiple) {
            const selectedValues = Array.isArray(selectedValue) ? selectedValue : typeof selectedValue === 'string' ? [selectedValue] : [];
            onChange(selectedValues.map(v => Number(v)));
          } else {
            onChange(Number(selectedValue));
          }
        }}
        placeholder={placeholder}
        multiple={multiple}
        disabled={disabled}
        error={error}
        onSearch={setSearchQuery}
      />
    </View>
  );
}
