/**
 * New BOM Page
 * Create a new Bill of Materials
 */

'use client';

import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
import { useForm, useFieldArray } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { productionAPI } from '@/lib/api/production';
import { productsAPI } from '@/lib/api/products';
// categoriesAPI removed - category is now derived from Product in backend
import { Button, Card, CardHeader, CardTitle, CardContent, Input } from '@/components/ui';
import { ArrowLeft, Plus, Trash2 } from 'lucide-react';
import toast from 'react-hot-toast';

const bomItemSchema = z.object({
  item_type: z.enum(['FABRIC', 'BUTTONS', 'ZIPPER', 'LINING', 'ELASTIC']),
  rm_product_id: z.number().int().positive('Raw material is required'),
  // use_dimensions removed - derived from Product.track_by_dimensions in backend
  quantity_per_unit: z.preprocess(
    (val) => {
      if (val === '' || val === null || val === undefined || (typeof val === 'number' && isNaN(val))) {
        return undefined;
      }
      const num = typeof val === 'string' ? parseFloat(val) : val;
      return isNaN(num) ? undefined : num;
    },
    z.number().positive().optional()
  ), // For special items RM
  required_length: z.preprocess(
    (val) => {
      if (val === '' || val === null || val === undefined || (typeof val === 'number' && isNaN(val))) {
        return undefined;
      }
      const num = typeof val === 'string' ? parseFloat(val) : val;
      return isNaN(num) ? undefined : num;
    },
    z.number().positive().optional()
  ), // For dimension-based RM (Fabric, Lining)
  required_width: z.preprocess(
    (val) => {
      if (val === '' || val === null || val === undefined || (typeof val === 'number' && isNaN(val))) {
        return undefined;
      }
      const num = typeof val === 'string' ? parseFloat(val) : val;
      return isNaN(num) ? undefined : num;
    },
    z.number().positive().optional()
  ), // For dimension-based RM (Fabric, Lining)
  dimension_unit: z.preprocess(
    (val) => {
      // Convert empty string to undefined for optional enum field
      if (val === '' || val === null || val === undefined) {
        return undefined;
      }
      return val;
    },
    z.enum(['inch', 'cm', 'm']).optional()
  ), // For dimension-based RM
});

const bomSchema = z.object({
  // category and type removed - derived from Product in backend
  fg_product_id: z.number().int().positive('Finished good product is required'),
  items: z.array(bomItemSchema).min(1, 'At least one raw material is required'),
});

