/**
 * New Purchase Order Page
 * Create a new purchase order
 */

'use client';

import { useState } 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 { procurementAPI } from '@/lib/api/procurement';
import { productsAPI } from '@/lib/api/products';
import { Button, Card, CardHeader, CardTitle, CardContent, Input, Select } from '@/components/ui';
import { ArrowLeft, Plus, Trash2 } from 'lucide-react';
import toast from 'react-hot-toast';
import { formatCurrency } from '@/lib/utils/format';

const purchaseOrderItemSchema = z.object({
  product_id: z.number().int().positive(),
  variant_id: z.number().int().positive().optional(),
  quantity: z.number().positive().optional(), // Quantity for special items RM (optional for dimension-based RM)
  piece_length: z.number().positive().optional(), // For dimension-based RM
  piece_width: z.number().positive().optional(), // For dimension-based RM
  dimension_unit: z.enum(['inch', 'cm', 'm']).optional(), // For dimension-based RM
  pieces_count: z.number().int().positive().optional(), // For dimension-based RM
  unit_cost: z.number().nonnegative(),
});

const purchaseOrderSchema = z.object({
  vendor_id: z.number().int().positive(),
  status: z.enum(['DRAFT', 'CONFIRMED', 'CLOSED']).optional().default('DRAFT'),
  order_date: z.string().optional(),
  expected_delivery_date: z.string().optional(),
  items: z.array(purchaseOrderItemSchema).min(1, 'At least one item is required'),
  notes: z.string().optional(),
});

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

  // Fetch vendors
  const { data: vendorsData } = useQuery({
    queryKey: ['vendors'],
    queryFn: async () => {
      const response = await procurementAPI.listVendors({ limit: 100 });
      return response.data || response;
    },
  });

  // Fetch products
  const { data: productsData } = useQuery({
    queryKey: ['products'],
    queryFn: async () => {
      const response = await productsAPI.list({ limit: 100 });
      return response.data || response;
    },
  });

  const vendors = vendorsData?.vendors || [];
  const products = productsData?.products || [];

  const {
    register,
    handleSubmit,
    control,
    watch,
    formState: { errors },
  } = useForm({
    resolver: zodResolver(purchaseOrderSchema),
    defaultValues: {
      status: 'DRAFT',
      order_date: new Date().toISOString().split('T')[0],
      items: [{ product_id: 0, quantity: 1, unit_cost: 0 }],
    },
  });

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

  const watchedItems = watch('items');
  
  // Helper function to get product details
  const getProductInfo = (productId) => {
    if (!productId) return null;
    return products.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 calculateTotal = () => {
    return watchedItems?.reduce((sum, item) => {
      const unitCost = parseFloat(item.unit_cost) || 0;
      let itemQuantity = 0;
      
      // For dimension-based RM, use pieces_count; for special items RM, use quantity
      if (isDimensionBasedRM(item.product_id)) {
        itemQuantity = parseFloat(item.pieces_count) || 0;
      } else {
        itemQuantity = parseFloat(item.quantity) || 0;
      }
      
      return sum + itemQuantity * unitCost;
    }, 0) || 0;
  };

  const createPOMutation = useMutation({
    mutationFn: async (data) => {
      const poData = {
        vendor_id: parseInt(data.vendor_id),
        status: data.status || 'DRAFT',
        order_date: data.order_date || undefined,
        expected_delivery_date: data.expected_delivery_date || undefined,
        items: data.items
          .filter((item) => {
            // Filter items that have valid data (quantity > 0 for special items RM, or pieces_count > 0 for dimension-based RM)
            if (isDimensionBasedRM(item.product_id)) {
              return item.pieces_count > 0;
            } else {
              return item.quantity > 0;
            }
          })
          .map((item) => {
            const productId = parseInt(item.product_id);
            const baseItem = {
              product_id: productId,
              variant_id: item.variant_id ? parseInt(item.variant_id) : undefined,
              unit_cost: parseFloat(item.unit_cost),
            };

            // For dimension-based RM, include dimension fields
            if (isDimensionBasedRM(productId)) {
              return {
                ...baseItem,
                quantity: parseFloat(item.pieces_count || 0), // quantity = pieces_count for dimension-based RM
                piece_length: parseFloat(item.piece_length),
                piece_width: parseFloat(item.piece_width),
                dimension_unit: item.dimension_unit,
                pieces_count: parseInt(item.pieces_count),
              };
            } else {
              // For special items RM and FG, use quantity
              return {
                ...baseItem,
                quantity: parseFloat(item.quantity),
              };
            }
          }),
        notes: data.notes || undefined,
      };
      return await procurementAPI.createPurchaseOrder(poData);
    },
    onSuccess: () => {
      queryClient.invalidateQueries(['purchase-orders']);
      toast.success('Purchase order created successfully!');
      router.push('/procurement/purchase-orders');
    },
    onError: (error) => {
      const message = error?.response?.data?.message || error.message || 'Failed to create purchase order';
      toast.error(message);
    },
  });

  const onSubmit = async (data) => {
    setIsSubmitting(true);
    try {
      await createPOMutation.mutateAsync(data);
    } catch (error) {
      // Error handled in mutation
    } 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('/procurement/purchase-orders')}
          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 Purchase Order</h1>
          <p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
            Create a new purchase order
          </p>
        </div>
      </div>

      {/* Form */}
      <Card>
        <CardHeader>
          <CardTitle>Purchase Order Information</CardTitle>
        </CardHeader>
        <CardContent>
          <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
            <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">
                  Vendor <span className="text-red-500">*</span>
                </label>
                <select
                  {...register('vendor_id', { valueAsNumber: true })}
                  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.vendor_id ? 'border-red-500' : 'border-gray-300 dark:border-gray-700'
                  }`}
                  required
                >
                  <option value="">Select vendor...</option>
                  {vendors.map((vendor) => (
                    <option key={vendor.id} value={vendor.id}>
                      {vendor.name}
                    </option>
                  ))}
                </select>
                {errors.vendor_id && (
                  <p className="mt-1 text-sm text-red-600">{errors.vendor_id.message}</p>
                )}
              </div>

              <div>
                <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                  Status
                </label>
                <select
                  {...register('status')}
                  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 dark:bg-gray-800 dark:text-white"
                >
                  <option value="DRAFT">Draft</option>
                  <option value="CONFIRMED">Confirmed</option>
                  <option value="CLOSED">Closed</option>
                </select>
              </div>

              <Input
                label="Order Date"
                type="date"
                {...register('order_date')}
                error={errors.order_date?.message}
              />

              <Input
                label="Expected Delivery Date"
                type="date"
                {...register('expected_delivery_date')}
                error={errors.expected_delivery_date?.message}
              />
            </div>

            {/* Items Section */}
            <div className="border-t dark:border-gray-700 pt-6">
              <div className="flex justify-between items-center mb-4">
                <div>
                  <h3 className="text-lg font-semibold text-gray-900 dark:text-white">Items</h3>
                  <p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
                    You can add the same product multiple times with different dimensions (e.g., 2×2, 3×3, 6×6)
                  </p>
                </div>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  onClick={() => append({ product_id: 0, quantity: 1, unit_cost: 0 })}
                  className="flex items-center gap-2"
                >
                  <Plus className="w-4 h-4" />
                  Add Item
                </Button>
              </div>

              {fields.map((field, index) => {
                const itemProductId = watchedItems?.[index]?.product_id;
                const isDimBased = isDimensionBasedRM(itemProductId);
                
                return (
                <div key={field.id} className="space-y-4 mb-4 p-4 border dark:border-gray-700 rounded-lg bg-white dark:bg-gray-800">
                  {/* First row: Product, Quantity/Dimensions, Unit Cost, Total, Delete */}
                  <div className="grid grid-cols-12 gap-4">
                    <div className="col-span-5">
                      <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
                        Product <span className="text-red-500">*</span>
                      </label>
                      <select
                        {...register(`items.${index}.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.items?.[index]?.product_id ? 'border-red-500' : 'border-gray-300 dark:border-gray-600'
                        }`}
                        required
                      >
                        <option value="">Select product...</option>
                        {products.map((product) => (
                          <option key={product.id} value={product.id}>
                            {product.name}
                          </option>
                        ))}
                      </select>
                      {errors.items?.[index]?.product_id && (
                        <p className="mt-1 text-sm text-red-600">
                          {errors.items[index].product_id.message}
                        </p>
                      )}
                    </div>

                    {/* Conditional fields based on product type */}
                    {isDimBased ? (
                      // Dimension-based RM - show label only on first row
                      <div className="col-span-2">
                        <div className="text-xs font-medium text-blue-600 dark:text-blue-400 mb-1">
                          Dimension-Based RM
                        </div>
                      </div>
                    ) : (
                      // Quantity field for special items RM and FG
                      <div className="col-span-2">
                        <Input
                          label="Quantity"
                          type="number"
                          step="0.01"
                          min="0.01"
                          {...register(`items.${index}.quantity`, { valueAsNumber: true })}
                          error={errors.items?.[index]?.quantity?.message}
                          required
                        />
                      </div>
                    )}

                  <div className="col-span-2">
                    <Input
                      label="Unit Cost"
                      type="number"
                      step="0.01"
                      min="0"
                      {...register(`items.${index}.unit_cost`, { valueAsNumber: true })}
                      error={errors.items?.[index]?.unit_cost?.message}
                      required
                    />
                  </div>

                    {/* Total */}
                    <div className="col-span-2 flex items-end">
                      <div className="w-full">
                        <label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Total</label>
                        <div className="px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-white">
                          {formatCurrency(
                            (isDimBased
                              ? (parseFloat(watchedItems?.[index]?.pieces_count) || 0)
                              : (parseFloat(watchedItems?.[index]?.quantity) || 0)
                            ) * (parseFloat(watchedItems?.[index]?.unit_cost) || 0)
                          )}
                        </div>
                      </div>
                    </div>

                    {/* Delete Button */}
                    <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>

                  {/* Second row: Dimension fields for dimension-based RM */}
                  {isDimBased && (
                    <div className="grid grid-cols-12 gap-4">
                      <div className="col-span-12 space-y-2">
                        <div className="text-xs font-medium text-blue-600 dark:text-blue-400 mb-1">
                          Piece Dimensions
                        </div>
                        <div className="grid grid-cols-4 gap-2">
                          <div>
                            <Input
                              label="Length"
                              type="number"
                              step="0.01"
                              min="0"
                              {...register(`items.${index}.piece_length`, { valueAsNumber: true })}
                              error={errors.items?.[index]?.piece_length?.message}
                              placeholder="0.00"
                              required
                            />
                          </div>
                          <div>
                            <Input
                              label="Width"
                              type="number"
                              step="0.01"
                              min="0"
                              {...register(`items.${index}.piece_width`, { valueAsNumber: true })}
                              error={errors.items?.[index]?.piece_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
                            </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>
                            <Input
                              label="Pieces"
                              type="number"
                              step="1"
                              min="1"
                              {...register(`items.${index}.pieces_count`, { valueAsNumber: true })}
                              error={errors.items?.[index]?.pieces_count?.message}
                              placeholder="1"
                              required
                            />
                          </div>
                        </div>
                        {watchedItems?.[index]?.piece_length && watchedItems?.[index]?.piece_width && (
                          <p className="text-xs text-gray-500 dark:text-gray-400">
                            Total area: {(parseFloat(watchedItems[index].piece_length) * parseFloat(watchedItems[index].piece_width) * (parseFloat(watchedItems[index].pieces_count) || 1)).toFixed(2)} {watchedItems[index].dimension_unit || ''}²
                          </p>
                        )}
                      </div>
                    </div>
                  )}
                </div>
              );
              })}

              {errors.items && errors.items.root && (
                <p className="mt-2 text-sm text-red-600">{errors.items.root.message}</p>
              )}

              <div className="mt-4 p-4 bg-gray-50 dark:bg-gray-800 rounded-lg flex justify-end">
                <div className="text-right">
                  <p className="text-sm text-gray-600 dark:text-gray-400">Total Amount:</p>
                  <p className="text-2xl font-bold text-gray-900 dark:text-white">{formatCurrency(calculateTotal())}</p>
                </div>
              </div>
            </div>

            <div className="flex justify-end gap-4 pt-4 border-t dark:border-gray-700">
              <Button
                type="button"
                variant="outline"
                onClick={() => router.push('/procurement/purchase-orders')}
                disabled={isSubmitting}
              >
                Cancel
              </Button>
              <Button
                type="submit"
                variant="primary"
                disabled={isSubmitting}
                loading={isSubmitting}
              >
                Create Purchase Order
              </Button>
            </div>
          </form>
        </CardContent>
      </Card>
    </div>
  );
}


