import React from 'react';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { apiClient } from "@/utils/apiClient";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from '@/components/ui/dialog';
import { Textarea } from '@/components/ui/textarea';
import { Loader2, ChevronsUpDown, Check } from 'lucide-react';
import { toast } from 'sonner';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from '@/components/ui/command';
import { cn } from '@/lib/utils';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Label } from '@/components/ui/label';

interface FieldOption {
  label: string;
  value: string;
  type?: number;
  level?: number;
  hexColor?: string;
}

interface FieldOptions {
  companies: FieldOption[];
  artists: FieldOption[];
  sizes: FieldOption[];
  themes: FieldOption[];
  categories: FieldOption[];
  colors: FieldOption[];
  suppliers: FieldOption[];
  taxCategories: FieldOption[];
  shippingRestrictions: FieldOption[];
}

interface TemplateFormData {
  company: string;
  product_type: string;
  supplier?: string;
  msrp?: number;
  cost_each?: number;
  qty_per_unit?: number;
  case_qty?: number;
  hts_code?: string;
  description?: string;
  weight?: number;
  length?: number;
  width?: number;
  height?: number;
  tax_cat?: string;
  size_cat?: string;
  categories?: string[];
  ship_restrictions?: string[];
}

interface TemplateFormProps {
  isOpen: boolean;
  onClose: () => void;
  onSuccess: () => void;
  initialData: TemplateFormData | null;
  mode: 'create' | 'edit' | 'copy';
  templateId?: number;
  fieldOptions: FieldOptions | null;
}

