import React, { useCallback, useEffect, useState } from 'react';
import {
  Button,
  Card,
  Col,
  DatePicker,
  Form,
  Input,
  InputNumber,
  Modal,
  Popconfirm,
  Row,
  Select,
  Space,
  Spin,
  Table,
  message,
  Descriptions,
  Divider,
  Popover,
  Tag,
} from 'antd';
import { useNavigate } from 'react-router-dom';
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  MinusCircleOutlined,
  DownloadOutlined,
  EyeOutlined,
  ThunderboltOutlined,
  SyncOutlined,
  CloseCircleOutlined,
  CheckCircleOutlined,
} from '@ant-design/icons';
import dayjs, { Dayjs } from 'dayjs';
import { AppContainer } from '../../components/AppContainer';
import jwtAxios from '../../api/axiosInstance';
import { ENDPOINTS } from '../../api/endpoints';

const ENTITY_LABEL = 'Purchase';
const ENTITY_ENDPOINT = ENDPOINTS.PURCHASE; // e.g. '/api/purchases'

interface Option {
  value: string;
  label: string;
}

interface PurchaseMeta {
  purchaseUnits: Option[];
  suppliers: NamedOption[];
  vegetables: NamedOption[];
}

interface NamedOption {
  id: string;
  name: string;
  outstandingBalance?: string;
}

interface DataRecord {
  key: string;
  id: string;
  purchaseDate: string;
  billNo: string;
  lotNo: string;
  unit: string;
  bags?: string;
  weightPerBag?: string | null;
  quantity: string;
  ratePerUnit: string;
  grandTotal: string;
  costPerUnit: string;
  advanceAmount: string;
  balanceAmount: string;
  remainingQuantity?: string;
  remainingBags?: string;
  supplierId: string;
  vegetableId: string;
  supplier?: { name: string };
  vegetable?: { id?: string; name: string; isFlexible?: boolean };
  status?: string;
}

const { RangePicker } = DatePicker;

// ── Per-lot row data ────────────────────────────────────────────
interface LotRow {
  id: string;
  vegetableId?: string;
  lotNo: string;
  unit: string;
  bags?: number;
  quantity?: number;
  ratePerUnit?: number;
  rateType?: 'UNIT' | 'KG';
  extraCharges?: number;
  lastEdited?: 'bags' | 'quantity' | null;
  // Local state for duplicate validation in form
  isDuplicate?: boolean;
}

const makeLot = (): LotRow => ({
  id: Date.now().toString() + Math.random().toString(36).substring(2, 9),
  lotNo: '',
  unit: 'BOX',
  rateType: 'UNIT',
  extraCharges: 0,
  lastEdited: null,
  isDuplicate: false,
});

// ── Small sub-component for one lot row ────────────────────────
interface LotRowFormProps {
  lot: LotRow;
  index: number;
  purchaseUnits: Option[];
  vegetables: NamedOption[];
  canDelete: boolean;
  onChange: (id: string, updates: Partial<LotRow>) => void;
  onDelete: (id: string) => void;
  /** Server-side field errors keyed by field name e.g. { lotNo: "...", vegetableId: "..." } */
  fieldErrors?: Record<string, string>;
  onFieldErrorClear?: (id: string, field: string) => void;
}

