/**
 * Edit Product Page
 * Edit an existing product
 */

'use client';

import { useParams, useRouter } from 'next/navigation';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { productsAPI } from '@/lib/api/products';
import { categoriesAPI } from '@/lib/api/categories';
import { Button, Card, CardHeader, CardTitle, CardContent, Input, Textarea } from '@/components/ui';
import { PRODUCT_TYPES } from '@/lib/utils/constants';
import { ArrowLeft } from 'lucide-react';
import { LoadingSpinner } from '@/components/ui';
import { useState, useEffect } from 'react';
import toast from 'react-hot-toast';

const productSchema = z.object({
  name: z.string().min(1, 'Product name is required').max(150, 'Product name must not exceed 150 characters'),
  sku: z.string().optional(),
  product_type: z.enum(['FG', 'RM']).optional(),
  track_inventory: z.boolean().optional(),
  track_by_dimensions: z.boolean().optional(),
  unit_of_measure: z.enum(['inch', 'cm', 'm']).nullable().optional(),
  description: z.string().optional(),
  selling_price: z.number().min(0, 'Selling price must be non-negative').optional().or(z.literal('')),
}).refine((data) => {
  // If RM product, track_by_dimensions must be set
  if (data.product_type === 'RM') {
    return data.track_by_dimensions !== undefined;
  }
  return true;
}, {
  message: 'Track by dimensions must be set for RM products',
  path: ['track_by_dimensions'],
}).refine((data) => {
  // If dimension-based RM, unit_of_measure is required
  if (data.product_type === 'RM' && data.track_by_dimensions === true) {
    return data.unit_of_measure !== null && data.unit_of_measure !== undefined;
  }
  return true;
}, {
  message: 'Unit of measure is required for dimension-based RM products',
  path: ['unit_of_measure'],
});

