"use client";

import { Grid, Table, Tag } from "antd";
import { useState, useMemo } from "react";
import { getStatusById } from "@/app/utils/status";
import InputItem from "../FormItems";
import { errorMessage, successMessage } from "@/app/utils/alertMessages";
import { parseArrayField } from "@/app/utils/parseArrayField";
import { useSiteContext } from "@/app/Context/SiteContext";
import { generalUpdateReverse } from "@/app/utils/action_reverse/generalUpdateReverse";
import { forwardSalesTransactionFlow } from "../../utils/action_forward/forwardSalesTransactionFlow";
import { checkSalesReturnWalletIsUsed } from "@/app/utils/checkSalesRetunrWalletAmountUsed";
import { hasSufficientStockForItems } from "@/app/utils/hasSufficientStockForItemsForCancellation";
import { purchaseReturnCancel } from "@/app/utils/action_forward/purchaseReturnCancel";
import { updateUsedSerialNumbers } from "@/app/utils/updateUsedSerialNumbers";
import { updateInventoryStock } from "@/app/utils/updateInventoryStock";

export default function CancelForm({
  data = [],
  type = "",
  router,
  form = [],
  inventory = [],
}) {
  const [loading, setLoading] = useState(false);
  const [reasons, setReasons] = useState({});
  const [error, setError] = useState(false);

  const { setRefundCancelModalOpen, getCustomerWalletData } = useSiteContext();

  /* ================= BREAKPOINT ================= */
  const { useBreakpoint } = Grid;
  const screens = useBreakpoint();
  const isMobile = !screens.lg;

  /* =====================================================
     FILTER SALES RETURNS WHERE WALLET IS ALREADY USED
  ===================================================== */
  const filteredData = useMemo(() => {
    if (!Array.isArray(data)) return [];

    return data.filter((item) => {
      if (type !== "salesreturn") return true;

      const customerId = parseArrayField(
        parseArrayField(item?.invoice_info)?.[0]?.customer_id,
      );

      const isUsed = checkSalesReturnWalletIsUsed(
        getCustomerWalletData,
        item?.salesreturn_id,
        customerId,
      );

      return !isUsed;
    });
  }, [data, getCustomerWalletData, type]);

  /* ======================================
     CANCEL CONFIRM HANDLER
  ====================================== */
  const confirmCancel = async (recordId) => {
    const haveStock = hasSufficientStockForItems(
      inventory,
      data?.[0]?.updated_line_items,
    );

    if (type === "salesreturn" && !haveStock) {
      errorMessage("Insufficient stock for one or more items");
      return;
    }

    if (!recordId || !type) return;

    const reason = reasons[recordId]?.trim();
    if (!reason) {
      errorMessage("Cancel reason is required");
      setError(true);
      return;
    }

    try {
      setLoading(true);

      if (type === "salesorder") {
        await fetch(`/api/quote`, {
          method: "PATCH",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            quote_number: data?.[0]?.quote_info,
            status: JSON.stringify([getStatusById(1)]),
          }),
        });
      }

      if (type === "deliverynote") {
        if (data?.[0]?.serializationSerial !== "-") {
          await updateUsedSerialNumbers(
            parseArrayField(data?.[0]?.line_items),
            {
              mode: "remove",
              usedserialnumbers: parseArrayField(
                data?.[0]?.serializationSerial,
              ),
            },
          );
        }

        await updateInventoryStock(
          parseArrayField(data?.[0]?.line_items),
          "increase",
        );
      }

      if (type === "purchasereturn") {
        await purchaseReturnCancel({
          record: parseArrayField(data?.[0]?.payment_info),
          purchaseData: parseArrayField(data?.[0]?.purchase_info),
          data: parseArrayField(data?.[0]?.purchase_info),
          appliedAmount: Number(data?.[0]?.return_amount || 0),
          currency: "AED",
          reason: Object.values(reasons)[0] || "Purchase return cancelled",
          usedserialnumbers: parseArrayField(data?.[0]?.used_serial_numbers),
          amountFrom: `purchase-return-cancel-${data?.[0]?.purchasereturn_id}`,
          updatedLineItems: data?.[0]?.updated_line_items || [],
        });

        await updateUsedSerialNumbers({
          mode: "remove",
          inventory_id: parseArrayField(data?.[0]?.serializationSerial).map(
            (item) => item.inventory_id,
          ),
          usedserialnumbers: Object.fromEntries(
            parseArrayField(
              parseArrayField(data?.[0]?.serializationSerial),
            ).map((d) => [
              d.inventory_id,
              d.used_serialization?.usedSerial || [],
            ]),
          ),
        });
      }

      if (type === "salesreturn") {
        await forwardSalesTransactionFlow({
          record: parseArrayField(data?.[0]?.payment_info),
          invoiceData: parseArrayField(data?.[0]?.invoice_info),
          data: parseArrayField(data?.[0]?.invoice_info),
          type: "invoice",
          appliedAmount: Number(data?.[0]?.return_amount || 0),
          currency: "AED",
          reason: Object.values(reasons)[0] || "Sales return cancelled",
          usedserialnumbers: parseArrayField(data?.[0]?.used_serial_numbers),
          amountFrom: `sales-return-cancel-${data?.[0]?.salesreturn_id}`,
        });
      }

      const response = await fetch(`/api/${type}`, {
        method: "PATCH",
        body: JSON.stringify({
          [`${type}_id`]: recordId,
          status: JSON.stringify([getStatusById(4, reason)]),
        }),
      });

      const resData = await response.json();
      if (!response.ok) throw new Error(resData?.message);

      if (
        type === "deliverynote" ||
        type === "invoice" ||
        type === "proforma"
      ) {
        const serialRows =
          parseArrayField(data?.[0]?.serializationSerial) || [];

        const usedSerials = serialRows.reduce((acc, row) => {
          if (
            row?.inventory_id &&
            Array.isArray(row?.used_serialization?.usedSerial)
          ) {
            acc[String(row.inventory_id)] = row.used_serialization.usedSerial;
          }
          return acc;
        }, {});

        await generalUpdateReverse({
          targetType: "quote",
          targetNumbers:
            type === "proforma"
              ? data?.[0]?.quote_ref_number
              : data?.[0]?.[`${type}_id`],
          removeLockRef: data?.[0]?.[`${type}_number`],
          status: [getStatusById(2)],
          stock: [
            {
              inventory_id: parseArrayField(data?.[0]?.line_items) || [],
            },
          ],
          usedSerials,
        });
      }

      successMessage(
        `${type.charAt(0).toUpperCase() + type.slice(1)} cancelled successfully`,
      );

      location.reload();
      setRefundCancelModalOpen(false);
    } catch (err) {
      errorMessage(err.message || "Something went wrong");
      setRefundCancelModalOpen(false);
    } finally {
      setLoading(false);
    }
  };

  /* ================= COLUMNS ================= */

  const reasonColumn = {
    title: (
      <>
        Reason <span className="text-red-500">*</span>
      </>
    ),
    key: "cancel_reason",
    render: (_, record) => {
      const recordId = record?.[`${type}_id`];

      return (
        <InputItem
          placeholder="Enter cancel reason"
          value={reasons[recordId] || ""}
          onChange={(e) =>
            setReasons((prev) => ({
              ...prev,
              [recordId]: e.target.value,
            }))
          }
          disabled={loading}
          type="text"
          showErrorOutline={error}
        />
      );
    },
  };

  const actionColumn = {
    title: "Action",
    key: "action",
    render: (_, record) => (
      <InputItem
        disabled={loading}
        type="popconfirm"
        title={`Are you sure you want to cancel ${record?.[`${type}_number`] ?? ""
          }?`}
        placeholder="Cancel"
        onClick={() => confirmCancel(record?.[`${type}_id`])}
      />
    ),
  };

  const desktopColumns = [
    {
      title: `${type} No`,
      dataIndex: `${type}_number`,
      key: `${type}_number`,
    },
    {
      title: type === "purchasereturn" ? "Supplier" : "Customer",
      key: type === "purchasereturn" ? "supplier_name" : "customer_name",
      render: (_, record) =>
        type === "purchasereturn"
          ? record?.supplier_name || "-"
          : record?.customer_name || "-",
    },
    {
      title: "Date",
      dataIndex: `${type}_date`,
      key: `${type}_date`,
      render: (v) => (v ? new Date(v).toLocaleDateString() : "-"),
    },
    {
      title: "Status",
      key: "status",
      render: (_, record) => {
        let label = "-";

        try {
          const parsed =
            typeof record.status === "string"
              ? JSON.parse(record.status)
              : record.status;

          label = parsed?.[0]?.label ?? "-";
        } catch { }

        return <Tag color="green">{label}</Tag>;
      },
    },
    reasonColumn,
    actionColumn,
  ];

  const mobileColumns = [reasonColumn, actionColumn];

  return (
    <Table
      columns={isMobile ? mobileColumns : desktopColumns}
      dataSource={filteredData}
      rowKey={`${type}_id`}
      pagination={false}
      size="small"
      rowClassName={() => "crm-row"}
      scroll={{ x: true }}
      className="crm-table"
    />
  );
}