export function TemplateForm({ 
  isOpen, 
  onClose, 
  onSuccess, 
  initialData, 
  mode,
  templateId,
  fieldOptions
}: TemplateFormProps) {
  const defaultFormData = {
    company: "",
    product_type: "",
    supplier: undefined,
    msrp: undefined,
    cost_each: undefined,
    qty_per_unit: undefined,
    case_qty: undefined,
    hts_code: undefined,
    description: undefined,
    weight: undefined,
    length: undefined,
    width: undefined,
    height: undefined,
    tax_cat: "0",
    size_cat: undefined,
    categories: [],
    ship_restrictions: ["0"]
  };

  const [formData, setFormData] = React.useState<TemplateFormData>(defaultFormData);
  const [isSubmitting, setIsSubmitting] = React.useState(false);

  // Reset form data when dialog opens/closes or mode changes
  React.useEffect(() => {
    if (isOpen) {
      if (initialData) {
        console.log('Setting initial form data:', initialData);
        // Format number fields to 2 decimal places if they exist
        const formattedData = {
          ...initialData,
          company: initialData.company || '',  // Ensure company is set
          msrp: initialData.msrp ? Number(Number(initialData.msrp).toFixed(2)) : undefined,
          cost_each: initialData.cost_each ? Number(Number(initialData.cost_each).toFixed(2)) : undefined,
          categories: initialData.categories || []
        };
        console.log('Formatted form data:', formattedData);
        setFormData(formattedData);
      } else {
        setFormData(defaultFormData);
      }
    }
  }, [isOpen, initialData, mode]);

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleTextAreaChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleMultiSelectChange = (name: string, value: string) => {
    setFormData(prev => {
      const currentValues = name === 'categories' 
        ? (prev.categories || [])
        : [];
      const valueSet = new Set(currentValues);

      if (valueSet.has(value)) {
        valueSet.delete(value);
      } else {
        valueSet.add(value);
      }

      return {
        ...prev,
        [name]: Array.from(valueSet),
      };
    });
  };

  const handleSelectChange = (name: string, value: string, closePopover = true) => {
    if (name === 'ship_restrictions') {
      setFormData(prev => ({ ...prev, [name]: [value] }));
    } else {
      setFormData(prev => ({ ...prev, [name]: value }));
    }
    if (closePopover) {
      // Close the popover by blurring the trigger button
      const button = document.activeElement as HTMLElement;
      button?.blur();
    }
  };

  const handleNumberInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const { name, value } = e.target;
    const numValue = value === '' ? undefined : parseFloat(value);
    setFormData(prev => ({ ...prev, [name]: numValue }));
  };

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    setIsSubmitting(true);

    try {
      console.log('Form data before submission:', formData);

      // Validate required fields
      if (!formData.company || !formData.product_type) {
        toast.error('Validation failed', {
          description: 'Company and Product Type are required fields'
        });
        setIsSubmitting(false);
        return;
      }

      // Create a clean copy of form data without undefined values
      const cleanFormData = Object.entries(formData).reduce((acc, [key, value]) => {
        if (value !== undefined && value !== '') {
          // Handle arrays and array-like fields
          if (Array.isArray(value)) {
            // For categories array, always quote values as they are strings
            if (key === 'categories') {
              acc[key] = value.length > 0 ? `{${value.map(v => `"${v}"`).join(',')}}` : '{}';
            } else {
              // For other arrays, don't quote numeric values
              acc[key] = value.length > 0 ? `{${value.join(',')}}` : '{}';
            }
          } else if (key === 'ship_restrictions') {
            // For ship_restrictions, it's already an array so we can format it directly
            if (Array.isArray(value)) {
              acc[key] = value.length > 0 ? `{${value.join(',')}}` : '{}';
            } else {
              // If for some reason it's not an array, convert it
              acc[key] = `{${value}}`;
            }
          } else if (key === 'tax_cat' || key === 'supplier') {
            // Convert these fields to numbers
            acc[key] = Number(value);
          } else {
            acc[key] = value;
          }
        }
        return acc;
      }, {} as Record<string, any>);

      console.log('Clean form data:', cleanFormData);

      // Convert numeric strings to numbers
      const numericFields = ['msrp', 'cost_each', 'qty_per_unit', 'case_qty', 'weight', 'length', 'width', 'height'];
      numericFields.forEach(field => {
        if (cleanFormData[field]) {
          cleanFormData[field] = Number(cleanFormData[field]);
        }
      });

      // Ensure company is a string
      if (cleanFormData.company) {
        cleanFormData.company = String(cleanFormData.company);
      }

      const endpoint = mode === 'edit' ? `/api/templates/${templateId}` : '/api/templates';
      const method = mode === 'edit' ? 'put' : 'post';

      console.log('Sending request to:', endpoint, 'with data:', cleanFormData);

      await apiClient[method](endpoint, cleanFormData);

      toast.success(
        mode === 'edit' ? 'Template updated successfully' : 'Template created successfully'
      );

      onSuccess();
      onClose();
    } catch (error: any) {
      console.error('Error saving template:', error);
      console.error('Error response:', error.response?.data);
      const serverMessage = error.response?.data?.error;
      toast.error(
        error.response?.status === 409
          ? 'Duplicate template'
          : 'Failed to save template',
        {
          description: serverMessage || error.message || 'An unknown error occurred'
        }
      );
    } finally {
      setIsSubmitting(false);
    }
  };

  // Helper function to sort options with selected value at top
  const getSortedOptions = (options: FieldOption[], selectedValue?: string | string[]) => {
    return [...options].sort((a, b) => {
      if (Array.isArray(selectedValue)) {
        const aSelected = selectedValue.includes(String(a.value));
        const bSelected = selectedValue.includes(String(b.value));
        if (aSelected && !bSelected) return -1;
        if (!aSelected && bSelected) return 1;
        return 0;
      }
      if (String(a.value) === String(selectedValue)) return -1;
      if (String(b.value) === String(selectedValue)) return 1;
      return 0;
    });
  };

  // Helper function to get selected category labels
  const getSelectedCategoryLabels = () => {
    if (!formData.categories || !Array.isArray(formData.categories) || !formData.categories.length || !fieldOptions) return "";
    const labels = formData.categories
      .map(value => fieldOptions.categories.find(cat => cat.value === value)?.label)
      .filter(Boolean);
    return labels.join(", ");
  };

  // Sort categories with selected ones first and respect levels
  const getSortedCategories = () => {
    if (!fieldOptions) return [];
    const selected = new Set(formData.categories || []);
    
    // Filter categories to only include types 10, 11, 12, and 13 (proper categories, not themes)
    const validCategoryTypes = [10, 11, 12, 13];
    const filteredCategories = fieldOptions.categories.filter(
      category => category.type && validCategoryTypes.includes(category.type)
    );
       
    return [...filteredCategories].sort((a, b) => {
      const aSelected = selected.has(a.value);
      const bSelected = selected.has(b.value);
      if (aSelected && !bSelected) return -1;
      if (!aSelected && bSelected) return 1;
      return 0;
    });
  };

  // Add wheel event handler for scrolling
  const handleWheel = (e: React.WheelEvent) => {
    const commandList = e.currentTarget;
    commandList.scrollTop += e.deltaY;
    e.stopPropagation();
  };

  // Update the CommandList components to include the wheel handler
  const renderCommandList = (options: FieldOption[], selectedValue: string | string[] | undefined, name: string, closeOnSelect = true) => {
    let displayValue: string | undefined;
    
    if (name === 'ship_restrictions' && Array.isArray(selectedValue)) {
      displayValue = selectedValue.length > 0 ? selectedValue[0] : undefined;
    } else {
      displayValue = selectedValue as string;
    }
    
    return (
      <CommandList className="max-h-[200px] overflow-y-auto" onWheel={handleWheel}>
        <CommandEmpty>No options found.</CommandEmpty>
        <CommandGroup>
          {getSortedOptions(options, selectedValue).map((option) => (
            <CommandItem
              key={option.value}
              value={option.label}
              onSelect={() => {
                if (name === 'categories') {
                  handleMultiSelectChange(name, option.value);
                } else {
                  handleSelectChange(name, option.value, closeOnSelect);
                }
              }}
            >
              {name === 'categories' ? (
                <div className="flex items-center w-full">
                  <Check
                    className={cn(
                      "mr-2 h-4 w-4 flex-shrink-0",
                      (formData.categories || []).some(cat => String(cat) === String(option.value))
                        ? "opacity-100"
                        : "opacity-0"
                    )}
                  />
                  <span className={cn(
                    "truncate",
                    option.level === 1 && "font-bold"
                  )}>
                    {option.label}
                  </span>
                </div>
              ) : (
                <>
                  <Check
                    className={cn(
                      "mr-2 h-4 w-4",
                      String(displayValue) === String(option.value)
                        ? "opacity-100"
                        : "opacity-0"
                    )}
                  />
                  {option.label}
                </>
              )}
            </CommandItem>
          ))}
        </CommandGroup>
      </CommandList>
    );
  };

  // Add logging to company display
  const getCompanyLabel = (companyId: string | number) => {
    if (!fieldOptions) return '';
    const stringId = String(companyId);
    const company = fieldOptions.companies.find(c => String(c.value) === stringId);
    console.log('Finding company label for:', companyId, 'Found:', company, 'Available companies:', fieldOptions.companies);
    return company?.label || stringId;
  };

  if (!fieldOptions) return null;

  const title = mode === 'edit' 
    ? 'Edit Template'
    : mode === 'copy'
    ? 'Copy Template'
    : initialData
    ? 'Create Template from Product'
    : 'Create Template';

  const description = mode === 'edit'
    ? 'Edit an existing template. Company and Product Type combination must be unique.'
    : 'Create a new template for importing products. Company and Product Type combination must be unique.';

  return (
    <Dialog open={isOpen} onOpenChange={(open) => {
      if (!open) {
        setFormData(defaultFormData); // Reset form when closing
        onClose();
      }
    }}>
      <DialogContent className="max-w-2xl max-h-[95vh] flex flex-col p-6">
        <DialogHeader className="px-0">
          <DialogTitle>{title}</DialogTitle>
          <DialogDescription>{description}</DialogDescription>
        </DialogHeader>
        
        <form onSubmit={handleSubmit} className="flex flex-col flex-1 overflow-hidden">
          <ScrollArea className="flex-1 -mr-6 pr-6 overflow-y-auto">
            <div className="grid gap-4 py-4 px-1 pr-4">
              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="company">Company*</Label>
                  <Popover>
                    <PopoverTrigger asChild>
                      <Button
                        variant="outline"
                        role="combobox"
                        className={cn(
                          "w-full justify-between",
                          !formData.company && "text-muted-foreground"
                        )}
                      >
                        {formData.company
                          ? getCompanyLabel(formData.company)
                          : "Select company..."}
                        <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                      </Button>
                    </PopoverTrigger>
                    <PopoverContent className="w-[var(--radix-popover-trigger-width)] p-0">
                      <Command>
                        <CommandInput placeholder="Search companies..." />
                        {renderCommandList(fieldOptions.companies, formData.company, 'company')}
                      </Command>
                    </PopoverContent>
                  </Popover>
                </div>
                
                <div className="space-y-2">
                  <Label htmlFor="product_type">Product Type*</Label>
                  <Input
                    id="product_type"
                    name="product_type"
                    value={formData.product_type}
                    onChange={handleInputChange}
                    placeholder="e.g. 'Ephemera' or '12x12 Paper'"
                  />
                </div>
              </div>

              <div className="space-y-2">
                <Label htmlFor="supplier">Supplier</Label>
                <Popover>
                  <PopoverTrigger asChild>
                    <Button
                      variant="outline"
                      role="combobox"
                      className={cn(
                        "w-full justify-between",
                        (!formData.supplier || formData.supplier === "") && "text-muted-foreground"
                      )}
                    >
                      {formData.supplier && formData.supplier !== ""
                        ? fieldOptions.suppliers.find(
                            supplier => supplier.value === formData.supplier
                          )?.label || "Select supplier..."
                        : "Select supplier..."}
                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="w-[var(--radix-popover-trigger-width)] p-0">
                    <Command>
                      <CommandInput placeholder="Search suppliers..." />
                      {renderCommandList(fieldOptions.suppliers, formData.supplier, 'supplier')}
                    </Command>
                  </PopoverContent>
                </Popover>
              </div>

              <div className="grid grid-cols-4 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="msrp">MSRP</Label>
                  <Input
                    id="msrp"
                    name="msrp"
                    type="number"
                    step="0.01"
                    value={formData.msrp || ""}
                    onChange={handleNumberInputChange}
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="cost_each">Cost Each</Label>
                  <Input
                    id="cost_each"
                    name="cost_each"
                    type="number"
                    step="0.01"
                    value={formData.cost_each || ""}
                    onChange={handleNumberInputChange}
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="qty_per_unit">Quantity per Unit</Label>
                  <Input
                    id="qty_per_unit"
                    name="qty_per_unit"
                    type="number"
                    value={formData.qty_per_unit || ""}
                    onChange={handleNumberInputChange}
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="case_qty">Case Quantity</Label>
                  <Input
                    id="case_qty"
                    name="case_qty"
                    type="number"
                    value={formData.case_qty || ""}
                    onChange={handleNumberInputChange}
                  />
                </div>
              </div>

              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="ship_restrictions">Shipping Restrictions</Label>
                  <Popover>
                    <PopoverTrigger asChild>
                      <Button
                        variant="outline"
                        role="combobox"
                        className={cn(
                          "w-full justify-between",
                          !formData.ship_restrictions && "text-muted-foreground"
                        )}
                      >
                        {formData.ship_restrictions
                          ? fieldOptions.shippingRestrictions.find(
                              (r) => r.value === (Array.isArray(formData.ship_restrictions) ? formData.ship_restrictions[0] : formData.ship_restrictions)
                            )?.label
                          : "Select shipping restriction..."}
                        <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                      </Button>
                    </PopoverTrigger>
                    <PopoverContent className="w-[var(--radix-popover-trigger-width)] p-0">
                      <Command>
                        <CommandInput placeholder="Search restrictions..." />
                        {renderCommandList(fieldOptions.shippingRestrictions, formData.ship_restrictions, 'ship_restrictions')}
                      </Command>
                    </PopoverContent>
                  </Popover>
                </div>
                <div className="space-y-2">
                  <Label htmlFor="hts_code">HTS Code</Label>
                  <Input
                    id="hts_code"
                    name="hts_code"
                    value={formData.hts_code || ""}
                    onChange={handleInputChange}
                  />
                </div>
              </div>

              <div className="grid grid-cols-4 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="weight">Weight (oz)</Label>
                  <Input
                    id="weight"
                    name="weight"
                    type="number"
                    step="0.01"
                    value={formData.weight || ""}
                    onChange={handleNumberInputChange}
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="length">Length (in)</Label>
                  <Input
                    id="length"
                    name="length"
                    type="number"
                    step="0.01"
                    value={formData.length || ""}
                    onChange={handleNumberInputChange}
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="width">Width (in)</Label>
                  <Input
                    id="width"
                    name="width"
                    type="number"
                    step="0.01"
                    value={formData.width || ""}
                    onChange={handleNumberInputChange}
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="height">Height (in)</Label>
                  <Input
                    id="height"
                    name="height"
                    type="number"
                    step="0.01"
                    value={formData.height || ""}
                    onChange={handleNumberInputChange}
                  />
                </div>
              </div>

              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="tax_cat">Tax Category</Label>
                  <Popover>
                    <PopoverTrigger asChild>
                      <Button
                        variant="outline"
                        role="combobox"
                        className={cn(
                          "w-full justify-between",
                          formData.tax_cat === undefined && "text-muted-foreground"
                        )}
                      >
                        {formData.tax_cat !== undefined
                          ? (() => {
                              console.log('Looking for tax_cat:', {
                                formData_tax_cat: formData.tax_cat,
                                formData_tax_cat_type: typeof formData.tax_cat,
                                taxCategories: fieldOptions.taxCategories.map(cat => ({ 
                                  value: cat.value, 
                                  value_type: typeof cat.value,
                                  label: cat.label
                                }))
                              });
                              const match = fieldOptions.taxCategories.find(
                                (cat) => String(cat.value) === String(formData.tax_cat)
                              );
                              console.log('Tax category match:', match);
                              return match?.label || "Not Specifically Set";
                            })()
                          : "Select tax category..."}
                        <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                      </Button>
                    </PopoverTrigger>
                    <PopoverContent className="w-[var(--radix-popover-trigger-width)] p-0">
                      <Command>
                        <CommandInput placeholder="Search tax categories..." />
                        {renderCommandList(fieldOptions.taxCategories, formData.tax_cat, 'tax_cat')}
                      </Command>
                    </PopoverContent>
                  </Popover>
                </div>
                <div className="space-y-2">
                  <Label htmlFor="size_cat">Size Category</Label>
                  <Popover>
                    <PopoverTrigger asChild>
                      <Button
                        variant="outline"
                        role="combobox"
                        className={cn(
                          "w-full justify-between",
                          !formData.size_cat && "text-muted-foreground"
                        )}
                      >
                        {formData.size_cat
                          ? fieldOptions.sizes.find(
                              (size) => size.value === formData.size_cat
                            )?.label
                          : "Select size category..."}
                        <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                      </Button>
                    </PopoverTrigger>
                    <PopoverContent className="w-[var(--radix-popover-trigger-width)] p-0">
                      <Command>
                        <CommandInput placeholder="Search sizes..." />
                        {renderCommandList(fieldOptions.sizes, formData.size_cat, 'size_cat')}
                      </Command>
                    </PopoverContent>
                  </Popover>
                </div>
              </div>

              <div className="space-y-2 max-w-[610px]">
                <Label htmlFor="categories">Categories</Label>
                <Popover modal={false}>
                  <PopoverTrigger asChild className="w-full">
                    <Button
                      variant="outline"
                      role="combobox"
                      className="w-full justify-between"
                    >
                      <span className={cn(
                        "truncate block flex-1 text-left",
                        !formData.categories?.length && "text-muted-foreground"
                      )}>
                        {formData.categories?.length
                          ? getSelectedCategoryLabels()
                          : "Select categories..."}
                      </span>
                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="w-[var(--radix-popover-trigger-width)] p-0" align="start">
                    <Command className="max-h-[200px]">
                      <CommandInput placeholder="Search categories..." />
                      {renderCommandList(getSortedCategories(), undefined, 'categories', false)}
                    </Command>
                  </PopoverContent>
                </Popover>
              </div>

              <div className="space-y-2">
                <Label htmlFor="description">Description</Label>
                <Textarea
                  id="description"
                  name="description"
                  value={formData.description || ""}
                  onChange={handleTextAreaChange}
                  rows={3}
                />
              </div>
            </div>
          </ScrollArea>
          
          <DialogFooter className="px-0 mt-6">
            <Button type="button" variant="outline" onClick={onClose}>
              Cancel
            </Button>
            <Button type="submit" disabled={isSubmitting}>
              {isSubmitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              {mode === 'edit' ? 'Update' : 'Create'} Template
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
} 