/**
 * SearchableTemplateSelect Component
 *
 * A template dropdown with brand filtering and search.
 * Ported from ValidationStepNew with updated imports for the new store types.
 */

import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { Button } from '@/components/ui/button';
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
} from '@/components/ui/command';
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover';
import { ScrollArea } from '@/components/ui/scroll-area';
import { cn } from '@/lib/utils';
import { Check, ChevronsUpDown } from 'lucide-react';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import type { Template } from '../store/types';

interface SearchableTemplateSelectProps {
  templates: Template[] | undefined;
  value: string;
  onValueChange: (value: string) => void;
  getTemplateDisplayText: (templateId: string | null) => string;
  placeholder?: string;
  className?: string;
  triggerClassName?: string;
  defaultBrand?: string;
  disabled?: boolean;
}

const SearchableTemplateSelect: React.FC<SearchableTemplateSelectProps> = ({
  templates = [],
  value,
  onValueChange,
  getTemplateDisplayText,
  placeholder = 'Select template',
  className,
  triggerClassName,
  defaultBrand,
  disabled = false,
}) => {
  const [searchTerm, setSearchTerm] = useState('');
  const [selectedBrand, setSelectedBrand] = useState<string | null>(null);
  const [open, setOpen] = useState(false);

  // Set default brand when component mounts or defaultBrand changes
  useEffect(() => {
    if (defaultBrand) {
      setSelectedBrand(defaultBrand);
    }
  }, [defaultBrand]);

  // Force a re-render when templates change from empty to non-empty
  useEffect(() => {
    if (templates && templates.length > 0) {
      setSearchTerm('');
    }
  }, [templates]);

  // Handle wheel events for scrolling
  const handleWheel = (e: React.WheelEvent) => {
    const scrollArea = e.currentTarget;
    scrollArea.scrollTop += e.deltaY;
  };

  // Extract unique brands from templates
  const brands = useMemo(() => {
    try {
      if (!Array.isArray(templates) || templates.length === 0) {
        return [];
      }

      const brandSet = new Set<string>();
      const brandNames: { id: string; name: string }[] = [];

      templates.forEach((template) => {
        if (!template?.company) return;

        const companyId = template.company;
        if (!brandSet.has(companyId)) {
          brandSet.add(companyId);

          // Try to get the company name from the template display text
          try {
            const displayText = getTemplateDisplayText(template.id.toString());
            const companyName = displayText.split(' - ')[0];
            brandNames.push({ id: companyId, name: companyName || companyId });
          } catch (err) {
            brandNames.push({ id: companyId, name: companyId });
          }
        }
      });

      return brandNames.sort((a, b) => a.name.localeCompare(b.name));
    } catch (err) {
      return [];
    }
  }, [templates, getTemplateDisplayText]);

  // Group templates by company for better organization
  const groupedTemplates = useMemo(() => {
    try {
      if (!Array.isArray(templates) || templates.length === 0) return {};

      const groups: Record<string, Template[]> = {};

      templates.forEach((template) => {
        if (!template?.company) return;

        const companyId = template.company;
        if (!groups[companyId]) {
          groups[companyId] = [];
        }
        groups[companyId].push(template);
      });

      return groups;
    } catch (err) {
      return {};
    }
  }, [templates]);

  // Filter templates based on selected brand and search term
  const filteredTemplates = useMemo(() => {
    try {
      if (!Array.isArray(templates) || templates.length === 0) return [];

      // First filter by brand if selected
      let brandFiltered = templates;
      if (selectedBrand) {
        // Check if the selected brand has any templates
        const brandTemplates = templates.filter((t) => t?.company === selectedBrand);

        // If the selected brand has templates, use them; otherwise, show all templates
        brandFiltered = brandTemplates.length > 0 ? brandTemplates : templates;
      }

      // Then filter by search term if provided
      if (!searchTerm.trim()) return brandFiltered;

      const lowerSearchTerm = searchTerm.toLowerCase();
      return brandFiltered.filter((template) => {
        if (!template?.id) return false;
        try {
          const displayText = getTemplateDisplayText(template.id.toString());
          const productType = template.product_type?.toLowerCase() || '';

          return displayText.toLowerCase().includes(lowerSearchTerm) || productType.includes(lowerSearchTerm);
        } catch (error) {
          return false;
        }
      });
    } catch (err) {
      return [];
    }
  }, [templates, selectedBrand, searchTerm, getTemplateDisplayText]);

  // Handle errors gracefully
  const getDisplayText = useCallback(() => {
    try {
      if (!value) return placeholder;
      const template = templates.find((t) => t.id.toString() === value);
      if (!template) return placeholder;

      // Get the original display text
      const originalText = getTemplateDisplayText(value);

      // Check if it has the expected format "Brand - Product Type"
      if (originalText.includes(' - ')) {
        const [brand, productType] = originalText.split(' - ', 2);
        // Reverse the order to "Product Type - Brand"
        return `${productType} - ${brand}`;
      }

      // If it doesn't match the expected format, return the original text
      return originalText;
    } catch (err) {
      console.error('Error getting display text:', err);
      return placeholder;
    }
  }, [getTemplateDisplayText, placeholder, value, templates]);

  // Safe render function for CommandItem
  const renderCommandItem = useCallback(
    (template: Template) => {
      if (!template?.id) return null;

      try {
        const displayText = getTemplateDisplayText(template.id.toString());

        return (
          <CommandItem
            key={template.id}
            value={template.id.toString()}
            onSelect={(currentValue) => {
              try {
                onValueChange(currentValue);
                setOpen(false);
                setSearchTerm('');
              } catch (err) {
                console.error('Error selecting template:', err);
              }
            }}
            className="flex items-center justify-between"
          >
            <span>{displayText}</span>
            {value === template.id.toString() && <Check className="h-4 w-4 ml-2" />}
          </CommandItem>
        );
      } catch (err) {
        console.error('Error rendering template item:', err);
        return null;
      }
    },
    [onValueChange, value, getTemplateDisplayText]
  );

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          aria-expanded={open}
          disabled={disabled}
          className={cn('w-full justify-between overflow-hidden', triggerClassName)}
        >
          <span className="truncate overflow-hidden mr-1 text-sm font-normal">{getDisplayText()}</span>
          <ChevronsUpDown className="h-4 w-4 shrink-0 opacity-50 flex-none" />
        </Button>
      </PopoverTrigger>
      <PopoverContent className={cn('w-[300px] p-0', className)}>
        <Command>
          <div className="flex flex-col p-2 gap-2">
            {brands.length > 0 && (
              <div className="flex items-center gap-2">
                <Select
                  value={selectedBrand || 'all'}
                  onValueChange={(value) => {
                    setSelectedBrand(value === 'all' ? null : value);
                  }}
                >
                  <SelectTrigger className="w-full">
                    <SelectValue placeholder="All Brands" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="all">All Brands</SelectItem>
                    {brands.map((brand) => (
                      <SelectItem key={brand.id} value={brand.id}>
                        {brand.name}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
            )}

            <CommandSeparator />

            <div className="flex items-center gap-2">
              <CommandInput
                placeholder="Search by product type..."
                value={searchTerm}
                onValueChange={setSearchTerm}
                className="h-8 flex-1"
              />
            </div>
          </div>

          <CommandEmpty>
            <div className="py-6 text-center">
              <p className="text-sm text-muted-foreground">No templates found.</p>
            </div>
          </CommandEmpty>

          <CommandList>
            <ScrollArea className="max-h-[200px] overflow-y-auto" onWheel={handleWheel}>
              {!searchTerm ? (
                selectedBrand ? (
                  groupedTemplates[selectedBrand]?.length > 0 ? (
                    <CommandGroup heading={brands.find((b) => b.id === selectedBrand)?.name || selectedBrand}>
                      {groupedTemplates[selectedBrand]?.map((template) => renderCommandItem(template))}
                    </CommandGroup>
                  ) : (
                    // If selected brand has no templates, show all brands
                    Object.entries(groupedTemplates).map(([companyId, companyTemplates]) => {
                      const brand = brands.find((b) => b.id === companyId);
                      const companyName = brand ? brand.name : companyId;

                      return (
                        <CommandGroup key={companyId} heading={companyName}>
                          {companyTemplates.map((template) => renderCommandItem(template))}
                        </CommandGroup>
                      );
                    })
                  )
                ) : (
                  Object.entries(groupedTemplates).map(([companyId, companyTemplates]) => {
                    const brand = brands.find((b) => b.id === companyId);
                    const companyName = brand ? brand.name : companyId;

                    return (
                      <CommandGroup key={companyId} heading={companyName}>
                        {companyTemplates.map((template) => renderCommandItem(template))}
                      </CommandGroup>
                    );
                  })
                )
              ) : (
                <CommandGroup>{filteredTemplates.map((template) => renderCommandItem(template))}</CommandGroup>
              )}
            </ScrollArea>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  );
};

export default SearchableTemplateSelect;