export default function NewBOMPage() {
  const router = useRouter();
  const queryClient = useQueryClient();
  const [isSubmitting, setIsSubmitting] = useState(false);

  // Fetch Finished Good products (FG type)
  const { data: fgProductsData } = useQuery({
    queryKey: ['products', 'FG'],
    queryFn: async () => {
      const response = await productsAPI.list({ product_type: 'FG', limit: 100 });
      return response?.data || response;
    },
  });

  // Fetch Raw Material products (RM type)
  const { data: rmProductsData } = useQuery({
    queryKey: ['products', 'RM'],
    queryFn: async () => {
      const response = await productsAPI.list({ product_type: 'RM', limit: 100 });
      return response?.data || response;
    },
  });

  const fgProducts = fgProductsData?.products || [];
  const rmProducts = rmProductsData?.products || [];

  // Variants removed - use products directly

  const {
    register,
    handleSubmit,
    control,
    watch,
    setValue,
    formState: { errors },
  } = useForm({
    resolver: zodResolver(bomSchema),
    defaultValues: {
      category: '',
      type: '',
      fg_product_id: undefined,
      items: [], // Start with empty - user must add items
    },
  });

  const { fields, append, remove } = useFieldArray({
    control,
    name: 'items',
  });

  // Watch form values - must be declared before useQuery hooks that use them
  const selectedFgProductId = watch('fg_product_id');
  const selectedFgProduct = fgProducts.find((p) => p.id === parseInt(selectedFgProductId));
  const watchedItems = watch('items');

  // Fetch full product details with categories when a product is selected
  // Must be declared AFTER watch() calls so selectedFgProductId is available
  const { data: selectedProductDetailsResponse } = useQuery({
    queryKey: ['product', selectedFgProductId, 'details'],
    queryFn: async () => {
      if (!selectedFgProductId) return null;
      const response = await productsAPI.getById(selectedFgProductId);
      // API returns { success: true, data: { product: {...} } }
      // Extract the product from the response
      return response?.data?.product || response?.product || response?.data || response;
    },
    enabled: !!selectedFgProductId, // Only fetch when product is selected
  });
  
  // Extract product from response (handle different response structures)
  const selectedProductDetails = selectedProductDetailsResponse?.product || selectedProductDetailsResponse;

  // Note: category and type are now derived from Product in backend
  // No need to auto-populate or send these fields - they're displayed read-only in UI

  // Helper function to get product details
  const getProductInfo = (productId) => {
    if (!productId) return null;
    return rmProducts.find(p => p.id === parseInt(productId));
  };

  // Helper function to check if product is dimension-based RM
  const isDimensionBasedRM = (productId) => {
    const product = getProductInfo(productId);
    return product?.product_type === 'RM' && product?.track_by_dimensions === true;
  };

  const createBOMMutation = useMutation({
    mutationFn: async (data) => {
      // Normalized: category and type removed - backend derives from Product
      // use_dimensions removed - backend derives from Product.track_by_dimensions
      const bomData = {
        fg_product_id: parseInt(data.fg_product_id),
        items: data.items.map((item) => {
          const productId = parseInt(item.rm_product_id);
          const isDimBased = isDimensionBasedRM(productId);
          const itemType = item.item_type; // FABRIC, BUTTONS, ZIPPER, LINING, ELASTIC
          
          const baseItem = {
            item_type: itemType,
            rm_product_id: productId,
          };

          if (isDimBased) {
            // Dimension-based RM (Fabric, Lining)
            // Backend will derive use_dimensions from product.track_by_dimensions
            return {
              ...baseItem,
              required_length: parseFloat(item.required_length),
              required_width: parseFloat(item.required_width),
              dimension_unit: item.dimension_unit,
              // quantity_per_unit not sent for dimension-based items
            };
          } else {
            // Special items RM (quantity-based) - Buttons, Zipper, Elastic
            // Backend will derive use_dimensions from product.track_by_dimensions
            return {
              ...baseItem,
              quantity_per_unit: parseFloat(item.quantity_per_unit),
              // Dimension fields not sent for quantity-based items
            };
          }
        }),
      };
      return await productionAPI.createBOM(bomData);
    },
    onSuccess: () => {
      queryClient.invalidateQueries(['boms']);
      toast.success('BOM created successfully!');
      router.push('/production/boms');
    },
    onError: (error) => {
      const message = error?.response?.data?.message || error.message || 'Failed to create BOM';
      toast.error(message);
    },
  });

  const onSubmit = async (data) => {
    // Log form data for debugging
    console.log('Form submitted with data:', data);
    console.log('FG Product ID:', data.fg_product_id);
    console.log('Items:', data.items);
    
    // Normalized validation - category and type are derived from product, not validated here
    if (!data.fg_product_id) {
      toast.error('Finished Good Product is required.');
      return;
    }
    
    if (!data.items || data.items.length === 0) {
      toast.error('At least one raw material is required.');
      return;
    }

    setIsSubmitting(true);
    try {
      console.log('Calling createBOMMutation with:', data);
      await createBOMMutation.mutateAsync(data);
    } catch (error) {
      // Error handled in mutation
      console.error('BOM creation error:', error);
      console.error('Error details:', error?.response?.data);
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <div className="p-6 bg-gray-50 dark:bg-gray-950 space-y-6">
      {/* Header */}
      <div className="flex items-center gap-4">
        <Button
          variant="outline"
          onClick={() => router.push('/production/boms')}
          className="flex items-center gap-2"
        >
          <ArrowLeft className="w-4 h-4" />
          Back
        </Button>
        <div>
          <h1 className="text-3xl font-bold text-gray-900 dark:text-white">New BOM</h1>
          <p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
            Create a new Bill of Materials (recipe for finished goods)
          </p>
        </div>
      </div>

      {/* Form */}
      <Card>
        <CardHeader>
          <CardTitle>BOM Information</CardTitle>
        </CardHeader>
        <CardContent>
          <form 
            onSubmit={handleSubmit(
              (data) => {
                console.log('✅ handleSubmit validation passed');
                console.log('handleSubmit success - calling onSubmit with:', data);
                onSubmit(data);
              },
              (errors) => {
                console.error('❌ handleSubmit validation FAILED');
                console.error('Validation errors object:', errors);
                console.error('Validation errors keys:', Object.keys(errors));
                
                // Log detailed error messages
                Object.keys(errors).forEach(field => {
                  console.error(`  - ${field}:`, errors[field]);
                  if (errors[field]?.message) {
                    console.error(`    Message: ${errors[field].message}`);
                  }
                  if (errors[field]?.type) {
                    console.error(`    Type: ${errors[field].type}`);
                  }
                });
                
                // Show a more detailed error message
                const errorMessages = Object.values(errors)
                  .map(err => err?.message || 'Invalid field')
                  .filter(Boolean);
                toast.error(`Form validation failed: ${errorMessages.join(', ')}`, {
                  duration: 6000,
                });
              }
            )} 
            className="space-y-6"
          >
            {/* Finished Good Product - Select First */}
            <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                  Finished Good Product <span className="text-red-500">*</span>
                </label>
                <select
                  {...register('fg_product_id', { valueAsNumber: true })}
                  className={`w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-900 dark:text-white dark:border-gray-600 ${
                    errors.fg_product_id ? 'border-red-500' : 'border-gray-300'
                  }`}
                  required
                >
                  <option value="">Select finished good product...</option>
                  {fgProducts.map((product) => (
                    <option key={product.id} value={product.id}>
                      {product.name} {product.sku ? `(${product.sku})` : ''}
                    </option>
                  ))}
                </select>
                {errors.fg_product_id && (
                  <p className="mt-1 text-sm text-red-600">{errors.fg_product_id.message}</p>
                )}
                {selectedFgProduct && (
                  <p className="mt-1 text-sm text-gray-500 dark:text-gray-400">
                    Creating BOM for: <strong>{selectedFgProduct.name}</strong>
                  </p>
                )}
              </div>
            </div>

            {/* BOM Category and Type - Auto-filled and displayed as read-only text */}
            <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
              {/* Hidden inputs for form submission - must be registered */}
              <input 
                type="hidden" 
                {...register('category', { 
                  required: 'Category is required'
                })} 
              />
              <input 
                type="hidden" 
                {...register('type', { 
                  required: 'Type is required'
                })} 
              />
              
              {/* Category and Type Info (Read-only, derived from Product) */}
              {selectedFgProductId && (
                <div className="col-span-12 grid grid-cols-12 gap-4 p-4 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg">
                  <div className="col-span-6">
                    <label className="block text-sm font-medium text-blue-900 dark:text-blue-200 mb-1">
                      Category (from Product)
                    </label>
                    <p className="text-sm text-blue-800 dark:text-blue-300">
                      {(() => {
                        const categories = selectedProductDetails?.categories || selectedProductDetails?.productCategories || [];
                        const primaryCategory = categories.find(cat => cat.is_primary === true || cat.is_primary === 1);
                        const categoryToUse = primaryCategory || categories[0];
                        return categoryToUse?.name || categoryToUse?.category?.name || 'N/A';
                      })()}
                    </p>
                  </div>
                  <div className="col-span-6">
                    <label className="block text-sm font-medium text-blue-900 dark:text-blue-200 mb-1">
                      Type (from Product)
                    </label>
                    <p className="text-sm text-blue-800 dark:text-blue-300">
                      {selectedFgProduct?.name || 'N/A'}
                    </p>
                  </div>
                  <p className="col-span-12 mt-2 text-xs text-blue-600 dark:text-blue-400">
                    Note: Category and Type are automatically derived from the selected product (not stored in BOM)
                  </p>
                </div>
              )}
            </div>

            {/* Raw Materials Section */}
            <div className="border-t pt-6">
              <div className="flex justify-between items-center mb-4">
                <h3 className="text-lg font-semibold">Raw Materials</h3>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  onClick={() => append({ item_type: 'FABRIC', rm_product_id: undefined })}
                  className="flex items-center gap-2"
                >
                  <Plus className="w-4 h-4" />
                  Add Raw Material
                </Button>
              </div>

              {fields.map((field, index) => {
                const itemType = watchedItems?.[index]?.item_type || 'FABRIC';
                const isFabricOrLining = itemType === 'FABRIC' || itemType === 'LINING';
                
                return (
                <div key={field.id} className="grid grid-cols-12 gap-4 mb-4 p-4 border rounded-lg bg-gray-50 dark:bg-gray-800/50">
                  {/* Item Type */}
                  <div className="col-span-3">
                    <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                      Item Type <span className="text-red-500">*</span>
                    </label>
                    <select
                      {...register(`items.${index}.item_type`)}
                      className={`w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-900 dark:text-white dark:border-gray-600 ${
                        errors.items?.[index]?.item_type ? 'border-red-500' : 'border-gray-300'
                      }`}
                      required
                    >
                      <option value="FABRIC">Fabric</option>
                      <option value="BUTTONS">Buttons</option>
                      <option value="ZIPPER">Zipper</option>
                      <option value="LINING">Lining</option>
                      <option value="ELASTIC">Elastic</option>
                    </select>
                    {errors.items?.[index]?.item_type && (
                      <p className="mt-1 text-sm text-red-600">
                        {errors.items[index].item_type.message}
                      </p>
                    )}
                  </div>

                  {/* Raw Material Product */}
                  <div className="col-span-4">
                    <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                      Raw Material <span className="text-red-500">*</span>
                    </label>
                    <select
                      {...register(`items.${index}.rm_product_id`, { 
                        valueAsNumber: true,
                        validate: (value) => {
                          if (!value || value === 0) {
                            return 'Raw material is required';
                          }
                          return true;
                        }
                      })}
                      className={`w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-900 dark:text-white dark:border-gray-600 ${
                        errors.items?.[index]?.rm_product_id ? 'border-red-500' : 'border-gray-300'
                      }`}
                      required
                    >
                      <option value="">Select raw material...</option>
                      {rmProducts.map((product) => (
                        <option key={product.id} value={product.id}>
                          {product.name} {product.sku ? `(${product.sku})` : ''}
                        </option>
                      ))}
                    </select>
                    {errors.items?.[index]?.rm_product_id && (
                      <p className="mt-1 text-sm text-red-600">
                        {errors.items[index].rm_product_id.message}
                      </p>
                    )}
                  </div>

                  {/* Conditional fields based on item type and product type */}
                  {isFabricOrLining && isDimensionBasedRM(watchedItems?.[index]?.rm_product_id) ? (
                    // Dimension-based RM fields (Fabric, Lining)
                    <div className="col-span-4 space-y-3">
                      <div className="text-xs font-medium text-blue-600 dark:text-blue-400 mb-1">
                        Dimension-Based ({itemType})
                      </div>
                      <div className="grid grid-cols-3 gap-3">
                        <div>
                          <Input
                            label="Required Length"
                            type="number"
                            step="0.001"
                            min="0.001"
                            {...register(`items.${index}.required_length`, { valueAsNumber: true })}
                            error={errors.items?.[index]?.required_length?.message}
                            placeholder="0.00"
                            required
                          />
                        </div>
                        <div>
                          <Input
                            label="Required Width"
                            type="number"
                            step="0.001"
                            min="0.001"
                            {...register(`items.${index}.required_width`, { valueAsNumber: true })}
                            error={errors.items?.[index]?.required_width?.message}
                            placeholder="0.00"
                            required
                          />
                        </div>
                        <div>
                          <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                            Unit <span className="text-red-500">*</span>
                          </label>
                          <select
                            {...register(`items.${index}.dimension_unit`)}
                            className={`w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 dark:bg-gray-900 dark:text-white dark:border-gray-600 ${
                              errors.items?.[index]?.dimension_unit ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'
                            }`}
                            required
                          >
                            <option value="">Select</option>
                            <option value="inch">Inch</option>
                            <option value="cm">cm</option>
                            <option value="m">m</option>
                          </select>
                          {errors.items?.[index]?.dimension_unit && (
                            <p className="mt-1 text-sm text-red-600">{errors.items[index].dimension_unit.message}</p>
                          )}
                        </div>
                      </div>
                      {watchedItems?.[index]?.required_length && watchedItems?.[index]?.required_width && (
                        <p className="text-xs text-gray-500 dark:text-gray-400">
                          Required area: {(parseFloat(watchedItems[index].required_length) * parseFloat(watchedItems[index].required_width)).toFixed(2)} {watchedItems[index].dimension_unit || ''}² per unit
                        </p>
                      )}
                    </div>
                  ) : (
                    // Quantity field for special items RM (Buttons, Zipper, Elastic)
                    <div className="col-span-4">
                      <Input
                        label="Quantity Per Unit"
                        type="number"
                        step="0.001"
                        min="0.001"
                        {...register(`items.${index}.quantity_per_unit`, { valueAsNumber: true })}
                        error={errors.items?.[index]?.quantity_per_unit?.message}
                        required
                        placeholder="1.0"
                      />
                      <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                        Amount needed per unit of finished good (e.g., 15 buttons, 1 zipper)
                      </p>
                    </div>
                  )}

                  <div className="col-span-1 flex items-end">
                    {fields.length > 1 && (
                      <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        onClick={() => remove(index)}
                        className="text-red-600 hover:text-red-700"
                      >
                        <Trash2 className="w-4 h-4" />
                      </Button>
                    )}
                  </div>
                </div>
              )})}
            </div>

            <div className="flex justify-end gap-4 pt-4 border-t">
              <Button
                type="button"
                variant="outline"
                onClick={() => router.push('/production/boms')}
                disabled={isSubmitting}
              >
                Cancel
              </Button>
              <Button type="submit" variant="primary" disabled={isSubmitting} loading={isSubmitting}>
                Create BOM
              </Button>
            </div>
          </form>
        </CardContent>
      </Card>
    </div>
  );
}