const LotRowForm: React.FC<LotRowFormProps> = ({
  lot, index, purchaseUnits, vegetables, canDelete, onChange, onDelete,
  fieldErrors = {}, onFieldErrorClear,
}) => {
  const { id, unit, bags, quantity, ratePerUnit, rateType, lotNo, vegetableId, extraCharges } = lot;

  // Local state for checking status via API
  const [lotStatus, setLotStatus] = useState<{
    checking: boolean;
    isAvailable: boolean | null;
    message: string;
  }>({ checking: false, isAvailable: null, message: '' });

  // Debounced effect to check availability
  useEffect(() => {
    if (!lotNo || !lotNo.trim()) {
      setLotStatus({ checking: false, isAvailable: null, message: '' });
      return;
    }
    const timer = setTimeout(async () => {
      setLotStatus((prev) => ({ ...prev, checking: true }));
      try {
        const res = await jwtAxios.get(ENDPOINTS.PURCHASE_CHECK_LOT, {
          params: { lotNo: lotNo.trim(), vegetableId },
        });
        const data = res.data?.data;
        setLotStatus({
          checking: false,
          isAvailable: data?.isAvailable,
          message: data?.message || '',
        });
      } catch (err: any) {
        setLotStatus({
          checking: false,
          isAvailable: false,
          message: err?.response?.data?.message || 'Could not verify lot status.',
        });
      }
    }, 500);
    return () => clearTimeout(timer);
  }, [lotNo, vegetableId]);

  // Handlers
  const handleBagsChange = (val: number | null) => {
    onFieldErrorClear?.(id, 'bags');
    onChange(id, { bags: val ?? undefined, lastEdited: 'bags' });
  };

  const handleQtyChange = (val: number | null) => {
    onFieldErrorClear?.(id, 'quantity');
    onChange(id, { quantity: val ?? undefined, lastEdited: 'quantity' });
  };

  // Helper: renders a red error message below a field
  const FieldError = ({ field }: { field: string }) =>
    fieldErrors[field] ? (
      <div style={{ color: '#ff4d4f', fontSize: 12, marginTop: -10, marginBottom: 12, lineHeight: 1.3 }}>
        {fieldErrors[field]}
      </div>
    ) : null;

  const lotGoodsTotal = (unit === 'KG' || rateType === 'KG')
    ? (quantity ?? 0) * (ratePerUnit ?? 0)
    : (bags ?? 0) * (ratePerUnit ?? 0);

  const lotTotalCost = lotGoodsTotal + (extraCharges ?? 0);

  let costPerUnit = 0;
  if (lotTotalCost > 0) {
    if (unit === 'KG' || rateType === 'KG') {
      costPerUnit = quantity ? lotTotalCost / quantity : 0;
    } else {
      costPerUnit = bags ? lotTotalCost / bags : 0;
    }
  }

  return (
    <Card
      size="small"
      style={{
        marginBottom: 12,
        border: '1px solid #d9d9d9',
        borderRadius: 8,
        background: '#fafafa',
      }}
      title={
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ fontWeight: 600, color: '#1677ff' }}>Lot {index + 1}</span>
          {lotTotalCost > 0 && (
            <Tag color="green" style={{ marginLeft: 4 }}>
              Total: ₹{lotTotalCost.toFixed(2)}
            </Tag>
          )}
          {costPerUnit > 0 && (
            <Tag color="magenta">
              Cost/Unit: ₹{costPerUnit.toFixed(2)}
            </Tag>
          )}
        </div>
      }
      extra={
        canDelete ? (
          <Popconfirm
            title="Remove Lot"
            description="Are you sure you want to remove this lot?"
            onConfirm={() => onDelete(id)}
            okText="Yes"
            cancelText="No"
            placement="topRight"
          >
            <Button
              type="text"
              danger
              size="small"
              icon={<MinusCircleOutlined />}
            />
          </Popconfirm>
        ) : null
      }
    >
      <Row gutter={16}>
        {/* Vegetable */}
        <Col xs={24} sm={12} md={8}>
          <div style={{ marginBottom: 4 }}>
            <label style={{ fontSize: 12, fontWeight: 500 }}>
              <span style={{ color: '#ff4d4f', marginRight: 4 }}>*</span>Vegetable
            </label>
          </div>
          <Select
            showSearch
            placeholder="Select a vegetable"
            optionFilterProp="label"
            style={{ width: '100%', marginBottom: fieldErrors['vegetableId'] ? 4 : 16 }}
            status={fieldErrors['vegetableId'] ? 'error' : undefined}
            value={lot.vegetableId}
            filterOption={(input, option) =>
              (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
            }
            options={vegetables.map((v) => ({ label: v.name, value: v.id }))}
            onChange={(val) => {
              onFieldErrorClear?.(id, 'vegetableId');
              const veg = vegetables.find((v) => String(v.id) === String(val));
              const vegName = (veg?.name || '').toLowerCase();
              let defaultUnit = lot.unit;
              let defaultRateType = lot.rateType;
              if (vegName.includes('banana') || vegName.includes('வாழை')) {
                defaultUnit = 'THAAR';
                defaultRateType = 'UNIT';
              } else if (vegName.includes('coconut') || vegName.includes('தேங்காய்')) {
                defaultUnit = 'KG';
                defaultRateType = 'KG';
              } else if (vegName.includes('cabbage') || vegName.includes('முட்டைக்கோஸ்')) {
                defaultUnit = 'BAG';
                defaultRateType = 'UNIT';
              }
              onChange(id, { vegetableId: val, unit: defaultUnit, rateType: defaultRateType });
            }}
          />
          <FieldError field="vegetableId" />
        </Col>

        {/* Lot No */}
        <Col xs={24} sm={12} md={8}>
          <div style={{ marginBottom: 4 }}>
            <label style={{ fontSize: 12, fontWeight: 500 }}>
              <span style={{ color: '#ff4d4f', marginRight: 4 }}>*</span>Lot No
            </label>
            {lotStatus.checking ? (
              <Tag icon={<SyncOutlined spin />} color="processing" style={{ marginLeft: 8 }}>Checking...</Tag>
            ) : lotStatus.isAvailable === false ? (
              <Tag icon={<CloseCircleOutlined />} color="error" style={{ marginLeft: 8 }}>Unavailable</Tag>
            ) : lotStatus.isAvailable === true && !lot.isDuplicate ? (
              <Tag icon={<CheckCircleOutlined />} color="success" style={{ marginLeft: 8 }}>Available</Tag>
            ) : lot.isDuplicate ? (
              <Tag icon={<CloseCircleOutlined />} color="error" style={{ marginLeft: 8 }}>Duplicate</Tag>
            ) : null}
          </div>
          <Input
            placeholder="LOT-VEG-NAME-XX"
            style={{ marginBottom: (lotStatus.message || lot.isDuplicate || fieldErrors['lotNo']) ? 4 : 16 }}
            status={(lotStatus.isAvailable === false || lot.isDuplicate || fieldErrors['lotNo']) ? 'error' : ''}
            value={lot.lotNo}
            onChange={(e) => { onFieldErrorClear?.(id, 'lotNo'); onChange(id, { lotNo: e.target.value }); }}
          />
          {lotStatus.isAvailable === false && !lot.isDuplicate && (
            <div style={{ color: '#ff4d4f', fontSize: 12, marginBottom: 12, lineHeight: 1.2 }}>
              {lotStatus.message}
            </div>
          )}
          {lot.isDuplicate && (
            <div style={{ color: '#ff4d4f', fontSize: 12, marginBottom: 12, lineHeight: 1.2 }}>
              Lot Number is duplicated in this form.
            </div>
          )}
          {fieldErrors['lotNo'] && !lot.isDuplicate && (
            <div style={{ color: '#ff4d4f', fontSize: 12, marginBottom: 12, lineHeight: 1.2 }}>
              {fieldErrors['lotNo']}
            </div>
          )}
        </Col>

        {/* Unit */}
        <Col xs={24} sm={12} md={8}>
          <div style={{ marginBottom: 4 }}>
            <label style={{ fontSize: 12, fontWeight: 500 }}>
              <span style={{ color: '#ff4d4f', marginRight: 4 }}>*</span>Unit
            </label>
          </div>
          <Select
            options={purchaseUnits}
            placeholder="Select a unit"
            style={{ width: '100%', marginBottom: fieldErrors['unit'] ? 4 : 16 }}
            status={fieldErrors['unit'] ? 'error' : undefined}
            value={lot.unit}
            onChange={(val) => { onFieldErrorClear?.(id, 'unit'); onChange(id, { unit: val, bags: undefined, quantity: undefined, lastEdited: null, rateType: val === 'KG' ? 'KG' : 'UNIT' }); }}
          />
          <FieldError field="unit" />
        </Col>

        {/* Rate Type (only for BOX/BAG/THAAR/PIECES) */}
        {unit !== 'KG' && (
          <Col xs={24} sm={12} md={8}>
            <div style={{ marginBottom: 4 }}>
              <label style={{ fontSize: 12, fontWeight: 500 }}>
                <span style={{ color: '#ff4d4f', marginRight: 4 }}>*</span>Rate Type
              </label>
            </div>
            <Select
              style={{ width: '100%', marginBottom: 16 }}
              value={lot.rateType}
              onChange={(val) => { onChange(id, { rateType: val as 'UNIT' | 'KG', quantity: val === 'UNIT' ? undefined : lot.quantity }); }}
              options={[
                { value: 'UNIT', label: `Rate / ${unit === 'BOX' ? 'Box' : (unit === 'THAAR' ? 'Thaar' : (unit === 'PIECES' ? 'Piece' : 'Bag'))}` },
                { value: 'KG', label: 'Rate / Kg' },
              ]}
            />
          </Col>
        )}

        {/* Bags / Quantity Count (only for BOX/BAG/THAAR/PIECES) */}
        {unit !== 'KG' && (
          <Col xs={24} sm={12} md={8}>
            <div style={{ marginBottom: 4 }}>
              <label style={{ fontSize: 12, fontWeight: 500 }}>
                <span style={{ color: '#ff4d4f', marginRight: 4 }}>*</span>
                {unit === 'THAAR' ? 'Number of Thaar' : (unit === 'PIECES' ? 'Number of Pieces' : 'Number of Boxes/Bags')}
              </label>
            </div>
            <InputNumber
              placeholder={unit === 'THAAR' ? 'Thaar count' : (unit === 'PIECES' ? 'Piece count' : 'Boxes/Bags')}
              style={{ width: '100%', marginBottom: fieldErrors['bags'] ? 4 : 16 }}
              status={fieldErrors['bags'] ? 'error' : undefined}
              min={1}
              step={1}
              value={lot.bags}
              onChange={handleBagsChange}
            />
            <FieldError field="bags" />
          </Col>
        )}

        {/* Quantity */}
        {(unit === 'KG' || rateType === 'KG') && (
          <Col xs={24} sm={12} md={8}>
            <div style={{ marginBottom: 4 }}>
              <label style={{ fontSize: 12, fontWeight: 500 }}>
                <span style={{ color: '#ff4d4f', marginRight: 4 }}>*</span>Quantity (Kg)
              </label>
            </div>
            <InputNumber
              style={{ width: '100%', marginBottom: fieldErrors['quantity'] ? 4 : 16 }}
              status={fieldErrors['quantity'] ? 'error' : undefined}
              min={0.001}
              step={1}
              value={lot.quantity}
              onChange={handleQtyChange}
            />
            <FieldError field="quantity" />
          </Col>
        )}

        {/* Rate */}
        <Col xs={24} sm={12} md={8}>
          <div style={{ marginBottom: 4 }}>
            <label style={{ fontSize: 12, fontWeight: 500 }}>
              <span style={{ color: '#ff4d4f', marginRight: 4 }}>*</span>
              {unit === 'KG' ? 'Rate / Kg' : (rateType === 'KG' ? 'Rate / Kg' : `Rate / ${unit === 'BOX' ? 'Box' : (unit === 'THAAR' ? 'Thaar' : (unit === 'PIECES' ? 'Piece' : 'Bag'))}`)}
            </label>
          </div>
          <InputNumber
            style={{ width: '100%', marginBottom: fieldErrors['ratePerUnit'] ? 4 : 16 }}
            status={fieldErrors['ratePerUnit'] ? 'error' : undefined}
            min={0}
            step={0.01}
            value={lot.ratePerUnit}
            onChange={(val) => { onFieldErrorClear?.(id, 'ratePerUnit'); onChange(id, { ratePerUnit: val ?? undefined }); }}
          />
          <FieldError field="ratePerUnit" />
        </Col>

        {/* Extra Charges */}
        <Col xs={24} sm={12} md={8}>
          <div style={{ marginBottom: 4 }}>
            <label style={{ fontSize: 12, fontWeight: 500 }}>Extra Charges</label>
          </div>
          <InputNumber
            style={{ width: '100%', marginBottom: fieldErrors['extraCharges'] ? 4 : 16 }}
            min={0}
            step={0.01}
            value={lot.extraCharges}
            onChange={(val) => { onFieldErrorClear?.(id, 'extraCharges'); onChange(id, { extraCharges: val ?? 0 }); }}
          />
          <FieldError field="extraCharges" />
        </Col>
      </Row>
    </Card>
  );
};

// ─────────────────────────────────────────────────────────────────

