import { Space, Table, Tooltip } from "antd";
import { useEffect, useRef, useState } from "react";
import InputItem from "./FormItems";
import { useQuery } from "@tanstack/react-query";
import { CloseOutlined } from "@ant-design/icons";
import { useSiteContext } from "../Context/SiteContext";
import { parseArrayField } from "../utils/parseArrayField";
import { useFormattedPrice } from "../utils/formatPrice";
import { filterProductsByMinStock } from "../utils/filterProductsByMinStock";
import AutoCompleteInput from "./ApiAutoComplete";
import AddSerialNumbers from "./AddSerialNumbers";
import UseSerialNumbers from "./UseSerialNumbers";
import { AlertMessage } from "./AlertMessage";
import { checkStockNew } from "../utils/checkStock";
import { getStatusById } from "../utils/status";
import { getTaxById, getTaxNameById } from "../utils/getTaxById";
import { mapToLabelValue } from "../utils/mapToLabelValue";
import { isCompositeProduct } from "../utils/isCompositeProduct";
import GoogleIcon from "./GoogleIcon";


const fetcher = (url) =>
  fetch(url, {}).then((res) => {
    if (!res.ok) throw new Error("Unauthorized or error fetching data");
    return res.json();
  });

export default function LineItemFormTable({
  type = "",
  tax = true,
  activelineItems,
  seletedcurrency,
  purchase = false,
  setForm = [],
  refdata = false,
  customercurrency = null,
  editable = true,
  priceMethod = "selling",
  disabled = false,
  form = {},
  onKeyDownLastItem,
  editQty = true,
}) {
  const {
    selectedCustomer,
    brandData,
    lineItems,
    setLineItems,
    updatedLineItems,
    setUpdatedLineItems,
    formList,
    setFormList,
    setQuoteLineItems,
    newTax,
    setNewTax,
  } = useSiteContext();

  const stockRequestRef = useRef({});
  const [stockMap, setStockMap] = useState({});
  const [searchTerm, setSearchTerm] = useState("");



  // const validateStock = async (itemKey, inventory_id, qty) => {






  //   if (type !== "deliverynote") return; 
  //   if (!inventory_id) return;

  //   const requestId = Date.now();
  //   stockRequestRef.current[itemKey] = requestId;

  //   try {
  //     const res = await checkStockNew({ inventory_id, qty });

  //     if (stockRequestRef.current[itemKey] !== requestId) return;

  //     const availableStock = Number(res.availableStock);
  //     const inStock = res.inStock === true;

  //     setStockMap((prev) => ({
  //       ...prev,
  //       [itemKey]: { inStock, availableStock, qty },
  //     }));

  //     setUpdatedLineItems((prev) => {
  //       const source = prev.length ? prev : formList;

  //       return source.map((item) => {
  //         if (item.key !== itemKey) return item;

  //         const finalQty = inStock ? qty : Math.max(availableStock, 0);

  //         return {
  //           ...item,
  //           qty: finalQty,
  //           total: (finalQty * Number(item.price)).toFixed(2),
  //         };
  //       });
  //     });
  //   } catch (err) {
  //     console.error("Stock check failed", err);
  //   }
  // };



const validateStock = async (itemKey, inventory_id, qty) => {
  if (type !== "deliverynote") return;
  if (!inventory_id) return;

  const currentItem = formList.find((i) => i.key === itemKey);
  if (!currentItem) return;

  const requestId = Date.now();
  stockRequestRef.current[itemKey] = requestId;

  try {
    /* ======================================
       COMPOSITE PRODUCT STOCK CHECK
    ====================================== */
    if (
      Array.isArray(currentItem.composite_products) &&
      currentItem.composite_products.length > 0
    ) {
      let minAllowedQty = Infinity;
      let hasStockIssue = false;
      let limitingChildren = []; // ✅ FIX: ARRAY

      for (const child of currentItem.composite_products) {
        const childUnitQty = Number(child.qty || 1);
        const requiredQty = qty * childUnitQty;

        const res = await checkStockNew({
          inventory_id: child.item_id,
          qty: requiredQty,
        });

        if (stockRequestRef.current[itemKey] !== requestId) return;

        const availableStock = Number(res.availableStock || 0);

        // how many parent items can be made from this child
        const maxParentQty = Math.floor(
          availableStock / childUnitQty
        );

        // reset limiting list if new lower limit found
        if (maxParentQty < minAllowedQty) {
          minAllowedQty = maxParentQty;
          limitingChildren = [
            {
              item_id: child.item_id,
              name: child.item,
              availableStock,
              requiredPerUnit: childUnitQty,
            },
          ];
        }
        // same limiting qty → add to list
        else if (maxParentQty === minAllowedQty) {
          limitingChildren.push({
            item_id: child.item_id,
            name: child.item,
            availableStock,
            requiredPerUnit: childUnitQty,
          });
        }

        if (!res.inStock) {
          hasStockIssue = true;
        }
      }

      const finalQty = hasStockIssue
        ? Math.max(minAllowedQty, 0)
        : qty;

      setStockMap((prev) => ({
        ...prev,
        [itemKey]: {
          inStock: !hasStockIssue,
          availableStock: minAllowedQty,
          qty: finalQty,
          isComposite: true,
          limitingChildren, // ✅ ARRAY SAVED
        },
      }));

      setUpdatedLineItems((prev) => {
        const source = prev.length ? prev : formList;

        return source.map((item) => {
          if (item.key !== itemKey) return item;

          return {
            ...item,
            qty: finalQty,
            total: (finalQty * Number(item.price)).toFixed(2),
          };
        });
      });

      return; // 🚫 STOP HERE
    }

    /* ======================================
       NORMAL PRODUCT STOCK CHECK
    ====================================== */
    const res = await checkStockNew({ inventory_id, qty });

    if (stockRequestRef.current[itemKey] !== requestId) return;

    const availableStock = Number(res.availableStock || 0);
    const inStock = res.inStock === true;

    const finalQty = inStock ? qty : Math.max(availableStock, 0);

    setStockMap((prev) => ({
      ...prev,
      [itemKey]: {
        inStock,
        availableStock,
        qty: finalQty,
        isComposite: false,
      },
    }));

    setUpdatedLineItems((prev) => {
      const source = prev.length ? prev : formList;

      return source.map((item) => {
        if (item.key !== itemKey) return item;

        return {
          ...item,
          qty: finalQty,
          total: (finalQty * Number(item.price)).toFixed(2),
        };
      });
    });
  } catch (err) {
    console.error("Stock check failed", err);
  }
};





  function calculateFormStatus(activelineItems = [], updatedLineItems = []) {
    const usedMap = updatedLineItems.reduce((acc, item) => {
      acc[item.item_id] = (acc[item.item_id] || 0) + Number(item.qty || 0);
      return acc;
    }, {});

    const hasPending = activelineItems.some((item) => {
      const originalQty = Number(item.qty || 0);
      const usedQty = usedMap[item.item_id] || 0;
      return usedQty < originalQty;
    });

    return hasPending ? getStatusById(18) : getStatusById(5);
  }



  

  useEffect(() => {
    if (type !== "salesorder" && type !== "deliverynote") return;
    if (!activelineItems?.length) return;

    const status = calculateFormStatus(activelineItems, updatedLineItems);

    setForm((prev) => ({
      ...prev,
      status,
    }));
  }, [type, activelineItems, updatedLineItems]);

  useEffect(() => {
    if (type !== "salesorder" && type !== "deliverynote") return;

    formList.forEach((item) => {
      if (!item.item_id || item.qty == null) return;
      validateStock(item.key, item.item_id, Number(item.qty));
    });
  }, [type, formList]);

  useEffect(() => {
    if (type !== "salesorder" && type !== "deliverynote") return;

    setUpdatedLineItems(formList);
  }, [type, formList]);

  const { formatPrice } = useFormattedPrice();
  const currency =
    customercurrency || seletedcurrency || selectedCustomer?.default_currency;

  const [selectedItemId, setSelectedItemId] = useState(null);

  // const { data: getItems } = useQuery({
  //   queryKey: ["inventory", "all"],
  //   queryFn: () => fetcher(`/api/inventory?search=test`),
  // });

  const { data: getItems, isFetching } = useQuery({
    queryKey: ["inventory", searchTerm],
    queryFn: () =>
      fetcher(`/api/inventory?search=${encodeURIComponent(searchTerm)}`),
    enabled: searchTerm !== "", // only fetch when searching
  });

  const inventory =
    activelineItems?.length !== 0 ? activelineItems : getItems?.inventory;

  /** Price selector */
  const getPriceByCurrency = (rawPrice) => {
    const parsed = parseArrayField(rawPrice);

    if (Array.isArray(parsed)) {
      const firstObj = parsed[0];
      return firstObj?.[currency] ?? Object.values(firstObj || {})[0] ?? 0;
    }

    if (parsed && typeof parsed === "object") {
      return parsed?.[currency] ?? Object.values(parsed || {})[0] ?? 0;
    }

    return 0;
  };

  /** Load inventory / preset line items */
  useEffect(() => {
    if (!inventory) return;

    // Case: array of line items
 if (Array.isArray(inventory) && "item_id" in (inventory[0] || {})) {
  const cleaned =
    type === "purchase" || type === "purchaseorder"
      ? inventory.filter(i => !isCompositeProduct(i))
      : inventory;

  setFormList(cleaned);
  return;
}


    // Case: normalize inventory item


    const normalizeItem = (first) => {
  const price =
    priceMethod === "buying"
      ? getPriceByCurrency(first?.buying_price)
      : getPriceByCurrency(first?.price);

  return {
    key: Date.now(),
    item_id: first?.inventory_id,
    item_name: first?.inventory_name,
    item_description: first?.description || "",
    qty: 1,
    price,
    service_charge: Number(first?.service_charge || 0),

    // ✅ REQUIRED
    is_composite: isCompositeProduct(first),
    composite_products: first?.composite_products || [],

    type: first?.inventory_type,
    buying_price: getPriceByCurrency(first?.buying_price),
    discountPercentage: "",
    discountAmount: "",
    sku: first?.sku || "",
    unit: first?.unit || "",
    total: (1 * price).toFixed(2),
    serialization: first?.serialization === true,
  };
};



    if (!Array.isArray(inventory) && inventory?.inventory_id) {
      setFormList([normalizeItem(inventory)]);
      return;
    }

    if (Array.isArray(inventory) && inventory[0]?.inventory_id) {

       const first = inventory[0];

  if ((type === "purchase" || type === "purchaseorder") && isCompositeProduct(first)) {
    return;
  }

      setFormList([normalizeItem(inventory[0])]);
    }
  }, [inventory, currency, selectedCustomer]);

  /** Update field */
  const updateField = (key, field, value) => {
    setFormList((prev) =>
      prev.map((item) =>
        item.key === key ? { ...item, [field]: value } : item,
      ),
    );
  };




  /** Calculate line total */
  const lineTotal = (data) => {
    const qty = Number(data?.qty || 0);
    const price = Number(data?.price || 0);

    const discountPercent = Number(data?.discountPercentage || 0);
    const discountAmount = Number(data?.discountAmount || 0);

    const taxRate = Number(
      getTaxById(
        newTax || selectedCustomer?.customer_tax,
        brandData?.global_tax,
      )?.value || 0
    );

    // --- Discount ---
    let unitDiscount = discountPercent
      ? (price * discountPercent) / 100
      : discountAmount;

    unitDiscount = Math.min(unitDiscount, price);

    const discountedUnit = price - unitDiscount;

    // --- Base amount ---
    let subTotal = discountedUnit * qty;

    // ⭐ ADD SERVICE CHARGE (ONLY FOR COMPOSITE)
    const isComposite = data?.is_composite === true;

    if (isComposite) {
      subTotal += Number(data?.service_charge || 0);
    }


    // --- Tax ---
    const taxValue = tax ? (subTotal * taxRate) / 100 : 0;

    // --- Final ---
    const total = subTotal + taxValue;

    return total.toFixed(2);
  };


  /** Update totals whenever formList changes */
  useEffect(() => {
    const updatedItems = formList.map((item) => ({
      ...item,
      total: lineTotal(item),
    }));
    setLineItems(updatedItems);
  }, [formList, tax]);

  const inventoryList = Array.isArray(getItems?.inventory)
    ? getItems.inventory
    : [];

  const inventorySource = purchase
    ? (filterProductsByMinStock(inventoryList) ?? [])
    : inventoryList;

  /** Inventory select options */
  const inventoryTransformed = inventorySource.map((item) => ({
    id: item.inventory_id,
    label: item.inventory_name,
    value: item.inventory_name,
    description: item.description || "",
    price: item.price,
    buying_price: item.buying_price,
    type: item.inventory_type,
    unit: item.unit,
    sku: item.sku,
    serialization: item?.serialization === true,
  }));

  const usedItemIds = formList.map((i) => i.item_id);
  const filteredOptions = inventoryTransformed.filter(
    (option) => !usedItemIds.includes(option.id),
  );

  /** Add new row */
  const add = () => {
    setFormList((prev) => [
      ...prev,
      {
        key: Date.now(),
        type: "",
        item_id: null,
        item_name: "",
        item_description: "",
        qty: 1,
        price: 0,
        buying_price: 0,
        discountPercentage: "",
        discountAmount: "",
        sku: "",
        unit: "",
        total: "0.00",
        serialization: false,
      },
    ]);

    setQuoteLineItems([]);
  };

  /** Remove row */
  const remove = (key) => {

    setFormList((prev) => {

      return prev.length <= 1 ? prev : prev.filter((item) => item.key !== key);
    });


    setQuoteLineItems((prevItems) => {

      return prevItems.filter((item) => item.key !== key);
    });
  };





  /** Columns definition */
  const columns = [
    { title: "Item Details", dataIndex: "item_name", width: 150 },
    { title: "Description", dataIndex: "description", width: 60 },
    {
      title: "Unit",
      dataIndex: "item_unit",
      width: 60,
      className: "text-left",
    },
    {
      title: "Quantity",
      dataIndex: "item_qty",
      width: 80,
      className: "text-left",
    },
    {
      title: `Rate (${currency})`,
      dataIndex: "item_rate",
      width: 100,
      className: "text-right",
    },
    {
      title: "Total",
      dataIndex: "item_amount",
      width: 80,
      className: "text-right",
    },
    {
      title: "Tax",
      dataIndex: "item_tax",
      width: 60,
      className: "text-left",
    },
    {
      title: "Item Discount",
      dataIndex: "discount",
      width: 140,
      className: "text-left",
    },
    {
      title: "Line Total",
      dataIndex: "line_total",
      width: 80,
      className: "text-right font-semibold text-gray-800",
    },
    { title: "", dataIndex: "options", width: 60, className: "text-left" },
  ];

  /** Render each row */

  function getMaxQtyFromActiveItems(activelineItems = [], item_id) {
    const found = activelineItems.find((item) => item.item_id === item_id);

    return Number(found?.qty || 0);
  }


const filteredItems =
   ["purchase", "purchaseorder"].includes(type)
    ? (Array.isArray(formList) ? formList.filter(i => i?.is_composite !== true) : [])
    : formList;




return (
  <div className="overflow-x-hidden">

    {/* Desktop Header */}
    {filteredItems?.length !== 0 && (
      <div className="hidden lg:grid grid-cols-[2fr_2fr_1fr_1fr_1fr_1fr_1fr_2fr_1fr_40px] gap-2 sm:px-3 sm:py-1 p-5 text-xs font-normal text-gray-700">
        <div>Item</div>
        <div>Description</div>
        <div className="text-left">Unit</div>
        <div className="text-left">Qty</div>
        <div className="text-right">Rate</div>
        <div className="text-right">Amount</div>
        <div className="text-left">Tax</div>
        <div className="text-left">Discount</div>
        <div className="text-right">Total</div>
        <div />
      </div>
    )}

    {filteredItems.map((item, index) => {
      const isLastRow = index === filteredItems.length - 1;

      const deliveryMax =
        type === "deliverynote"
          ? Math.min(
              getMaxQtyFromActiveItems(activelineItems, item.item_id),
              stockMap[item.key]?.availableStock ?? Infinity
            )
          : type === "salesorder" || type === "purchase"
          ? getMaxQtyFromActiveItems(activelineItems, item.item_id)
          : undefined;

      return (
        <div
          key={item.key}
          className="mb-6 border border-gray-200 dark:border-gray-800 rounded-xl mt-5"
        >
          {type === "deliverynote" && stockMap[item.key]?.inStock === false && (
            <div className="p-4 pb-1">
              <AlertMessage
                type="error"
                message={
                  item.is_composite &&
                  Array.isArray(stockMap[item.key]?.limitingChildren)
                    ? `Composite stock limited. Max possible quantity: ${stockMap[item.key].availableStock}. Limited by: ${stockMap[item.key].limitingChildren
                        .map(
                          (c) => `${c.name} (Available: ${c.availableStock})`
                        )
                        .join(", ")}.`
                    : `Out of stock. Available: ${stockMap[item.key]?.availableStock}.`
                }
              />
            </div>
          )}

          <div className="grid grid-cols-1 lg:grid-cols-[2fr_2fr_1fr_1fr_1fr_1fr_1fr_2fr_1fr_40px] sm:gap-3 gap-5 sm:px-4 sm:py-4 p-5 items-center">

            {/* Item */}
            <div>
              <div className="lg:hidden text-[12px] mb-3 uppercase font-bold">Item</div>
              <AutoCompleteInput
                apiUrl="/api/inventory"
                value={item.item_name}
                disabled={disabled || !!refdata}
                placeholder="Search item"
                onChange={(value) => {
                  updateField(item.key, "item_name", value);
                  updateField(item.key, "item_id", null);
                  setSelectedItemId(null);
                  setSearchTerm(value);
                }}
                onSelect={(_, record) => {
                  updateField(item.key, "item_name", record.inventory_name);
                  updateField(item.key, "item_id", record.inventory_id);

                  const buyingPrice = getPriceByCurrency(record.buying_price);
                  const price =
                    priceMethod === "buying"
                      ? buyingPrice
                      : getPriceByCurrency(record.price);

                  updateField(item.key, "price", price);
                  updateField(item.key, "unit", record.unit);
                  updateField(item.key, "sku", record.sku);
                  updateField(item.key, "serialization", record.serialization === true);
                  updateField(item.key, "is_composite", isCompositeProduct(record));
                  updateField(item.key, "composite_products", record.composite_products || []);
                  updateField(item.key, "service_charge", Number(record.service_charge || 0));
                }}
              />
            </div>

            {/* Description */}
            <div>
              <div className="lg:hidden text-[12px] mb-3 uppercase font-bold">Description</div>
              <Tooltip title={item.item_description || "-"}>
                <div className="truncate text-gray-600">
                  {item.item_description || "-"}
                </div>
              </Tooltip>
            </div>

            {/* Unit */}
            <div className="text-left">
              <div className="lg:hidden text-[12px] mb-3 uppercase font-bold">Unit</div>
              {item.unit || "-"}
            </div>

            {/* Qty */}
            <div>
              <div className="lg:hidden text-[12px] mb-3 uppercase font-bold">Qty</div>
              <InputItem
                type="number"
                value={item.qty}
                min={1}
                max={deliveryMax}
                className="no-icon"
                disabled={editQty !== true}
                onChange={(e) => {
                  let qty = Number(e.target.value);
                  const baseMax = getMaxQtyFromActiveItems(
                    activelineItems,
                    item.item_id
                  );

                  if (type === "salesorder") qty = Math.min(qty, baseMax);

                  if (type === "deliverynote") {
                    const stockMax =
                      stockMap[item.key]?.availableStock ?? Infinity;
                    qty = Math.min(qty, baseMax, stockMax);
                    validateStock(item.key, item.item_id, qty);
                  }

                  updateField(item.key, "qty", qty);
                }}
              />
            </div>

            {/* Rate */}
            <div>
              <div className="lg:hidden text-[12px] mb-3 uppercase font-bold">Rate</div>
              <InputItem
                type="number"
                value={item.price}
                className="no-icon"
                disabled={disabled || !!refdata}
                onChange={(e) =>
                  updateField(item.key, "price", e.target.value)
                }
                onKeyDown={isLastRow ? onKeyDownLastItem : null}
              />
            </div>

            {/* Amount */}
            <div className="text-right lg:flex items-center">
              <div className="lg:hidden text-[12px] mb-3 uppercase font-bold text-left flex items-center">
                Amount
              </div>
              {formatPrice(
                item.qty * item.price +
                  (item.is_composite ? Number(item.service_charge || 0) : 0),
                currency
              )}
            </div>

            {/* Tax */}
            <div className="text-left lg:flex items-center">
              <div className="lg:hidden text-[12px] mb-3 uppercase font-bold">Tax</div>
              {tax && selectedCustomer?.customer_tax?.length !== 0 ? (
                <InputItem
                  type="select"
                  value={
                    getTaxById(
                      newTax || selectedCustomer?.customer_tax,
                      brandData?.global_tax
                    )?.name
                  }
                  onChange={(e) => setNewTax(e.target.value)}
                  options={
                    mapToLabelValue(
                      brandData?.global_tax,
                      "name",
                      "id"
                    ) || []
                  }
                />
              ) : (
                "-"
              )}
            </div>

            {/* Discount */}
            <div className="lg:flex items-center">
              <div className="lg:hidden text-[12px] mb-3 uppercase font-bold">Discount</div>
              <div className="flex gap-1">
                <InputItem
                  type="number"
                  placeholder="%"
                  value={item.discountPercentage}
                  disabled={disabled || !!item.discountAmount || !!refdata}
                  onChange={(e) =>
                    updateField(item.key, "discountPercentage", e.target.value)
                  }
                />
                <InputItem
                  type="number"
                  placeholder="0.00"
                  value={item.discountAmount}
                  disabled={disabled || !!item.discountPercentage || !!refdata}
                  onChange={(e) =>
                    updateField(item.key, "discountAmount", e.target.value)
                  }
                />
              </div>
            </div>

            {/* Line Total */}
            <div className="text-right font-semibold lg:flex items-center">
              <div className="lg:hidden text-[12px] mb-3 uppercase font-bold text-left flex items-center">
                Total
              </div>
              {formatPrice(Number(lineTotal(item)), currency)}
            </div>

            {/* Remove */}
            <div className="flex justify-end items-center">
              <InputItem
                type="icon_button"
                value="Remove"
                onClick={() => remove(item.key)}
                icon={<GoogleIcon size={16} name="close" />}
              />
            </div>
          </div>

          {type === "purchase" && (
            <AddSerialNumbers
              activeLineItems={[item]}
              form={form}
              setForm={setForm}
              minimalui
            />
          )}

          {(type === "salesorder" || type === "deliverynote") && (
            <UseSerialNumbers quoteLineItems={[item]} minimalui />
          )}
        </div>
      );
    })}

    {!disabled && !refdata && (
      <InputItem
        type="button"
        title="Add"
        btnColor="primary"
        onClick={add}
        className="no-width"
      />
    )}
  </div>
);

}