export default function EditProductPage() {
  const router = useRouter();
  const params = useParams();
  const productId = parseInt(params.id);
  const queryClient = useQueryClient();
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [selectedCategoryId, setSelectedCategoryId] = useState('');

  // Fetch product data
  const { data: product, isLoading } = useQuery({
    queryKey: ['product', productId],
    queryFn: async () => {
      const response = await productsAPI.getById(productId);
      return response?.data?.product || null;
    },
  });

  // Fetch product categories
  const { data: productCategories } = useQuery({
    queryKey: ['product-categories', productId],
    queryFn: async () => {
      try {
        const response = await categoriesAPI.getProductCategories(productId);
        return response?.data?.categories || [];
      } catch (error) {
        return [];
      }
    },
    enabled: !!productId,
  });

  // Fetch all categories for selection
  const { data: allCategories, isLoading: categoriesLoading, error: categoriesError } = useQuery({
    queryKey: ['categories', 'all'],
    queryFn: async () => {
      try {
        // API has max limit of 100, fetch with max allowed
        const response = await categoriesAPI.list({ limit: 100, page: 1 });
        
        // API interceptor returns response.data from axios
        // Server returns: { success: true, message: "...", data: { categories: [...], pagination: {...} } }
        // After interceptor: response = { success: true, message: "...", data: { categories: [...], pagination: {...} } }
        // Categories page uses: response.data || response, then data?.categories
        // So we should use the same pattern
        const data = response?.data || response;
        const categories = data?.categories || [];
        
        // Debug log in development
        if (process.env.NODE_ENV === 'development') {
          console.log('Categories API response (edit page):', { 
            rawResponse: response, 
            responseType: typeof response,
            hasData: !!response?.data,
            hasCategories: !!response?.data?.categories,
            categories, 
            count: categories?.length,
            firstCategory: categories?.[0] 
          });
        }
        
        return Array.isArray(categories) ? categories : [];
      } catch (error) {
        console.error('Error fetching categories:', error);
        return [];
      }
    },
  });

  // Initialize category when product is loaded (from product.categories or productCategories)
  useEffect(() => {
    // Try to get category from product.categories first (if included in product response)
    if (product?.categories && product.categories.length > 0) {
      const primary = product.categories.find(c => c.is_primary);
      const categoryId = primary ? primary.id : product.categories[0]?.id;
      if (categoryId) {
        setSelectedCategoryId(String(categoryId));
        return;
      }
    }
    
    // Fallback: get from productCategories API response
    if (productCategories && productCategories.length > 0) {
      // Get primary category first, or first category if no primary
      const primary = productCategories.find(pc => pc.is_primary);
      const categoryId = primary 
        ? (primary.category_id || primary.category?.id)
        : (productCategories[0]?.category_id || productCategories[0]?.category?.id);
      
      if (categoryId) {
        setSelectedCategoryId(String(categoryId));
      }
    }
  }, [product, productCategories]);

  const {
    register,
    handleSubmit,
    watch,
    setValue,
    formState: { errors },
    reset,
  } = useForm({
    resolver: zodResolver(productSchema),
    values: product ? {
      name: product.name || '',
      sku: product.sku || '',
      product_type: product.product_type || 'FG',
      track_inventory: product.track_inventory ?? true,
      track_by_dimensions: product.track_by_dimensions ?? (product.product_type === 'RM' ? true : undefined),
      unit_of_measure: product.unit_of_measure || null,
      description: product.description || '',
      selling_price: product.selling_price || '',
    } : undefined,
  });

  const productType = watch('product_type');
  const trackByDimensions = watch('track_by_dimensions');
  const isRM = productType === 'RM';
  const isDimensionBasedRM = isRM && trackByDimensions === true;

  const updateProductMutation = useMutation({
    mutationFn: async (data) => {
      const productData = {
        ...data,
        selling_price: data.selling_price === '' ? undefined : data.selling_price,
        // Handle track_by_dimensions and unit_of_measure for RM products
        track_by_dimensions: data.product_type === 'RM' ? (data.track_by_dimensions ?? true) : undefined,
        unit_of_measure: data.product_type === 'RM' && data.track_by_dimensions === true 
          ? data.unit_of_measure 
          : (data.product_type === 'RM' && data.track_by_dimensions === false ? null : undefined),
      };
      
      // Update product first
      await productsAPI.update(productId, productData);
      
      // Then update category if changed
      if (selectedCategoryId) {
        // Remove all existing categories first
        if (productCategories && productCategories.length > 0) {
          for (const pc of productCategories) {
            const catId = pc.category_id || pc.category?.id;
            if (catId) {
              try {
                await categoriesAPI.removeProductFromCategory(productId, catId);
              } catch (error) {
                // Ignore errors for removal
              }
            }
          }
        }
        
        // Assign new category
        await categoriesAPI.assignProductToCategories(
          productId,
          [parseInt(selectedCategoryId)],
          parseInt(selectedCategoryId) // Same category is primary
        );
      } else {
        // Remove all categories if none selected
        if (productCategories && productCategories.length > 0) {
          for (const pc of productCategories) {
            const catId = pc.category_id || pc.category?.id;
            if (catId) {
              try {
                await categoriesAPI.removeProductFromCategory(productId, catId);
              } catch (error) {
                // Ignore errors for removal
              }
            }
          }
        }
      }
      
      return { success: true };
    },
    onSuccess: () => {
      queryClient.invalidateQueries(['product', productId]);
      queryClient.invalidateQueries(['product-categories', productId]);
      queryClient.invalidateQueries(['products']);
      toast.success('Product updated successfully!');
      router.push(`/products/${productId}`);
    },
    onError: (error) => {
      const message = error?.response?.data?.message || error.message || 'Failed to update product';
      toast.error(message);
    },
  });

  const onSubmit = async (data) => {
    setIsSubmitting(true);
    try {
      await updateProductMutation.mutateAsync(data);
    } catch (error) {
      // Error handled in mutation
    } finally {
      setIsSubmitting(false);
    }
  };

  if (isLoading) {
    return (
      <div className="p-6 bg-gray-50 dark:bg-gray-950">
        <div className="flex justify-center py-12">
          <LoadingSpinner size="lg" />
        </div>
      </div>
    );
  }

  if (!product) {
    return (
      <div className="p-6 bg-gray-50 dark:bg-gray-950">
        <Card>
          <CardContent className="pt-6">
            <div className="text-center py-12">
              <p className="text-red-600 dark:text-red-400 mb-4">Product not found</p>
              <Button onClick={() => router.push('/products')} variant="outline">
                Back to Products Hub
              </Button>
            </div>
          </CardContent>
        </Card>
      </div>
    );
  }

  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(`/products/${productId}`)}
          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">Edit Product</h1>
          <p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
            {product.name}
          </p>
        </div>
      </div>

      {/* Form */}
      <Card>
        <CardHeader>
          <CardTitle>Product Information</CardTitle>
        </CardHeader>
        <CardContent>
          <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
            <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
              <Input
                label="Product Name"
                type="text"
                placeholder="Enter product name"
                {...register('name')}
                error={errors.name?.message}
                required
              />

              <Input
                label="SKU"
                type="text"
                placeholder="Enter SKU (optional)"
                {...register('sku')}
                error={errors.sku?.message}
              />

              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                  Product Type
                </label>
                <select
                  {...register('product_type')}
                  className={`w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-gray-800 dark:text-white dark:border-gray-700 ${
                    errors.product_type ? 'border-red-500' : 'border-gray-300 dark:border-gray-700'
                  }`}
                >
                  <option value="FG">Finished Goods</option>
                  <option value="RM">Raw Materials</option>
                </select>
                {errors.product_type && (
                  <p className="mt-1 text-sm text-red-600">{errors.product_type.message}</p>
                )}
              </div>

              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                  Track Inventory
                </label>
                <input
                  type="checkbox"
                  {...register('track_inventory')}
                  className="w-4 h-4 text-blue-600 border-gray-300 dark:border-gray-600 rounded focus:ring-blue-500 dark:bg-gray-800 dark:checked:bg-blue-600"
                />
              </div>

              {/* RM-specific fields */}
              {isRM && (
                <>
                  <div>
                    <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                      Track by Dimensions
                      <span className="text-red-500 ml-1">*</span>
                    </label>
                    <div className="flex items-center gap-2">
                      <input
                        type="checkbox"
                        {...register('track_by_dimensions')}
                        checked={trackByDimensions ?? true}
                        onChange={(e) => {
                          setValue('track_by_dimensions', e.target.checked);
                          if (!e.target.checked) {
                            setValue('unit_of_measure', null);
                          }
                        }}
                        className="w-4 h-4 text-blue-600 border-gray-300 dark:border-gray-600 rounded focus:ring-blue-500 dark:bg-gray-800 dark:checked:bg-blue-600"
                      />
                      <span className="text-sm text-gray-600 dark:text-gray-400">
                        {trackByDimensions ? 'Dimension-based (fabric, leather)' : 'Special items (zippers, buttons)'}
                      </span>
                    </div>
                    <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                      {trackByDimensions 
                        ? 'Track materials by length × width dimensions'
                        : 'Track materials by quantity (zippers, buttons, threads, etc.)'}
                    </p>
                    {errors.track_by_dimensions && (
                      <p className="mt-1 text-sm text-red-600">{errors.track_by_dimensions.message}</p>
                    )}
                  </div>

                  {isDimensionBasedRM && (
                    <div>
                      <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                        Unit of Measure
                        <span className="text-red-500 ml-1">*</span>
                      </label>
                      <select
                        {...register('unit_of_measure')}
                        className={`w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent dark:bg-gray-800 dark:text-white dark:border-gray-700 ${
                          errors.unit_of_measure ? 'border-red-500' : 'border-gray-300 dark:border-gray-700'
                        }`}
                      >
                        <option value="">Select unit</option>
                        <option value="inch">Inches (in)</option>
                        <option value="cm">Centimeters (cm)</option>
                        <option value="m">Meters (m)</option>
                      </select>
                      {errors.unit_of_measure && (
                        <p className="mt-1 text-sm text-red-600">{errors.unit_of_measure.message}</p>
                      )}
                      <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                        Unit for length and width measurements
                      </p>
                    </div>
                  )}
                </>
              )}

              <Input
                label="Selling Price"
                type="number"
                step="0.01"
                min="0"
                placeholder="e.g., 100.00"
                {...register('selling_price', { valueAsNumber: true })}
                error={errors.selling_price?.message}
              />
              <div className="text-xs text-gray-500 dark:text-gray-400">
                Simple default price. Can be overridden by price lists.
              </div>

              {/* Category Selection */}
              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                  Category
                </label>
                <select
                  value={selectedCategoryId}
                  onChange={(e) => setSelectedCategoryId(e.target.value)}
                  className={`w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-800 dark:text-white ${
                    categoriesLoading ? 'opacity-50' : ''
                  }`}
                  disabled={categoriesLoading}
                >
                  <option value="">No category (remove assignment)</option>
                  {allCategories?.map((category) => (
                    <option key={category.id} value={category.id}>
                      {category.name}
                    </option>
                  ))}
                </select>
                {categoriesLoading && (
                  <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">Loading categories...</p>
                )}
                {categoriesError && (
                  <p className="mt-1 text-xs text-red-600 dark:text-red-400">
                    Error loading categories: {categoriesError.message}
                  </p>
                )}
                {!categoriesLoading && !categoriesError && allCategories && allCategories.length === 0 && (
                  <p className="mt-1 text-xs text-amber-600 dark:text-amber-400">
                    No categories available. <a href="/categories/new" className="underline">Create one</a>
                  </p>
                )}
                {!categoriesLoading && allCategories && allCategories.length > 0 && (
                  <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
                    {allCategories.length} categor{allCategories.length === 1 ? 'y' : 'ies'} available. Assign this product to a category for better organization.
                  </p>
                )}
              </div>
            </div>

            <Textarea
              label="Description"
              placeholder="Enter product description (optional)"
              rows={4}
              {...register('description')}
              error={errors.description?.message}
            />

            <div className="flex justify-end gap-4 pt-4 border-t dark:border-gray-700">
              <Button
                type="button"
                variant="outline"
                onClick={() => router.push(`/products/${productId}`)}
                disabled={isSubmitting}
              >
                Cancel
              </Button>
              <Button
                type="submit"
                variant="primary"
                disabled={isSubmitting}
                loading={isSubmitting}
              >
                Update Product
              </Button>
            </div>
          </form>
        </CardContent>
      </Card>
    </div>
  );
}