const Purchase = () => {
  const navigate = useNavigate();
  const [form] = Form.useForm();
  const [open, setOpen] = useState(false);
  // null = "Add" mode. Holds the record's id while editing.
  const [editingId, setEditingId] = useState<string | null>(null);
  const [searchText, setSearchText] = useState('');
  const [dateRange, setDateRange] = useState<[Dayjs, Dayjs] | null>(null);
  const [data, setData] = useState<DataRecord[]>([]);
  const [loading, setLoading] = useState<boolean>(false);
  // const [isInitializing, setIsInitializing] = useState<boolean>(false);
  const [exportLoading, setExportLoading] = useState<boolean>(false);
  const [exportPdfLoading, setExportPdfLoading] = useState<boolean>(false);
  const [meta, setMeta] = useState<PurchaseMeta>({ purchaseUnits: [], suppliers: [], vegetables: [] });
  const [suppliers, setSuppliers] = useState<NamedOption[]>([]);
  const [vegetables, setVegetables] = useState<NamedOption[]>([]);
  const [pagination, setPagination] = useState({
    current: 1,
    pageSize: Number(import.meta.env.VITE_PAGE_SIZE) || 10,
    total: 0,
    totalPages: 0,
  });
  const [paymentModes, setPaymentModes] = useState<Option[]>([]);

  // ── Multi-lot state (Add mode only) ─────────────────────────────
  const [lots, setLots] = useState<LotRow[]>([makeLot()]);
  // Server-side field errors per lot index: { lotIndex -> { fieldName -> errorMessage } }
  const [lotFieldErrors, setLotFieldErrors] = useState<Record<number, Record<string, string>>>({});

  const clearLotFieldError = useCallback((lotId: string, field: string) => {
    const idx = lots.findIndex(l => l.id === lotId);
    if (idx === -1) return;
    setLotFieldErrors(prev => {
      const current = prev[idx];
      if (!current || !current[field]) return prev;
      const next = { ...current };
      delete next[field];
      return { ...prev, [idx]: next };
    });
  }, [lots]);

  // Derive duplicates whenever lots change
  useEffect(() => {
    const counts: Record<string, number> = {};
    lots.forEach(l => {
      const ln = l.lotNo.trim();
      if (ln) {
        counts[ln] = (counts[ln] || 0) + 1;
      }
    });

    setLots(prev => {
      let changed = false;
      const next = prev.map(l => {
        const ln = l.lotNo.trim();
        const isDuplicate = ln ? counts[ln] > 1 : false;
        if (l.isDuplicate !== isDuplicate) {
          changed = true;
          return { ...l, isDuplicate };
        }
        return l;
      });
      return changed ? next : prev;
    });
  }, [lots.map(l => l.lotNo).join('|')]);

  const updateLot = useCallback((id: string, updates: Partial<LotRow>) => {
    setLots((prev) => prev.map((l) => l.id === id ? { ...l, ...updates } : l));
  }, []);

  const addLot = useCallback(() => {
    setLots((prev) => [...prev, makeLot()]);
  }, []);

  const removeLot = useCallback((id: string) => {
    setLots((prev) => prev.filter((l) => l.id !== id));
  }, []);

  // ── Shared charges watched from the form (single) ────────────────
  const purchaseDateVal = Form.useWatch('purchaseDate', form);
  const supplierIdVal = Form.useWatch('supplierId', form);
  // Additional forms/watch fields can be safely omitted if unused

  const selectedUnit = Form.useWatch('unit', form);
  const bagsVal = Form.useWatch('bags', form);
  const quantityVal = Form.useWatch('quantity', form);
  const rateVal = Form.useWatch('ratePerUnit', form);
  const rateTypeVal = Form.useWatch('rateType', form);
  const extraChargesVal = Form.useWatch('extraCharges', form);

  const [editingNames, setEditingNames] = useState<{ supplier?: string; vegetable?: string }>({});

  // View modal state
  const [viewOpen, setViewOpen] = useState(false);
  const [viewLoading, setViewLoading] = useState(false);
  const [viewRecord, setViewRecord] = useState<any>(null);
  const handleExport = async () => {
    if (!data || data.length === 0) {
      message.warning('No data available to export');
      return;
    }
    setExportLoading(true);
    try {
      const params = new URLSearchParams();
      if (searchText) params.set('search', searchText);
      if (dateRange) {
        params.set('dateFrom', dateRange[0].format('YYYY-MM-DD'));
        params.set('dateTo', dateRange[1].format('YYYY-MM-DD'));
      }

      const url = `${ENDPOINTS.PURCHASE_EXPORT}${params.toString() ? '?' + params.toString() : ''}`;
      const response = await jwtAxios.get(url, { responseType: 'blob' });

      const disposition = response.headers['content-disposition'];
      let fileName = `purchases-${dayjs().format('YYYY-MM-DD')}.xlsx`;
      if (disposition) {
        const match = disposition.match(/filename\*?=(?:UTF-8'')?"?([^"\n;]+)"?/i);
        if (match?.[1]) fileName = decodeURIComponent(match[1]);
      }

      const blob = new Blob([response.data], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      });
      const objectUrl = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = objectUrl;
      link.download = fileName;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(objectUrl);

      message.success('Purchases exported successfully');
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to export purchases');
    } finally {
      setExportLoading(false);
    }
  };


  const handleExportPdf = async () => {
    if (!data || data.length === 0) {
      message.warning('No data available to export');
      return;
    }
    setExportPdfLoading(true);
    try {
      const params = new URLSearchParams();
      if (searchText) params.set('search', searchText);
      if (dateRange) {
        params.set('dateFrom', dateRange[0].format('YYYY-MM-DD'));
        params.set('dateTo', dateRange[1].format('YYYY-MM-DD'));
      }

      const url = `${ENDPOINTS.PURCHASE_EXPORT_PDF}${params.toString() ? '?' + params.toString() : ''}`;
      const response = await jwtAxios.get(url, { responseType: 'blob' });

      const disposition = response.headers['content-disposition'];
      let fileName = `purchase-report-${dayjs().format('YYYY-MM-DD')}.pdf`;
      if (disposition) {
        const match = disposition.match(/filename\*?=(?:UTF-8'')?"?([^"\n;]+)"?/i);
        if (match?.[1]) fileName = decodeURIComponent(match[1]);
      }

      const blob = new Blob([response.data], { type: 'application/pdf' });
      const objectUrl = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = objectUrl;
      link.download = fileName;
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
      window.URL.revokeObjectURL(objectUrl);

      message.success('Purchases exported as PDF successfully');
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to export purchases as PDF');
    } finally {
      setExportPdfLoading(false);
    }
  };

  const handleAdd = () => {
    setEditingId(null);
    form.resetFields();
    setLots([makeLot()]);
    setLotFieldErrors({});
    setOpen(true);
  };

  const handleView = async (id: string) => {
    setViewLoading(true);
    setViewOpen(true);
    try {
      const res = await jwtAxios.get(`${ENTITY_ENDPOINT}/${id}`);
      const record = res.data?.result ?? res.data;
      setViewRecord(record);
    } catch (err: any) {
      message.error(err.response?.data?.message || `Failed to load ${ENTITY_LABEL.toLowerCase()}`);
      setViewOpen(false);
    } finally {
      setViewLoading(false);
    }
  };

  // Edit button click — GET the single record by id, then populate the
  // same form/modal used for "Add". We just switch modes with editingId.
  const handleEdit = async (id: string) => {
    setLoading(true);
    try {
      // setIsInitializing(true);
      const res = await jwtAxios.get(`${ENTITY_ENDPOINT}/${id}`);
      // Single-record response may or may not be wrapped in "result" —
      // handle both just in case.
      const record = res.data?.result ?? res.data;

      const supplierName =
        record.supplier?.name ||
        record.cashSupplierName ||
        record.supplierName ||
        record.quickSupplierName ||
        'Cash Supplier (Local Market)';

      let derivedRateType = 'UNIT';
      if (record.unit === 'KG') {
        derivedRateType = 'KG';
      } else if (Number(record.quantity) > 0 && Number(record.ratePerUnit) > 0) {
        // Check if goodsTotal matches quantity * rate
        const qTimesR = Number(record.quantity) * Number(record.ratePerUnit);
        // const bTimesR = Number(record.bags) * Number(record.ratePerUnit);
        const goodsTotal = Number(record.goodsTotal);
        if (Math.abs(goodsTotal - qTimesR) < 1) {
          derivedRateType = 'KG';
        }
      }

      const expense = record.expenses?.[0];

      form.setFieldsValue({
        purchaseDate: record.purchaseDate ? dayjs(record.purchaseDate) : undefined,
        billNo: record.billNo,
        supplierId: record.supplierId ? String(record.supplierId) : '',
        cashSupplierName: record.cashSupplierName,
        vegetableId: record.vegetableId ? String(record.vegetableId) : undefined,
        lotNo: record.lotNo,
        unit: record.unit,
        quantity: Number(record.quantity) > 0 ? Number(record.quantity) : undefined,
        bags: Number(record.bags) > 0 ? Number(record.bags) : undefined,
        rateType: derivedRateType,
        ratePerUnit: Number(record.ratePerUnit),
        transportFee: Number(record.transportFee ?? 0),
        loadingUnloadingFee: Number(record.loadingUnloadingFee ?? 0),
        otherCharges: Number(record.otherCharges ?? 0),
        thaiyalCharges: Number(record.thaiyalCharges ?? 0),
        extraCharges: Number(record.extraCharges ?? 0),
        advanceAmount: Number(record.advanceAmount ?? 0),
        expenseAmount: expense ? Number(expense.amount) : undefined,
        expensePaymentMode: expense ? expense.paymentMode : undefined,
        arrivalDate: record.arrivalDate ? dayjs(record.arrivalDate) : undefined,
        remarks: record.remarks,
      });

      setEditingNames({
        supplier: supplierName,
        vegetable: record.vegetable?.name,
      });

      setEditingId(id);
      setLotFieldErrors({});
      setOpen(true);
      // setTimeout(() => setIsInitializing(false), 0);
    } catch (err: any) {
      // setIsInitializing(false);
      message.error(err.response?.data?.message || `Failed to load ${ENTITY_LABEL.toLowerCase()}`);
    } finally {
      setLoading(false);
    }
  };

  // -----------------------------
  // Fetch meta (units + payment statuses) — ONLY ONCE on mount.
  // No auth / no body needed per the API doc.
  // -----------------------------
  const fetchMeta = async () => {
    try {
      const res = await jwtAxios.get(ENDPOINTS.PURCHASE_META);
      const result = res.data?.result || {
        purchaseUnits: [],
        paymentStatuses: [],
        suppliers: [],
        vegetables: [],
      };

      setMeta(result);
      setSuppliers(result.suppliers || []);
      setVegetables(result.vegetables || []);
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to fetch purchase meta');
      setMeta({ purchaseUnits: [], suppliers: [], vegetables: [] });
      setSuppliers([]);
      setVegetables([]);
    }
  };

  // -----------------------------
  // Fetch list — runs on initial load, page change, page-size change,
  // and whenever a search or filter is triggered.
  // -----------------------------
  const fetchData = async (
    page: number = pagination.current,
    limit: number = pagination.pageSize,
    search: string = searchText,
    range: [Dayjs, Dayjs] | null = dateRange
  ) => {
    setLoading(true);

    try {
      // Only add params to the query string when they're actually set.
      let url = ENTITY_ENDPOINT + `?page=${page}&limit=${limit}&search=${search}`;
      if (range) {
        url += `&dateFrom=${range[0].format('YYYY-MM-DD')}&dateTo=${range[1].format('YYYY-MM-DD')}`;
      }

      const res = await jwtAxios.get(url);
      // message.success(res?.data?.message);
      // Response shape: { message, result: { data: [...], meta: { total, page, limit, totalPages } } }
      const records = res.data?.result?.data || [];
      const metaInfo = res.data?.result?.meta || {};

      const formattedData = records.map((item: any) => ({
        key: item.id,
        ...item,
      }));

      setData(formattedData);
      setPagination((prev) => ({
        ...prev,
        current: metaInfo.page ?? page,
        pageSize: metaInfo.limit ?? limit,
        total: metaInfo.total ?? prev.total,
        totalPages: metaInfo.totalPages ?? prev.totalPages,
      }));
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to fetch data');
      setData([]);
    } finally {
      setLoading(false);
    }
  };

  // Initial load: meta, suppliers, vegetables and first page of records.
  useEffect(() => {
    const fetchPaymentModes = async () => {
      try {
        const res = await jwtAxios.get(ENDPOINTS.PAYMENTMODES);
        if (res.data?.success && res.data?.PaymentMode) {
          const modes = Object.keys(res.data.PaymentMode).map((key) => ({ label: key, value: key }));
          setPaymentModes(modes);
        }
      } catch (err) {
        setPaymentModes([{ label: 'CASH', value: 'CASH' }, { label: 'BANK', value: 'BANK' }, { label: 'UPI', value: 'UPI' }]);
      }
    };
    fetchMeta();
    fetchPaymentModes();
    fetchData(1, pagination.pageSize, '');
  }, []);

  // -----------------------------
  // Search — onChange just updates the input text; onSearch (Enter / icon)
  // actually triggers the API call and resets to page 1.
  // -----------------------------
  const handleSearch = (value: string) => {
    fetchData(1, pagination.pageSize, value, dateRange);
  };

  // Date range filter — same idea.
  const handleDateRangeChange = (values: any) => {
    const range = values ? (values as [Dayjs, Dayjs]) : null;
    setDateRange(range);
    fetchData(1, pagination.pageSize, searchText, range);
  };

  // Delete — actual API call happens only after the user confirms
  // in the Popconfirm popup (see the Actions column below).
  const handleDelete = async (id: string) => {
    setLoading(true);
    try {
      const res = await jwtAxios.delete(`${ENTITY_ENDPOINT}/${id}`);
      message.success(res.data?.message || `${ENTITY_LABEL} deleted successfully`);
      fetchData(pagination.current, pagination.pageSize, searchText, dateRange);
    } catch (err: any) {
      message.error(err.response?.data?.message || `Failed to delete ${ENTITY_LABEL.toLowerCase()}`);
    } finally {
      setLoading(false);
    }
  };

  const handleCloseLot = async (id: string) => {
    setLoading(true);
    try {
      const res = await jwtAxios.patch(`${ENTITY_ENDPOINT}/${id}/close`);
      message.success(res.data?.message || 'Lot closed successfully');
      fetchData(pagination.current, pagination.pageSize, searchText, dateRange);
    } catch (err: any) {
      message.error(err.response?.data?.message || 'Failed to close lot');
    } finally {
      setLoading(false);
    }
  };

  const handleSubmit = async (values: any) => {
    setLoading(true);

    try {
      const supplierId = values.supplierId ?? form.getFieldValue('supplierId');
      const cashSupplierName = form.getFieldValue('cashSupplierName');
      const isQuickPurchase = editingId && (!supplierId || supplierId === '') && (cashSupplierName || editingNames.supplier);

      // ── EDIT MODE: single lot ──────────────────────────────────
      if (editingId) {
        const vegetableId = values.vegetableId ?? form.getFieldValue('vegetableId');
        const payload: any = {
          purchaseDate: values.purchaseDate?.format('YYYY-MM-DD'),
          billNo: values.billNo,
          lotNo: values.lotNo,
          unit: values.unit,
          rateType: values.rateType,
          bags: values.bags,
          quantity: values.quantity,
          ratePerUnit: values.ratePerUnit,
          transportFee: values.transportFee ?? 0,
          loadingUnloadingFee: values.loadingUnloadingFee ?? 0,
          otherCharges: values.otherCharges ?? 0,
          thaiyalCharges: values.thaiyalCharges ?? 0,
          extraCharges: values.extraCharges ?? 0,
          advanceAmount: values.advanceAmount ?? 0,
          expenseAmount: values.expenseAmount ?? null,
          expensePaymentMode: values.expensePaymentMode,
          arrivalDate: values.arrivalDate?.format('YYYY-MM-DD'),
          remarks: values.remarks ?? '',
          supplierId: supplierId && supplierId !== '' ? String(supplierId) : null,
          cashSupplierName: isQuickPurchase ? (cashSupplierName || editingNames.supplier || 'Cash Supplier (Local Market)') : null,
          vegetableId: String(vegetableId),
        };
        const response = await jwtAxios.put(`${ENTITY_ENDPOINT}/${editingId}`, payload);
        message.success(response.data?.message || `${ENTITY_LABEL} updated successfully`);
        setOpen(false);
        setEditingId(null);
        form.resetFields();
        fetchData(pagination.current, pagination.pageSize, searchText, dateRange);
        return;
      }

      // Shared charges for the whole purchase
      const isBulkQuickPurchase = (!supplierId || supplierId === '') && !!cashSupplierName;
      const sharedPayload = {
        purchaseDate: values.purchaseDate?.format('YYYY-MM-DD'),
        billNo: values.billNo,
        supplierId: supplierId && supplierId !== '' ? String(supplierId) : null,
        cashSupplierName: isBulkQuickPurchase ? cashSupplierName : null,
        transportFee: values.transportFee ?? 0,
        loadingUnloadingFee: values.loadingUnloadingFee ?? 0,
        otherCharges: values.otherCharges ?? 0,
        thaiyalCharges: values.thaiyalCharges ?? 0,
        advanceAmount: values.advanceAmount ?? 0,
        expenseAmount: values.expenseAmount ?? 0,
        expensePaymentMode: values.expensePaymentMode,
        arrivalDate: values.arrivalDate?.format('YYYY-MM-DD'),
        remarks: values.remarks ?? '',
      };

      // Build a single array of lot payloads and POST them all at once
      const purchasesPayload = lots.map((lot) => ({
        ...sharedPayload,
        vegetableId: lot.vegetableId != null ? String(lot.vegetableId) : undefined,
        lotNo: lot.lotNo,
        unit: lot.unit,
        rateType: lot.rateType,
        bags: lot.bags,
        quantity: lot.quantity,
        ratePerUnit: lot.ratePerUnit,
        extraCharges: lot.extraCharges ?? 0,
      }));

      const response = await jwtAxios.post(ENDPOINTS.PURCHASE_BULK, {
        purchases: purchasesPayload,
      });

      const { created = [], errors: lotErrors = [] } = response.data?.result ?? {};
      const successCount: number = created.length;

      // Map business-logic errors back to the lotNo field of the failing lot
      if (lotErrors.length > 0) {
        const newFieldErrors: Record<number, Record<string, string>> = {};
        lotErrors.forEach((e: { index: number; lotNo: string; message: string }) => {
          // Business-logic errors (lot availability, vegetable conflict) always relate to the lotNo
          newFieldErrors[e.index] = { ...(newFieldErrors[e.index] ?? {}), lotNo: e.message };
        });
        setLotFieldErrors(newFieldErrors);
      }

      if (successCount > 0) {
        message.success(`${successCount} lot${successCount > 1 ? 's' : ''} added successfully`);
        setOpen(false);
        setEditingId(null);
        setLots([makeLot()]);
        setLotFieldErrors({});
        form.resetFields();
        fetchData(pagination.current, pagination.pageSize, searchText, dateRange);
      } else {
        // All lots failed — stay on the form so the user can see inline errors
        message.error('No purchases were saved. Please fix the errors shown on each lot.');
      }

    } catch (err: any) {
      const responseData = err.response?.data;
      const rawErrors: Record<string, string> = responseData?.errors ?? {};

      // Separate lot-level Zod field errors (path: purchases.N.fieldName)
      // from top-level form field errors
      const newLotFieldErrors: Record<number, Record<string, string>> = {};
      const topLevelErrors: Array<{ name: string; errors: string[] }> = [];

      Object.entries(rawErrors).forEach(([path, errMsg]) => {
        // Matches paths like "purchases.0.lotNo" or "purchases.2.ratePerUnit"
        const lotMatch = path.match(/^purchases\.([0-9]+)\.(.+)$/);
        if (lotMatch) {
          const idx = parseInt(lotMatch[1], 10);
          const field = lotMatch[2];
          newLotFieldErrors[idx] = { ...(newLotFieldErrors[idx] ?? {}), [field]: String(errMsg) };
        } else {
          topLevelErrors.push({ name: path, errors: [String(errMsg)] });
        }
      });

      if (Object.keys(newLotFieldErrors).length > 0) {
        setLotFieldErrors(newLotFieldErrors);
      }
      if (topLevelErrors.length > 0) {
        form.setFields(topLevelErrors);
      }

      if (Object.keys(rawErrors).length > 0) {
        message.error(responseData?.message || 'Please fix the highlighted fields');
      } else {
        message.error(responseData?.message || `Failed to ${editingId ? 'update' : 'add'} ${ENTITY_LABEL.toLowerCase()}`);
      }
    } finally {
      setLoading(false);
    }
  };

  const columns = [
    {
      title: "ID",
      dataIndex: "id",
    },
    {
      title: 'Bill No',
      dataIndex: 'billNo',
      render: (billNo: string) => {
        return billNo ? <Tag color="blue">{billNo}</Tag> : <Tag color='red'>-</Tag>;
      }
    }, {
      title: 'Type',
      dataIndex: 'purchaseType',
      render: (purchaseType: string) => {
        return purchaseType == "COMMISSION_ARRIVAL" ? <Tag color="yellow">Arrival</Tag> : <Tag color='cyan'>Direct</Tag>;
      }
    },
    {
      title: 'Lot No',
      dataIndex: 'lotNo',
    },
    {
      title: 'Supplier',
      dataIndex: 'supplier',
      render: (supplier: DataRecord['supplier'], record: any) =>
        supplier ? supplier.name : (record.cashSupplierName || record.supplierName || record.quickSupplierName || 'Cash Supplier'),
    },
    {
      title: 'Vegetable',
      dataIndex: 'vegetable',
      render: (vegetable: DataRecord['vegetable']) => (vegetable ? vegetable.name : '-'),
    },
    {
      title: 'Quantity',
      dataIndex: 'quantity',
      ellipsis: true,
    },
    {
      title: "Bags/Boxes",
      dataIndex: "bags",
      render: (bags: number | string | null, record: DataRecord) => {
        const value = Number(bags);

        return value > 0 ? (
          <Tag color="blue">
            {value} {record.unit}
          </Tag>
        ) : (
          <Tag color="red">-</Tag>
        );
      },
    },
    {
      title: "Remaining Stock",
      dataIndex: "remainingQuantity",
      render: (remainingQuantity: string, record: DataRecord) => {
        const remaining = Number(remainingQuantity);
        const total = Number(record.quantity);

        // --- OLD CODE (Commented per request) ---
        // let colorOld = "green";
        // if (remaining === 0) { colorOld = "red"; } else if (remaining <= total * 0.2) { colorOld = "orange"; }
        // return (
        //   <div className="flex items-center gap-2">
        //     <span className="font-medium">
        //       <Tag color={colorOld}>
        //         {remaining} / {total} KG
        //         {record.weightPerBag ? ` / ${Number(record.remainingBags ?? 0)} ${record.unit}` : ""}
        //       </Tag>
        //     </span>
        //     {remaining === 0 && <Tag color="volcano" title="Fully depleted — lot number can be reused">♻</Tag>}
        //   </div>
        // );
        // ----------------------------------------

        const remainingBags = Number(record.remainingBags ?? 0);
        const totalBags = Number(record.bags ?? 0);

        const isBagOnly = record.unit !== 'KG' && total <= 0;
        const isDepleted = isBagOnly ? remainingBags <= 0 : remaining <= 0;
        const isLow = isBagOnly ? remainingBags <= totalBags * 0.2 : remaining <= total * 0.2;

        let color = "green";
        if (record.status === "CLOSED") {
          color = "default";
        } else if (isDepleted) {
          color = "red";
        } else if (isLow) {
          color = "orange";
        }

        return (
          <div className="flex items-center gap-2">
            <span className="font-medium">
              <Tag color={color}>
                {record.status === "CLOSED" ? (
                  "CLOSED"
                ) : isBagOnly ? (
                  `${remainingBags} / ${totalBags} ${record.unit}`
                ) : (
                  <>
                    {remaining} / {total} KG
                    {totalBags > 0
                      ? ` | ${remainingBags} / ${totalBags} ${record.unit}`
                      : ""}
                  </>
                )}
              </Tag>
            </span>
            {record.status === "CLOSED" ? (
              <Tag color="default">Closed</Tag>
            ) : isDepleted && (
              <Tag color="volcano" title="Fully depleted — lot number can be reused">♻</Tag>
            )}
          </div>
        );
      },
    },
    {
      title: 'Rate/Unit',
      dataIndex: 'ratePerUnit',
      render: (rate: string) => Number(rate).toFixed(2),
    },
    {
      title: 'Grand Total',
      dataIndex: 'grandTotal',
      render: (total: string) => <Tag color="cyan">₹{Number(total).toFixed(2)}</Tag>,
    },
    {
      title: 'Cost/Unit',
      dataIndex: 'costPerUnit',
      render: (cost: string) => <Tag color="magenta">₹{Number(cost).toFixed(2)}</Tag>,
    },
    {
      title: 'Actions',
      render: (_: any, record: any) => (
        <Space>
          {record.purchaseType !== "COMMISSION_ARRIVAL" && (<Popover content="Click to Edit">
            <Button type="link" icon={<EditOutlined />} onClick={() => handleEdit(record.id)}>
            </Button>
          </Popover>)}
          <Popover content="Click to View">
            <Button type="link" icon={<EyeOutlined />} onClick={() => handleView(record.id)}>
            </Button>
          </Popover>
          {record.vegetable?.isFlexible && record.status !== "CLOSED" && (
            <Popover content="Close Flexible Lot (Deplete remaining balance)">
              <Popconfirm
                title="Close Flexible Lot"
                description={`Are you sure you want to close lot "${record.lotNo}"? It will no longer be available for sale.`}
                okText="Yes, Close Lot"
                cancelText="Cancel"
                okButtonProps={{ danger: true }}
                onConfirm={() => handleCloseLot(record.id)}
              >
                <Button
                  size="small"
                  icon={<CheckCircleOutlined />}
                  style={{ color: "#d97706", borderColor: "#f59e0b" }}
                >
                  Close Lot
                </Button>
              </Popconfirm>
            </Popover>
          )}
          <Popover content="Click to Delete">
            <Popconfirm
              title={`Delete ${ENTITY_LABEL.toLowerCase()}`}
              description={`Are you sure you want to delete "${record.lotNo}"?`}
              okText="Delete"
              cancelText="Cancel"
              okButtonProps={{ danger: true }}
              onConfirm={() => handleDelete(record.id)} // API call fires only after confirm
            >
              <Button danger type="link" icon={<DeleteOutlined />}>
              </Button>
            </Popconfirm>
          </Popover>
        </Space>
      ),
    },
  ];

  const totalLotsAmount = lots.reduce((acc, lot) => {
    const lotGoodsTotal = (lot.unit === 'KG' || lot.rateType === 'KG')
      ? (lot.quantity ?? 0) * (lot.ratePerUnit ?? 0)
      : (lot.bags ?? 0) * (lot.ratePerUnit ?? 0);
    return acc + lotGoodsTotal + (lot.extraCharges ?? 0);
  }, 0);

  const editModeAmount = (selectedUnit === 'KG' || rateTypeVal === 'KG')
    ? (quantityVal ?? 0) * (rateVal ?? 0)
    : (bagsVal ?? 0) * (rateVal ?? 0);

  const editModeTotalCost = editModeAmount + (extraChargesVal ?? 0);
  let editModeCostPerUnit = 0;
  if (editModeTotalCost > 0) {
    if (selectedUnit === 'KG' || rateTypeVal === 'KG') {
      editModeCostPerUnit = quantityVal ? editModeTotalCost / quantityVal : 0;
    } else {
      editModeCostPerUnit = bagsVal ? editModeTotalCost / bagsVal : 0;
    }
  }

  return (
    <div>
      <Spin spinning={loading}>
        <AppContainer
          title={`${ENTITY_LABEL}`}
          headerAction={
            <Space>
              <Button
                icon={<DownloadOutlined />}
                style={{ color: '#52c41a', borderColor: '#52c41a' }}
                onClick={handleExport}
                loading={exportLoading}
              >
                Export Excel
              </Button>
              <Button
                icon={<DownloadOutlined />}
                style={{ color: '#f5222d', borderColor: '#f5222d' }}
                onClick={handleExportPdf}
                loading={exportPdfLoading}
              >
                Export PDF
              </Button>
              <Button
                type="primary"
                icon={<ThunderboltOutlined />}
                style={{ backgroundColor: '#1677ff' }}
                onClick={() => navigate('/purchase/cash-purchases')}
              >
                Cash Purchases
              </Button>
              <Button
                type="primary"
                icon={<PlusOutlined />}
                onClick={handleAdd}
                className="bg-green-600"
              >
                Add {ENTITY_LABEL}
              </Button>
            </Space>
          }
        >
          {/* Toolbar Section */}
          <div className="flex justify-between items-center mb-4 pb-4 border-b border-gray-200">
            <Space>
              <RangePicker value={dateRange as any} onChange={handleDateRangeChange} />
              <Input.Search
                placeholder="Search..."

                value={searchText}
                onChange={(e) => setSearchText(e.target.value)} // just updates what's typed
                onSearch={handleSearch} // fires the API call (Enter / icon click)
                allowClear
                style={{ width: 200 }}
              />
            </Space>
          </div>

          {/* Table Section */}
          <Table
            rowKey="key"
            columns={columns}
            dataSource={data}
            loading={loading}
            scroll={{ x: 'max-content', y: 400 }}
            pagination={{
              current: pagination.current,
              pageSize: pagination.pageSize,
              total: pagination.total,
              showSizeChanger: true,
            }}
            onChange={(pageInfo) => {
              fetchData(pageInfo.current!, pageInfo.pageSize!, searchText, dateRange);
            }}
          />
          <div className="text-center mt-2">
            <Tag color="cyan">
              Page {pagination.current} of {pagination.totalPages}
            </Tag>
          </div>
        </AppContainer>

        <Modal
          title={
            <span>
              {editingId ? `Edit ${ENTITY_LABEL}` : `Add ${ENTITY_LABEL}`}
              {!editingId && lots.length > 1 && (
                <Tag color="blue" style={{ marginLeft: 8 }}>
                  {lots.length} Lots
                </Tag>
              )}
            </span>
          }
          open={open}
          onCancel={() => {
            setOpen(false);
            setEditingId(null);
            setLots([makeLot()]);
            setLotFieldErrors({});
            form.resetFields();
          }}
          onOk={() => {
            if (!editingId) {
              Modal.confirm({
                title: 'Confirm Purchase Submission',
                content:
                  `You are about to add ${lots.length} lot${lots.length > 1 ? 's' : ''}. Please double-check all details before submitting.`,
                okText: 'Submit',
                cancelText: 'Cancel',
                onOk: () => form.submit(),
              });
            } else {
              form.submit();
            }
          }}
          confirmLoading={loading}
          okText="Submit"
          width="min(90vw, 1000px)"
          centered
          styles={{
            body: {
              maxHeight: '80vh',
              overflowY: 'auto',
              overflowX: 'hidden',
              paddingRight: 4,
            },
          }}
        >
          <Form form={form} layout="vertical" onFinish={handleSubmit}>
            {/* ── Shared Header Fields ─────────────────────────── */}
            <Row gutter={16}>
              <Col xs={24} sm={12} md={8}>
                <Form.Item label="Purchase Date" name="purchaseDate" rules={[{ required: true }]}>
                  <DatePicker
                    style={{ width: '100%' }}
                    disabledDate={(current) => current && current > dayjs().endOf('day')}
                  />
                </Form.Item>
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Form.Item label="Bill No" name="billNo" rules={[{ required: true }]}>
                  <Input placeholder="e.g. PUR-B-3912" />
                </Form.Item>
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Form.Item
                  label="Supplier"
                  name="supplierId"
                  rules={[
                    {
                      validator: (_, value) => {
                        const isQuickPurchaseEdit =
                          editingId &&
                          (!value || value === '') &&
                          (form.getFieldValue('cashSupplierName') || editingNames.supplier);
                        if (isQuickPurchaseEdit || (value && value !== '')) return Promise.resolve();
                        return Promise.reject(new Error('Supplier is required'));
                      },
                    },
                  ]}
                >
                  <Select
                    showSearch
                    placeholder="Select a supplier"
                    optionFilterProp="label"
                    disabled={!!editingId}
                    filterOption={(input, option) =>
                      (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
                    }
                    options={
                      editingId && editingNames.supplier
                        ? [
                          { label: editingNames.supplier, value: form.getFieldValue('supplierId') ?? '' },
                          ...suppliers
                            .filter((s) => s.id !== form.getFieldValue('supplierId'))
                            .map((s) => ({ label: s.name, value: s.id })),
                        ]
                        : suppliers.map((s) => ({ label: s.name, value: s.id }))
                    }
                  />
                </Form.Item>
                {supplierIdVal && (
                  <div style={{ marginTop: -16, marginBottom: 16, fontSize: 12, color: '#888' }}>
                    Outstanding Balance:{' '}
                    <span style={{ fontWeight: 600, color: Number(suppliers.find(s => String(s.id) === String(supplierIdVal))?.outstandingBalance) > 0 ? '#f5222d' : '#52c41a' }}>
                      ₹{Number(suppliers.find(s => String(s.id) === String(supplierIdVal))?.outstandingBalance || 0).toFixed(2)}
                    </span>
                  </div>
                )}
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Form.Item label="Arrival Date" name="arrivalDate">
                  <DatePicker
                    style={{ width: '100%' }}
                    disabledDate={(current) => {
                      if (!current) return false;
                      const isFuture = current > dayjs().endOf('day');
                      const isBeforePurchase = purchaseDateVal
                        ? current < dayjs(purchaseDateVal).startOf('day')
                        : false;
                      return isFuture || isBeforePurchase;
                    }}
                  />
                </Form.Item>
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Form.Item label="Expense Payment Mode" name="expensePaymentMode">
                  <Select options={paymentModes} placeholder="Select Payment Mode" />
                </Form.Item>
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Form.Item label="Expense Amount" name="expenseAmount">
                  <InputNumber className='w-full!' min={0} step={0.01} />
                </Form.Item>
              </Col>

              <Col xs={24} sm={24} md={24}>
                <Form.Item label="Remarks" name="remarks">
                  <Input.TextArea rows={2} />
                </Form.Item>
              </Col>
            </Row>

            {/* ── ADD MODE: Repeatable lot rows ─────────────────── */}
            {!editingId && (
              <>
                <Divider orientation="horizontal" titlePlacement="left" style={{ margin: '4px 0 12px', fontSize: 13, color: '#1677ff', fontWeight: 600 }}>
                  Lot Details
                </Divider>

                {lots.map((lot, idx) => (
                  <LotRowForm
                    key={lot.id}
                    lot={lot}
                    index={idx}
                    purchaseUnits={meta.purchaseUnits}
                    vegetables={vegetables}
                    canDelete={lots.length > 1}
                    onChange={updateLot}
                    onDelete={removeLot}
                    fieldErrors={lotFieldErrors[idx] ?? {}}
                    onFieldErrorClear={clearLotFieldError}
                  />
                ))}

                <div className="flex justify-end mb-4">
                  <div className="px-4 py-2 bg-[#f6ffed] border border-[#b7eb8f] rounded-lg">
                    <span className="text-sm text-[#595959] mr-2">Total Amount:</span>
                    <span className="text-lg font-bold text-[#52c41a]">
                      {new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR' }).format(totalLotsAmount)}
                    </span>
                  </div>
                </div>

                <Button
                  type="dashed"
                  block
                  icon={<PlusOutlined />}
                  onClick={addLot}
                  style={{ marginBottom: 16, borderColor: '#1677ff', color: '#1677ff' }}
                >
                  Add Another Lot
                </Button>
              </>
            )}

            {/* ── EDIT MODE: Single lot fields ───────────────────── */}
            {editingId && (
              <Row gutter={16}>
                <Col xs={24} sm={12} md={8}>
                  <Form.Item label="Vegetable" name="vegetableId" rules={[{ required: true }]}>
                    <Select
                      showSearch
                      placeholder="Select a vegetable"
                      optionFilterProp="label"
                      disabled={!!editingId}
                      filterOption={(input, option) =>
                        (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
                      }
                      options={
                        editingId && editingNames.vegetable
                          ? [
                            { label: editingNames.vegetable, value: form.getFieldValue('vegetableId') },
                            ...vegetables
                              .filter((v) => v.id !== form.getFieldValue('vegetableId'))
                              .map((v) => ({ label: v.name, value: v.id })),
                          ]
                          : vegetables.map((v) => ({ label: v.name, value: v.id }))
                      }
                    />
                  </Form.Item>
                </Col>

                <Col xs={24} sm={12} md={8}>
                  <Form.Item
                    label="Lot No"
                    name="lotNo"
                    rules={[{ required: true }]}
                  >
                    <Input placeholder="LOT-VEG-NAME-XX" />
                  </Form.Item>
                </Col>

                <Col xs={24} sm={12} md={8}>
                  <Form.Item label="Unit" name="unit" rules={[{ required: true }]}>
                    <Select
                      options={meta.purchaseUnits}
                      placeholder="Select a unit"
                    />
                  </Form.Item>
                </Col>

                {selectedUnit !== 'KG' && (
                  <Col xs={24} sm={12} md={8}>
                    <Form.Item
                      label="Rate Type"
                      name="rateType"
                      rules={[{ required: true }]}
                      initialValue="UNIT"
                    >
                      <Select
                        options={[
                          { value: 'UNIT', label: `Rate / ${selectedUnit === 'BOX' ? 'Box' : (selectedUnit === 'THAAR' ? 'Thaar' : (selectedUnit === 'PIECES' ? 'Piece' : 'Bag'))}` },
                          { value: 'KG', label: 'Rate / Kg' },
                        ]}
                      />
                    </Form.Item>
                  </Col>
                )}

                {selectedUnit !== 'KG' && (
                  <Col xs={24} sm={12} md={8}>
                    <Form.Item
                      label={selectedUnit === 'THAAR' ? 'Number of Thaar' : (selectedUnit === 'PIECES' ? 'Number of Pieces' : 'Number of Boxes/Bags')}
                      name="bags"
                      rules={[{ required: true, message: 'Please enter count' }]}
                    >
                      <InputNumber
                        style={{ width: '100%' }}
                        min={1}
                        step={1}
                        precision={0}
                      />
                    </Form.Item>
                  </Col>
                )}

                {(selectedUnit === 'KG' || rateTypeVal === 'KG') && (
                  <Col xs={24} sm={12} md={8}>
                    <Form.Item
                      label="Quantity (Kg)"
                      name="quantity"
                      rules={[{ required: selectedUnit === 'KG' || rateTypeVal === 'KG', message: 'Please enter a quantity' }]}
                    >
                      <InputNumber
                        style={{ width: '100%' }}
                        min={0}
                        step={1}
                      />
                    </Form.Item>
                  </Col>
                )}

                <Col xs={24} sm={12} md={8}>
                  <Form.Item
                    label={selectedUnit === 'KG' ? 'Rate / Kg' : (rateTypeVal === 'KG' ? 'Rate / Kg' : `Rate / ${selectedUnit === 'BOX' ? 'Box' : (selectedUnit === 'THAAR' ? 'Thaar' : (selectedUnit === 'PIECES' ? 'Piece' : 'Bag'))}`)}
                    name="ratePerUnit"
                    rules={[{ required: true, message: 'Please enter a rate' }]}
                  >
                    <InputNumber style={{ width: '100%' }} min={0} step={0.01} />
                  </Form.Item>
                </Col>

                <Col xs={24} sm={12} md={8}>
                  <Form.Item
                    label="Extra Charges"
                    name="extraCharges"
                    initialValue={0}
                  >
                    <InputNumber style={{ width: '100%' }} min={0} step={0.01} />
                  </Form.Item>
                </Col>
              </Row>
            )}

            {editingId && (
              <div className="flex justify-end mb-4">
                <div className="px-4 py-2 bg-[#f6ffed] border border-[#b7eb8f] rounded-lg">
                  <span className="text-sm text-[#595959] mr-2">Total Amount:</span>
                  <span className="text-lg font-bold text-[#52c41a] mr-4">
                    {new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR' }).format(editModeTotalCost)}
                  </span>
                  <span className="text-sm text-[#595959] mr-2">Cost/Unit:</span>
                  <span className="text-lg font-bold text-[#eb2f96]">
                    {new Intl.NumberFormat('en-IN', { style: 'currency', currency: 'INR' }).format(editModeCostPerUnit)}
                  </span>
                </div>
              </div>
            )}

            {/* ── Shared Charges (both modes) ───────────────────── */}
            {/* <Divider orientation="horizontal" titlePlacement="left" style={{ margin: '4px 0 12px', fontSize: 13, color: '#595959', fontWeight: 600 }}>
              Charges &amp; Payment
            </Divider>

            <Row gutter={16}>
              <Col xs={24} sm={12} md={8}>
                <Form.Item label="Transport Fee" name="transportFee" initialValue={0}>
                  <InputNumber style={{ width: '100%' }} min={0} step={0.01} />
                </Form.Item>
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Form.Item label="Loading/Unloading Fee" name="loadingUnloadingFee" initialValue={0}>
                  <InputNumber style={{ width: '100%' }} min={0} step={0.01} />
                </Form.Item>
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Form.Item label="Other Charges" name="otherCharges" initialValue={0}>
                  <InputNumber style={{ width: '100%' }} min={0} step={0.01} />
                </Form.Item>
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Form.Item label="Thaiyal Charges" name="thaiyalCharges" initialValue={0}>
                  <InputNumber style={{ width: '100%' }} min={0} step={0.01} />
                </Form.Item>
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Form.Item label="Extra Charges" name="extraCharges" initialValue={0}>
                  <InputNumber style={{ width: '100%' }} min={0} step={0.01} />
                </Form.Item>
              </Col>

              <Col xs={24} sm={12} md={8}>
                <Form.Item label="Advance Amount" name="advanceAmount" initialValue={0}>
                  <InputNumber style={{ width: '100%' }} min={0} step={0.01} disabled={!!editingId} />
                </Form.Item>
              </Col>
            </Row> */}

            {/* ── Summary ──────────────────────────────────────── */}
            <Divider style={{ margin: '4px 0 12px' }} />
            {/* <div
              style={{
                background: 'linear-gradient(135deg, #f6ffed 0%, #e6f7ff 100%)',
                border: '1px solid #b7eb8f',
                borderRadius: 8,
                padding: '14px 20px',
                marginBottom: 8,
              }}
            >
              {!editingId && lots.length > 1 && (
                <div style={{ fontSize: 12, color: '#8c8c8c', marginBottom: 8 }}>
                  Combined summary for all {lots.length} lots
                </div>
              )}
              <Row gutter={[16, 8]}>
                <Col xs={12} sm={8}>
                  <div style={{ fontSize: 12, color: '#8c8c8c' }}>Goods Total</div>
                  <div style={{ fontSize: 16, fontWeight: 600 }}>₹{totalSummary.goodsTotal.toFixed(2)}</div>
                </Col>
                <Col xs={12} sm={8}>
                  <div style={{ fontSize: 12, color: '#8c8c8c' }}>Surcharges</div>
                  <div style={{ fontSize: 16, fontWeight: 600, color: '#fa8c16' }}>₹{totalSummary.surchargeTotal.toFixed(2)}</div>
                </Col>
                <Col xs={12} sm={8}>
                  <div style={{ fontSize: 12, color: '#8c8c8c' }}>Grand Total</div>
                  <div style={{ fontSize: 20, fontWeight: 700, color: '#52c41a' }}>₹{totalSummary.grandTotal.toFixed(2)}</div>
                </Col>
                <Col xs={12} sm={8}>
                  <div style={{ fontSize: 12, color: '#8c8c8c' }}>Cost / KG</div>
                  <div style={{ fontSize: 16, fontWeight: 600, color: '#722ed1' }}>₹{totalSummary.costPerUnit.toFixed(2)}</div>
                </Col>
                <Col xs={12} sm={8}>
                  <div style={{ fontSize: 12, color: '#8c8c8c' }}>Advance</div>
                  <div style={{ fontSize: 16, fontWeight: 600, color: '#1890ff' }}>₹{totalSummary.advance.toFixed(2)}</div>
                </Col>
                <Col xs={12} sm={8}>
                  <div style={{ fontSize: 12, color: '#8c8c8c' }}>Balance</div>
                  <div style={{ fontSize: 16, fontWeight: 600, color: totalSummary.balanceAmount < 0 ? '#f5222d' : '#595959' }}>
                    ₹{totalSummary.balanceAmount.toFixed(2)}
                  </div>
                </Col>
              </Row>
            </div> */}
          </Form>
        </Modal>

        {/* View Modal */}
        <Modal
          title={`${ENTITY_LABEL} Details`}
          open={viewOpen}
          onCancel={() => {
            setViewOpen(false);
            setViewRecord(null);
          }}
          footer={
            <Button
              onClick={() => {
                setViewOpen(false);
                setViewRecord(null);
              }}
            >
              Close
            </Button>
          }
          width="min(90vw, 800px)"
          centered
        >
          <Spin spinning={viewLoading}>
            {viewRecord && (
              <Descriptions column={2} bordered size="small">
                <Descriptions.Item label="Purchase Date">
                  {viewRecord.purchaseDate ? dayjs(viewRecord.purchaseDate).format('DD MMM YYYY') : '-'}
                </Descriptions.Item>
                <Descriptions.Item label="Bill No">{viewRecord.billNo || '-'}</Descriptions.Item>

                <Descriptions.Item label="Supplier">
                  {viewRecord.supplier?.name || viewRecord.cashSupplierName || viewRecord.supplierName || 'Cash Supplier'}
                </Descriptions.Item>
                <Descriptions.Item label="Vegetable">
                  {viewRecord.vegetable?.name || '-'}
                </Descriptions.Item>

                <Descriptions.Item label="Lot No">{viewRecord.lotNo || '-'}</Descriptions.Item>
                <Descriptions.Item label="Unit">{viewRecord.unit || '-'}</Descriptions.Item>

                <Descriptions.Item label="Quantity">
                  {Number(viewRecord.quantity ?? 0)} KG
                </Descriptions.Item>
                <Descriptions.Item label="Remaining Stock (Kg)">
                  {Number(viewRecord.remainingQuantity ?? 0)}
                </Descriptions.Item>
                <Descriptions.Item label="Remaining Bags">
                  {Number(viewRecord.remainingBags ?? 0)}
                </Descriptions.Item>

                {/* <Descriptions.Item label="Transport Fee">
                  {Number(viewRecord.transportFee ?? 0).toFixed(2)}
                </Descriptions.Item>
                <Descriptions.Item label="Loading/Unloading Fee">
                  {Number(viewRecord.loadingUnloadingFee ?? 0).toFixed(2)}
                </Descriptions.Item>

                <Descriptions.Item label="Other Charges">
                  {Number(viewRecord.otherCharges ?? 0).toFixed(2)}
                </Descriptions.Item>
                <Descriptions.Item label="Thaiyal Charges">
                  {Number(viewRecord.thaiyalCharges ?? 0).toFixed(2)}
                </Descriptions.Item>
                <Descriptions.Item label="Goods Total">
                  {Number(viewRecord.goodsTotal ?? 0).toFixed(2)}
                </Descriptions.Item>

                <Descriptions.Item label="Surcharge Total">
                  {Number(viewRecord.surchargeTotal ?? 0).toFixed(2)}
                </Descriptions.Item>
                <Descriptions.Item label="Grand Total">
                  {Number(viewRecord.grandTotal ?? 0).toFixed(2)}
                </Descriptions.Item>

                
                {/* <Descriptions.Item label="Advance Amount">
                  {Number(viewRecord.advanceAmount ?? 0).toFixed(2)}
                </Descriptions.Item> */}
                <Descriptions.Item label="Extra Charges">
                  {Number(viewRecord.extraCharges ?? 0).toFixed(2)}
                </Descriptions.Item>

                <Descriptions.Item label="Cost / Unit">
                  {Number(viewRecord.costPerUnit ?? 0).toFixed(2)}
                </Descriptions.Item>

                <Descriptions.Item label="Balance Amount">
                  {Number(viewRecord.balanceAmount ?? 0).toFixed(2)}
                </Descriptions.Item>

                <Descriptions.Item label="Arrival Date">
                  {viewRecord.arrivalDate ? dayjs(viewRecord.arrivalDate).format('DD MMM YYYY') : '-'}
                </Descriptions.Item>
                <Descriptions.Item label="Created At">
                  {viewRecord.createdAt ? dayjs(viewRecord.createdAt).format('DD MMM YYYY, hh:mm A') : '-'}
                </Descriptions.Item>

                <Descriptions.Item label="Purchase Type" span={2}>
                  {viewRecord.purchaseType.toUpperCase() === 'DIRECT' ? (
                    <Tag color="green">Direct</Tag>
                  ) : (
                    <Tag color="blue">Arrival</Tag>
                  )}
                </Descriptions.Item>

                <Descriptions.Item label="Remarks" span={2}>
                  {viewRecord.remarks || '-'}
                </Descriptions.Item>
              </Descriptions>
            )}
          </Spin>
        </Modal>
      </Spin>
    </div>
  );
};

export default Purchase;