﻿import { useEffect, useState } from 'react';
import api from '../api/client';
import type { StockBag, StockExpense, ItemType, ItemTypeVariant, FactoryRegister, StockProcessingBatch } from '../types';
import Modal from '../components/Modal';
import { Field, Input } from '../components/FormField';

const today = new Date().toISOString().slice(0, 10);

function fmtDate(d: string) {
  return new Date(d).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' });
}

type FactoryWithStock = FactoryRegister & {
  stock_bags: StockBag[];
  stock_bags_count: number;
};

interface ShiftGroup {
  key: string;
  description: string;
  bag_weight_kg: number;
  totalBags: number;
  mann: number;
  kg: number;
}

export default function Stock() {
  const [location, setLocation] = useState<'warehouse' | 'factory'>('warehouse');
  const [bags, setBags] = useState<StockBag[]>([]);
  const [totalMann, setTotalMann] = useState(0);
  const [totalKg, setTotalKg] = useState(0);
  const [itemTypes, setItemTypes] = useState<ItemType[]>([]);
  const [factoryRegisters, setFactoryRegisters] = useState<FactoryRegister[]>([]);

  // Add modal
  const [showModal, setShowModal] = useState(false);
  const [mode, setMode] = useState<'direct' | 'open'>('direct');
  const [selectedTypeId, setSelectedTypeId] = useState('');
  const [selectedVariantId, setSelectedVariantId] = useState('');
  const [bagCount, setBagCount] = useState('');
  const [addPricePerMann, setAddPricePerMann] = useState('');
  const [addFactoryId, setAddFactoryId] = useState('');
  const [addQueueNumber, setAddQueueNumber] = useState('');
  const [addExpectedDate, setAddExpectedDate] = useState('');
  const [saving, setSaving] = useState(false);

  // Shift to factory modal
  const [showShiftModal, setShowShiftModal] = useState(false);
  const [shiftBags, setShiftBags] = useState<Record<string, string>>({});
  const [shiftFactoryId, setShiftFactoryId] = useState('');
  const [shiftQueueNumber, setShiftQueueNumber] = useState('');
  const [shiftExpectedDate, setShiftExpectedDate] = useState('');
  const [shifting, setShifting] = useState(false);

  // Edit modal
  const [showEditModal, setShowEditModal] = useState(false);
  const [editing, setEditing] = useState<StockBag | null>(null);
  const [editMode, setEditMode] = useState<'direct' | 'open'>('direct');
  const [editLocation, setEditLocation] = useState<'warehouse' | 'factory'>('warehouse');
  const [editTypeId, setEditTypeId] = useState('');
  const [editVariantId, setEditVariantId] = useState('');
  const [editBagCount, setEditBagCount] = useState('');
  const [editPrice, setEditPrice] = useState('');
  const [editFactoryId, setEditFactoryId] = useState('');
  const [editQueueNumber, setEditQueueNumber] = useState('');
  const [editExpectedDate, setEditExpectedDate] = useState('');
  const [editSaving, setEditSaving] = useState(false);

  // Expense modal
  const [showExpModal, setShowExpModal] = useState(false);
  const [expStock, setExpStock] = useState<StockBag | null>(null);
  const [expForm, setExpForm] = useState({ amount: '', note: '' });
  const [expSaving, setExpSaving] = useState(false);

  // Schedule modal
  const [showScheduleModal, setShowScheduleModal] = useState(false);
  const [scheduleStock, setScheduleStock] = useState<StockBag | null>(null);
  const [schedBags, setSchedBags] = useState('');
  const [schedStartDate, setSchedStartDate] = useState('');
  const [schedDays, setSchedDays] = useState('');
  const [schedNotes, setSchedNotes] = useState('');
  const [schedSaving, setSchedSaving] = useState(false);
  const [schedError, setSchedError] = useState('');

  // ── Schedule Processing modal ────────────────────────────────────────────
  const [showProcModal, setShowProcModal] = useState(false);
  const [procLoading, setProcLoading] = useState(false);
  const [procFactoryRegs, setProcFactoryRegs] = useState<FactoryWithStock[]>([]);
  const [procFactoryId, setProcFactoryId] = useState('');
  const [procInputs, setProcInputs] = useState<Record<string, string>>({});
  const [procSentDate, setProcSentDate] = useState(today);
  const [procNotes, setProcNotes] = useState('');
  const [procSaving, setProcSaving] = useState(false);
  const [procError, setProcError] = useState('');

  const loadBags = (loc = location) =>
    api.get('/stock', { params: { location: loc } }).then(r => {
      setBags(r.data.bags);
      setTotalMann(r.data.total_mann);
      setTotalKg(r.data.total_kg);
    });

  const loadItemTypes = () =>
    api.get('/settings/item-types').then(r => setItemTypes(r.data));

  const loadFactoryRegisters = () =>
    api.get('/settings/factory-registers').then(r => setFactoryRegisters(r.data));

  useEffect(() => { loadBags(); loadItemTypes(); loadFactoryRegisters(); }, []);
  useEffect(() => { loadBags(location); }, [location]);

  // Summary stats
  const totalBags = bags.reduce((s, b) => s + b.quantity, 0);
  const totalValue = bags.reduce((s, b) => s + Number(b.total_price || 0), 0);
  const byItemMap = bags.reduce((acc, b) => {
    const key = b.description ?? 'Unknown';
    if (!acc[key]) acc[key] = { bags: 0, mann: 0, kg: 0, value: 0 };
    acc[key].bags += b.quantity;
    acc[key].mann += Number(b.quantity_mann || 0);
    acc[key].kg += Number(b.quantity_kg || 0);
    acc[key].value += Number(b.total_price || 0);
    return acc;
  }, {} as Record<string, { bags: number; mann: number; kg: number; value: number }>);
  const byItemList = Object.entries(byItemMap).map(([name, d]) => {
    const extraMann = Math.floor(d.kg / 40);
    return { name, bags: d.bags, mann: d.mann + extraMann, kg: +(d.kg % 40).toFixed(3), value: d.value };
  });

  // Only factory-processing item types can be shifted to factory
  const factoryItemTypes = itemTypes.filter(t => t.processing_type === 'factory');
  const factoryItemNames = new Set(factoryItemTypes.map(t => t.name));

  // Shift groups — only warehouse bags whose item type is 'factory' processing
  const shiftGroups: ShiftGroup[] = Object.values(
    bags.reduce((acc, b) => {
      if (!factoryItemNames.has(b.description ?? '')) return acc;
      const key = `${b.description}__${b.bag_weight_kg}`;
      if (!acc[key]) acc[key] = {
        key,
        description: b.description ?? '',
        bag_weight_kg: Number(b.bag_weight_kg),
        totalBags: 0, mann: 0, kg: 0,
      };
      acc[key].totalBags += b.quantity;
      acc[key].mann += Number(b.quantity_mann || 0);
      acc[key].kg += Number(b.quantity_kg || 0);
      return acc;
    }, {} as Record<string, ShiftGroup>)
  );

  // Add modal derived — factory location only shows factory-processing types
  const addItemTypes = location === 'factory' ? factoryItemTypes : itemTypes;
  const selectedType = itemTypes.find(t => String(t.id) === selectedTypeId) ?? null;
  const variants: ItemTypeVariant[] = selectedType?.variants ?? [];
  const selectedVariant = variants.find(v => String(v.id) === selectedVariantId) ?? null;
  const autoTotalKg = selectedVariant && bagCount ? Number(bagCount) * Number(selectedVariant.bag_weight_kg) : 0;
  const autoMann = autoTotalKg > 0 ? Math.floor(autoTotalKg / 40) : 0;
  const autoKg = autoTotalKg > 0 ? +(autoTotalKg % 40).toFixed(3) : 0;

  // Edit modal derived
  const editItemTypes = editLocation === 'factory' ? factoryItemTypes : itemTypes;
  const editType = itemTypes.find(t => String(t.id) === editTypeId) ?? null;
  const editVariants: ItemTypeVariant[] = editType?.variants ?? [];
  const editVariant = editVariants.find(v => String(v.id) === editVariantId) ?? null;
  const editTotalKg = editVariant && editBagCount ? Number(editBagCount) * Number(editVariant.bag_weight_kg) : 0;
  const editAutoMann = editTotalKg > 0 ? Math.floor(editTotalKg / 40) : 0;
  const editAutoKg = editTotalKg > 0 ? +(editTotalKg % 40).toFixed(3) : 0;

  const openAdd = () => {
    setMode('direct');
    setSelectedTypeId('');
    setSelectedVariantId('');
    setBagCount('');
    setAddPricePerMann('');
    setAddFactoryId('');
    setAddQueueNumber('');
    setAddExpectedDate('');
    setShowModal(true);
  };

  const openShiftModal = () => {
    setShiftBags({});
    setShiftFactoryId('');
    setShiftQueueNumber('');
    setShiftExpectedDate('');
    setShowShiftModal(true);
  };

  const onTypeChange = (id: string) => { setSelectedTypeId(id); setSelectedVariantId(''); };
  const onEditTypeChange = (id: string) => { setEditTypeId(id); setEditVariantId(''); };

  const openEditModal = (b: StockBag) => {
    setEditing(b);
    setEditMode((b.mode as 'direct' | 'open') ?? 'direct');
    setEditLocation(b.location);
    setEditBagCount(String(b.quantity));
    setEditPrice(b.price_per_mann != null ? String(b.price_per_mann) : '');
    setEditFactoryId(b.factory_register_id != null ? String(b.factory_register_id) : '');
    setEditQueueNumber(b.queue_number ?? '');
    setEditExpectedDate(b.expected_date ?? '');
    const matchedType = itemTypes.find(t => t.name === b.description);
    const matchedTypeId = matchedType ? String(matchedType.id) : '';
    setEditTypeId(matchedTypeId);
    if (matchedType?.variants) {
      const mv = matchedType.variants.find(v => Number(v.bag_weight_kg) === Number(b.bag_weight_kg));
      setEditVariantId(mv ? String(mv.id) : '');
    } else { setEditVariantId(''); }
    setShowEditModal(true);
  };

  const save = async () => {
    if (!selectedVariantId || !bagCount || !addPricePerMann) return;
    setSaving(true);
    try {
      await api.post('/stock', {
        mode, location,
        variant_id: Number(selectedVariantId),
        bag_count: Number(bagCount),
        price_per_mann: Number(addPricePerMann),
        factory_register_id: addFactoryId ? Number(addFactoryId) : null,
        queue_number: addQueueNumber.trim() || null,
        expected_date: addExpectedDate || null,
      });
      setShowModal(false);
      loadBags();
    } finally { setSaving(false); }
  };

  const confirmShift = async () => {
    const items = shiftGroups
      .filter(g => Number(shiftBags[g.key] || 0) > 0)
      .map(g => ({
        description: g.description,
        bag_weight_kg: g.bag_weight_kg,
        bags: Number(shiftBags[g.key]),
      }));
    if (items.length === 0) return;
    setShifting(true);
    try {
      await api.post('/stock/shift-to-factory', {
        items,
        factory_register_id: shiftFactoryId ? Number(shiftFactoryId) : null,
        queue_number: shiftQueueNumber.trim() || null,
        expected_date: shiftExpectedDate || null,
      });
      setShowShiftModal(false);
      loadBags();
    } finally { setShifting(false); }
  };

  const saveEdit = async () => {
    if (!editing || !editVariantId || !editBagCount) return;
    setEditSaving(true);
    try {
      await api.put(`/stock/${editing.id}`, {
        mode: editMode, location: editLocation,
        variant_id: Number(editVariantId),
        bag_count: Number(editBagCount),
        price_per_mann: editPrice ? Number(editPrice) : null,
        factory_register_id: editFactoryId ? Number(editFactoryId) : null,
        queue_number: editQueueNumber.trim() || null,
        expected_date: editExpectedDate || null,
      });
      setShowEditModal(false);
      loadBags(location);
    } finally { setEditSaving(false); }
  };

  const saveExpense = async () => {
    if (!expStock) return;
    setExpSaving(true);
    try {
      await api.post(`/stock/${expStock.id}/expenses`, {
        amount: Number(expForm.amount),
        note: expForm.note || null,
      });
      setShowExpModal(false);
      loadBags();
    } finally { setExpSaving(false); }
  };


  const openScheduleModal = (b: StockBag) => {
    setScheduleStock(b);
    setSchedBags('');
    setSchedStartDate('');
    setSchedDays('');
    setSchedNotes('');
    setSchedError('');
    setShowScheduleModal(true);
  };

  const addBatch = async () => {
    if (!scheduleStock || !schedBags || !schedStartDate || !schedDays) {
      setSchedError('All fields are required'); return;
    }
    setSchedSaving(true); setSchedError('');
    try {
      await api.post(`/stock/${scheduleStock.id}/batches`, {
        bags_count: Number(schedBags),
        start_date: schedStartDate,
        processing_days: Number(schedDays),
        notes: schedNotes.trim() || null,
      });
      setSchedBags(''); setSchedStartDate(''); setSchedDays(''); setSchedNotes('');
      loadBags();
    } catch (e: any) {
      setSchedError(e.response?.data?.message ?? 'Failed to add batch');
    } finally { setSchedSaving(false); }
  };

  const toggleBatchStatus = async (stockId: number, batch: StockProcessingBatch) => {
    await api.put(`/stock/${stockId}/batches/${batch.id}`, {
      status: batch.status === 'pending' ? 'done' : 'pending',
    });
    loadBags();
  };

  const deleteBatch = async (stockId: number, batchId: number) => {
    if (!confirm('Remove this batch?')) return;
    await api.delete(`/stock/${stockId}/batches/${batchId}`);
    loadBags();
  };

  // Shift modal total weight preview per group
  const shiftWeightPreview = (g: ShiftGroup) => {
    const n = Number(shiftBags[g.key] || 0);
    if (!n) return null;
    const kg = n * g.bag_weight_kg;
    const m = Math.floor(kg / 40);
    const r = +(kg % 40).toFixed(3);
    return `${m > 0 ? m + ' mann' : ''}${m > 0 && r > 0 ? ' + ' : ''}${r > 0 ? r + ' kg' : ''}`;
  };

  const hasShiftInput = shiftGroups.some(g => Number(shiftBags[g.key] || 0) > 0);

  // ── Processing modal derived ────────────────────────────────────────────
  const procSelectedFactory = procFactoryRegs.find(fr => String(fr.id) === procFactoryId) ?? null;
  const procStockGroups = (() => {
    if (!procSelectedFactory) return [] as Array<{key: string; description: string; bag_weight_kg: number; total_bags: number}>;
    const map = new Map<string, {key: string; description: string; bag_weight_kg: number; total_bags: number}>();
    for (const bag of procSelectedFactory.stock_bags) {
      const bw = parseFloat(String(bag.bag_weight_kg));
      const key = `${bag.description}__${bw}`;
      const ex = map.get(key);
      if (ex) { ex.total_bags += bag.quantity; }
      else map.set(key, { key, description: bag.description ?? '', bag_weight_kg: bw, total_bags: bag.quantity });
    }
    return [...map.values()];
  })();

  const procInputItems = procStockGroups
    .filter(g => Number(procInputs[g.key] || 0) > 0)
    .map(g => ({
      description: g.description,
      bag_weight_kg: g.bag_weight_kg,
      bags_count: Number(procInputs[g.key]),
      weight_kg: Number(procInputs[g.key]) * g.bag_weight_kg,
    }));

  const procTotalInputKg = procInputItems.reduce((s, i) => s + i.weight_kg, 0);

  const openProcModal = async () => {
    setProcLoading(true);
    setProcInputs({});
    setProcSentDate(today);
    setProcNotes('');
    setProcError('');
    setShowProcModal(true);
    try {
      const r = await api.get('/factories');
      setProcFactoryRegs(r.data.factory_registers);
      const first = r.data.factory_registers.find((fr: FactoryWithStock) => fr.stock_bags_count > 0)
        ?? r.data.factory_registers[0];
      setProcFactoryId(first ? String(first.id) : '');
    } finally { setProcLoading(false); }
  };

  const procSubmit = async () => {
    if (!procFactoryId) { setProcError('Select a factory'); return; }
    if (procInputItems.length === 0) { setProcError('Enter bags for at least one item'); return; }
    if (!procSentDate) { setProcError('Enter sent date'); return; }
    setProcSaving(true); setProcError('');
    try {
      await api.post('/factories/batch', {
        factory_register_id: Number(procFactoryId),
        sent_date: procSentDate,
        notes: procNotes.trim() || null,
        items: procInputItems,
        outputs: [],
      });
      setShowProcModal(false);
      loadBags();
    } catch (e: unknown) {
      const err = e as { response?: { data?: { message?: string } } };
      setProcError(err?.response?.data?.message ?? 'Error creating processing run');
    } finally { setProcSaving(false); }
  };

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between gap-4 flex-wrap">
        <h1 className="text-xl font-semibold text-gray-900">Stock</h1>
        <div className="flex gap-2">
          {location === 'factory' && (
            <button onClick={openProcModal} className="px-4 py-2 rounded-lg bg-blue-600 hover:bg-blue-500 text-gray-900 text-sm font-medium transition-colors">
              Schedule Processing
            </button>
          )}
          {location === 'warehouse' && (
            <button onClick={openShiftModal} className="px-4 py-2 rounded-lg bg-purple-600 hover:bg-purple-500 text-gray-900 text-sm font-medium transition-colors">
              Shift to Factory
            </button>
          )}
          <button onClick={openAdd} className="px-4 py-2 rounded-lg bg-emerald-600 hover:bg-emerald-500 text-white text-sm font-medium transition-colors">
            + Add to Stock
          </button>
        </div>
      </div>

      {/* Location tabs */}
      <div className="flex gap-1 p-1 bg-gray-100 rounded-lg w-fit">
        {(['warehouse', 'factory'] as const).map(loc => (
          <button key={loc} onClick={() => setLocation(loc)}
            className={`px-6 py-2 rounded-md text-sm font-medium transition-colors ${location === loc ? 'bg-emerald-600 text-white' : 'text-gray-500 hover:text-gray-900'}`}>
            {loc === 'warehouse' ? 'Warehouse' : 'Factory'}
          </button>
        ))}
      </div>

      {/* Stat boxes */}
      <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
        <div className="rounded-xl bg-white border border-gray-200 shadow-sm p-4">
          <div className="text-xs text-gray-500 uppercase tracking-wider mb-2">Total Stock</div>
          <div className="text-2xl font-bold text-gray-900">{totalBags.toLocaleString()} bags</div>
          <div className="text-sm text-gray-500 mt-1">
            {Number(totalMann).toLocaleString()} mann
            {totalKg > 0 && ` + ${Number(totalKg).toLocaleString()} kg`}
          </div>
        </div>
        <div className="rounded-xl bg-white border border-gray-200 shadow-sm p-4">
          <div className="text-xs text-gray-500 uppercase tracking-wider mb-2">Total Value</div>
          <div className="text-2xl font-bold text-gray-900">
            {totalValue > 0 ? `PKR ${Math.round(totalValue).toLocaleString()}` : '—'}
          </div>
          <div className="text-sm text-gray-400 mt-1">{bags.length} entr{bags.length === 1 ? 'y' : 'ies'}</div>
        </div>
        <div className="rounded-xl bg-white border border-gray-200 shadow-sm p-4">
          <div className="text-xs text-gray-500 uppercase tracking-wider mb-2">By Item</div>
          {byItemList.length === 0 ? (
            <div className="text-sm text-gray-500">No stock yet</div>
          ) : (
            <div className="space-y-2">
              {byItemList.map(item => (
                <div key={item.name}>
                  <div className="flex justify-between items-baseline">
                    <span className="text-sm text-gray-900 font-medium">{item.name}</span>
                    <span className="text-xs text-gray-500">{item.bags} bags</span>
                  </div>
                  <div className="flex justify-between items-baseline mt-0.5">
                    <span className="text-xs text-gray-400">
                      {item.mann} mann{item.kg > 0 ? ` + ${item.kg} kg` : ''}
                    </span>
                    {item.value > 0 && <span className="text-xs text-emerald-700">PKR {Math.round(item.value).toLocaleString()}</span>}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>
      </div>

      {/* Table */}
      <div className="rounded-xl bg-white border border-gray-200 shadow-sm overflow-x-auto">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b border-gray-200">
              {['Item', location === 'factory' ? 'Factory / Queue' : 'Date Added', 'Bags', 'Weight', 'Rate / Mann', 'Expenses', 'Actions'].map(h => (
                <th key={h} className="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider whitespace-nowrap">{h}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {bags.length === 0 && (
              <tr><td colSpan={7} className="px-4 py-12 text-center text-gray-400">No items in {location}.</td></tr>
            )}
            {bags.map(b => {
              const expList = b.expenses ?? [];
              const expTotal = expList.reduce((s, e) => s + Number(e.amount), 0);
              const mannEquiv = Number(b.quantity_mann || 0) + Number(b.quantity_kg || 0) / 40;
              const pricePerMann = b.price_per_mann != null ? Number(b.price_per_mann) : null;
              const rateAfterExp = pricePerMann != null && mannEquiv > 0 && expTotal > 0
                ? Math.round(pricePerMann + expTotal / mannEquiv) : null;
              return (
                <tr key={b.id} className="border-b border-gray-100 hover:bg-gray-50">
                  <td className="px-4 py-3">
                    <div className="text-gray-900 font-medium">{b.description ?? '—'}</div>
                    {b.mode === 'open'
                      ? <span className="text-xs text-blue-700">From Purchase</span>
                      : <span className="text-xs text-gray-400">Direct</span>}
                  </td>
                  <td className="px-4 py-3">
                    {location === 'factory' ? (
                      <div>
                        {b.factory_register ? (
                          <div className="text-gray-900 text-xs font-medium">{b.factory_register.name}</div>
                        ) : (
                          <div className="text-gray-500 text-xs">No factory</div>
                        )}
                        {b.queue_number && (
                          <div className="text-purple-700 text-xs mt-0.5">Queue: {b.queue_number}</div>
                        )}
                        {b.expected_date && (
                          <div className="text-amber-700 text-xs mt-0.5">Expected: {fmtDate(b.expected_date)}</div>
                        )}
                      </div>
                    ) : (
                      <span className="text-gray-700 whitespace-nowrap">{fmtDate(b.created_at)}</span>
                    )}
                  </td>
                  <td className="px-4 py-3">
                    <div className="text-gray-700 text-xs">{b.quantity} bags</div>
                    {Number(b.bag_weight_kg) > 0 && (
                      <div className="text-gray-400 text-xs">{Number(b.bag_weight_kg).toLocaleString()} kg/bag</div>
                    )}
                  </td>
                  <td className="px-4 py-3">
                    {b.quantity_mann != null && <div className="text-gray-700 text-xs">{Number(b.quantity_mann).toLocaleString()} mann</div>}
                    {b.quantity_kg != null && <div className="text-gray-500 text-xs">{Number(b.quantity_kg).toLocaleString()} kg</div>}
                    {b.quantity_mann == null && b.quantity_kg == null && <span className="text-gray-500">—</span>}
                  </td>
                  <td className="px-4 py-3">
                    {pricePerMann != null
                      ? <div className="text-gray-900 text-xs">PKR {pricePerMann.toLocaleString()} / mann</div>
                      : <div className="text-gray-500 text-xs">—</div>}
                    {rateAfterExp != null && (
                      <div className="text-amber-700 text-xs mt-0.5">PKR {Math.round(rateAfterExp).toLocaleString()} / mann after exp</div>
                    )}
                  </td>
                  <td className="px-4 py-3">
                    {expList.length > 0 ? (
                      <div className="space-y-0.5">
                        {expList.map((e: StockExpense) => (
                          <div key={e.id} className="flex justify-between gap-3 text-xs">
                            <span className="text-gray-500">{e.description || 'Expense'}</span>
                            <span className="text-orange-400 whitespace-nowrap">PKR {Number(e.amount).toLocaleString()}</span>
                          </div>
                        ))}
                        {expList.length > 1 && (
                          <div className="flex justify-between gap-3 text-xs border-t border-gray-300 pt-0.5">
                            <span className="text-gray-400">Total</span>
                            <span className="text-orange-300 font-medium">PKR {expTotal.toLocaleString()}</span>
                          </div>
                        )}
                      </div>
                    ) : <span className="text-gray-500">—</span>}
                  </td>
                  <td className="px-4 py-3">
                    <div className="flex gap-1.5 flex-wrap">
                      <button onClick={() => { setExpStock(b); setExpForm({ amount: '', note: '' }); setShowExpModal(true); }}
                        className="px-2 py-1 rounded-md bg-orange-500/10 hover:bg-orange-500/20 text-orange-400 text-xs whitespace-nowrap">+ Exp</button>
                      {b.location === 'factory' && (
                        <button onClick={() => openScheduleModal(b)}
                          className="px-2 py-1 rounded-md bg-blue-50 hover:bg-blue-100 text-blue-600 text-xs whitespace-nowrap">
                          Schedule{(b.processing_batches?.length ?? 0) > 0 ? ` (${b.processing_batches!.length})` : ''}
                        </button>
                      )}
                      <button onClick={() => openEditModal(b)} className="px-2 py-1 rounded-md bg-gray-100 hover:bg-gray-200 text-gray-700 text-xs">Edit</button>
                    </div>
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {/* Shift to Factory Modal */}
      <Modal open={showShiftModal} onClose={() => setShowShiftModal(false)} title="Shift Stock to Factory" maxWidth="max-w-lg">
        <div className="space-y-4">
          {shiftGroups.length === 0 ? (
            <p className="text-center text-gray-400 py-6">No warehouse stock available to shift.</p>
          ) : (
            <>
              {/* Factory + Queue selection */}
              <div className="rounded-lg bg-gray-100/60 border border-gray-300 p-3 space-y-2">
                <p className="text-xs font-medium text-gray-700">Factory & Queue (optional)</p>
                <div className="flex gap-2">
                  <select
                    value={shiftFactoryId}
                    onChange={e => setShiftFactoryId(e.target.value)}
                    className="flex-1 px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-purple-500 text-gray-900 text-sm outline-none">
                    <option value="">— No factory assigned —</option>
                    {factoryRegisters.map(fr => (
                      <option key={fr.id} value={String(fr.id)}>{fr.name}{fr.location ? ` (${fr.location})` : ''}</option>
                    ))}
                  </select>
                  <input
                    type="text"
                    value={shiftQueueNumber}
                    onChange={e => setShiftQueueNumber(e.target.value)}
                    placeholder="Queue no."
                    className="w-28 px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-purple-500 text-gray-900 text-sm outline-none"
                  />
                </div>
                <div>
                  <label className="text-xs text-gray-500 block mb-1">Expected Processing Date</label>
                  <input
                    type="date"
                    value={shiftExpectedDate}
                    onChange={e => setShiftExpectedDate(e.target.value)}
                    className="w-full px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-purple-500 text-gray-900 text-sm outline-none"
                  />
                </div>
              </div>
              <p className="text-xs text-gray-500">Enter how many bags to shift from each variant. Leave blank to skip.</p>
              <div className="space-y-3">
                {shiftGroups.map(g => {
                  const preview = shiftWeightPreview(g);
                  const inputVal = shiftBags[g.key] ?? '';
                  return (
                    <div key={g.key} className="rounded-lg bg-gray-100 border border-gray-300 p-3">
                      <div className="flex items-center justify-between gap-4">
                        <div className="flex-1 min-w-0">
                          <div className="text-gray-900 font-medium text-sm">{g.description}</div>
                          <div className="text-xs text-gray-500 mt-0.5">
                            {g.bag_weight_kg} kg/bag · {g.totalBags} bags available
                            {' '}({Math.floor(g.mann + g.kg / 40)} mann{+(g.kg % 40).toFixed(3) > 0 ? ` + ${+(g.kg % 40).toFixed(3)} kg` : ''})
                          </div>
                          {preview && (
                            <div className="text-xs text-purple-700 mt-1">Shifting: {preview}</div>
                          )}
                        </div>
                        <div className="w-24 shrink-0">
                          <input
                            type="number"
                            min="1"
                            max={g.totalBags}
                            value={inputVal}
                            onChange={e => {
                              const n = parseInt(e.target.value, 10);
                              if (e.target.value === '') {
                                setShiftBags(s => ({ ...s, [g.key]: '' }));
                              } else if (n > g.totalBags) {
                                setShiftBags(s => ({ ...s, [g.key]: String(g.totalBags) }));
                              } else if (n < 1) {
                                setShiftBags(s => ({ ...s, [g.key]: '1' }));
                              } else {
                                setShiftBags(s => ({ ...s, [g.key]: String(n) }));
                              }
                            }}
                            onWheel={e => e.currentTarget.blur()}
                            placeholder="Bags"
                            className="w-full px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-purple-500 text-gray-900 text-sm outline-none text-center"
                          />
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            </>
          )}
          <div className="flex justify-end gap-2 pt-2">
            <button onClick={() => setShowShiftModal(false)} className="px-4 py-2 rounded-lg bg-gray-100 hover:bg-gray-200 text-gray-900 text-sm">Cancel</button>
            <button
              onClick={confirmShift}
              disabled={shifting || !hasShiftInput}
              className="px-4 py-2 rounded-lg bg-purple-600 hover:bg-purple-500 disabled:opacity-60 text-gray-900 text-sm">
              {shifting ? 'Shifting…' : 'Confirm Shift'}
            </button>
          </div>
        </div>
      </Modal>

      {/* Add Modal */}
      <Modal open={showModal} onClose={() => setShowModal(false)} title="Add to Stock" maxWidth="max-w-md">
        <div className="space-y-4">
          <div className="flex gap-1 p-1 bg-gray-100 rounded-lg">
            {(['direct', 'open'] as const).map(m => (
              <button key={m} onClick={() => setMode(m)}
                className={`flex-1 py-1.5 rounded-md text-sm font-medium transition-colors ${mode === m ? 'bg-emerald-600 text-white' : 'text-gray-500 hover:text-gray-900'}`}>
                {m === 'direct' ? 'Direct' : 'From Purchase'}
              </button>
            ))}
          </div>
          <div className="flex gap-1 p-1 bg-gray-50 rounded-lg border border-gray-300">
            {(['warehouse', 'factory'] as const).map(loc => (
              <button key={loc} onClick={() => setLocation(loc)}
                className={`flex-1 py-1.5 rounded-md text-sm font-medium transition-colors ${location === loc ? 'bg-gray-300 text-gray-900' : 'text-gray-500 hover:text-gray-900'}`}>
                {loc === 'warehouse' ? 'Warehouse' : 'Factory'}
              </button>
            ))}
          </div>
          <Field label="Item Type">
            <select value={selectedTypeId} onChange={e => onTypeChange(e.target.value)}
              className="w-full px-3 py-2 rounded-lg bg-gray-100 border border-gray-300 text-gray-900 text-sm outline-none focus:border-emerald-500">
              <option value="">— Select item —</option>
              {addItemTypes.map(t => <option key={t.id} value={String(t.id)}>{t.name}</option>)}
            </select>
          </Field>
          {selectedType && (
            <Field label="Variant (kg / bag)">
              {variants.length === 0
                ? <p className="text-xs text-amber-700 px-1">No variants. Add in Settings → Item Types.</p>
                : <select value={selectedVariantId} onChange={e => setSelectedVariantId(e.target.value)}
                    className="w-full px-3 py-2 rounded-lg bg-gray-100 border border-gray-300 text-gray-900 text-sm outline-none focus:border-emerald-500">
                    <option value="">— Select variant —</option>
                    {variants.map(v => <option key={v.id} value={String(v.id)}>{Number(v.bag_weight_kg).toLocaleString()} kg / bag</option>)}
                  </select>}
            </Field>
          )}
          {location === 'factory' && (
            <div className="rounded-lg bg-gray-100/60 border border-gray-300 p-3 space-y-2">
              <p className="text-xs font-medium text-gray-700">Factory & Queue (optional)</p>
              <div className="flex gap-2">
                <select
                  value={addFactoryId}
                  onChange={e => setAddFactoryId(e.target.value)}
                  className="flex-1 px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-emerald-500 text-gray-900 text-sm outline-none">
                  <option value="">— No factory assigned —</option>
                  {factoryRegisters.map(fr => (
                    <option key={fr.id} value={String(fr.id)}>{fr.name}{fr.location ? ` (${fr.location})` : ''}</option>
                  ))}
                </select>
                <input
                  type="text"
                  value={addQueueNumber}
                  onChange={e => setAddQueueNumber(e.target.value)}
                  placeholder="Queue no."
                  className="w-28 px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-emerald-500 text-gray-900 text-sm outline-none"
                />
              </div>
              <div>
                <label className="text-xs text-gray-500 block mb-1">Expected Processing Date</label>
                <input
                  type="date"
                  value={addExpectedDate}
                  onChange={e => setAddExpectedDate(e.target.value)}
                  className="w-full px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-emerald-500 text-gray-900 text-sm outline-none"
                />
              </div>
            </div>
          )}
          {selectedVariant && (
            <>
              <Field label="No. of Bags">
                <Input type="number" value={bagCount} onChange={e => setBagCount(e.target.value)} step="1" min="1" placeholder="e.g. 10" autoFocus />
              </Field>
              <div className="rounded-lg bg-gray-100/60 border border-gray-300 px-4 py-3 space-y-1 text-sm">
                <div className="flex justify-between">
                  <span className="text-gray-500">Bag weight</span>
                  <span className="text-gray-700">{Number(selectedVariant.bag_weight_kg).toLocaleString()} kg/bag</span>
                </div>
                <div className="flex justify-between">
                  <span className="text-gray-500">Total weight</span>
                  <span className="text-gray-900 font-medium">
                    {autoTotalKg > 0 ? <>{autoMann > 0 ? `${autoMann} mann` : ''}{autoMann > 0 && autoKg > 0 ? ' + ' : ''}{autoKg > 0 ? `${autoKg} kg` : ''}{autoMann === 0 && autoKg === 0 ? '—' : ''}</> : '—'}
                  </span>
                </div>
              </div>
              <Field label="Price per Mann (PKR)">
                <Input type="number" value={addPricePerMann} onChange={e => setAddPricePerMann(e.target.value)} step="1" min="0" placeholder="e.g. 1500" autoFocus={false} />
              </Field>
              {autoMann > 0 && addPricePerMann && Number(addPricePerMann) > 0 && (
                <div className="rounded-lg bg-blue-50 border border-blue-200 px-3 py-2 text-sm">
                  <span className="text-gray-500">Total payment: </span>
                  <span className="font-semibold text-blue-700">
                    PKR {Math.round((autoMann + autoKg / 40) * Number(addPricePerMann)).toLocaleString()}
                  </span>
                  <span className="text-gray-400 ml-2">will be deducted from shop balance</span>
                </div>
              )}
            </>
          )}
          <div className="flex justify-end gap-2 pt-2">
            <button onClick={() => setShowModal(false)} className="px-4 py-2 rounded-lg bg-gray-100 hover:bg-gray-200 text-gray-900 text-sm">Cancel</button>
            <button onClick={save} disabled={saving || !selectedVariantId || !bagCount || !addPricePerMann}
              className="px-4 py-2 rounded-lg bg-emerald-600 hover:bg-emerald-500 disabled:opacity-60 text-white text-sm">
              {saving ? 'Saving…' : `Add to ${location === 'warehouse' ? 'Warehouse' : 'Factory'}`}
            </button>
          </div>
        </div>
      </Modal>

      {/* Edit Modal */}
      <Modal open={showEditModal} onClose={() => setShowEditModal(false)} title="Edit Stock" maxWidth="max-w-md">
        <div className="space-y-4">
          <div className="flex gap-1 p-1 bg-gray-100 rounded-lg">
            {(['direct', 'open'] as const).map(m => (
              <button key={m} onClick={() => setEditMode(m)}
                className={`flex-1 py-1.5 rounded-md text-sm font-medium transition-colors ${editMode === m ? 'bg-emerald-600 text-white' : 'text-gray-500 hover:text-gray-900'}`}>
                {m === 'direct' ? 'Direct' : 'From Purchase'}
              </button>
            ))}
          </div>
          <div className="flex gap-1 p-1 bg-gray-50 rounded-lg border border-gray-300">
            {(['warehouse', 'factory'] as const).map(loc => (
              <button key={loc} onClick={() => setEditLocation(loc)}
                className={`flex-1 py-1.5 rounded-md text-sm font-medium transition-colors ${editLocation === loc ? 'bg-gray-300 text-gray-900' : 'text-gray-500 hover:text-gray-900'}`}>
                {loc === 'warehouse' ? 'Warehouse' : 'Factory'}
              </button>
            ))}
          </div>
          <Field label="Item Type">
            <select value={editTypeId} onChange={e => onEditTypeChange(e.target.value)}
              className="w-full px-3 py-2 rounded-lg bg-gray-100 border border-gray-300 text-gray-900 text-sm outline-none focus:border-emerald-500">
              <option value="">— Select item —</option>
              {editItemTypes.map(t => <option key={t.id} value={String(t.id)}>{t.name}</option>)}
            </select>
          </Field>
          {editType && (
            <Field label="Variant (kg / bag)">
              {editVariants.length === 0
                ? <p className="text-xs text-amber-700 px-1">No variants.</p>
                : <select value={editVariantId} onChange={e => setEditVariantId(e.target.value)}
                    className="w-full px-3 py-2 rounded-lg bg-gray-100 border border-gray-300 text-gray-900 text-sm outline-none focus:border-emerald-500">
                    <option value="">— Select variant —</option>
                    {editVariants.map(v => <option key={v.id} value={String(v.id)}>{Number(v.bag_weight_kg).toLocaleString()} kg / bag</option>)}
                  </select>}
            </Field>
          )}
          <Field label="No. of Bags">
            <Input type="number" value={editBagCount} onChange={e => setEditBagCount(e.target.value)} step="1" min="1" placeholder="e.g. 10" />
          </Field>
          {editTotalKg > 0 && (
            <div className="rounded-lg bg-gray-100/60 border border-gray-300 px-4 py-3 space-y-1 text-sm">
              <div className="flex justify-between">
                <span className="text-gray-500">Bag weight</span>
                <span className="text-gray-700">{editVariant ? Number(editVariant.bag_weight_kg).toLocaleString() : '—'} kg/bag</span>
              </div>
              <div className="flex justify-between">
                <span className="text-gray-500">Total weight</span>
                <span className="text-gray-900 font-medium">
                  {editAutoMann > 0 ? `${editAutoMann} mann` : ''}
                  {editAutoMann > 0 && editAutoKg > 0 ? ' + ' : ''}
                  {editAutoKg > 0 ? `${editAutoKg} kg` : ''}
                </span>
              </div>
            </div>
          )}
          <Field label="Price per Mann (PKR)">
            <Input type="number" value={editPrice} onChange={e => setEditPrice(e.target.value)} step="1" min="0" placeholder="e.g. 1500" />
          </Field>
          <div className="rounded-lg bg-gray-100/60 border border-gray-300 p-3 space-y-2">
            <p className="text-xs font-medium text-gray-700">Factory & Processing Date (optional)</p>
            <div className="flex gap-2">
              <select value={editFactoryId} onChange={e => setEditFactoryId(e.target.value)}
                className="flex-1 px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-emerald-500 text-gray-900 text-sm outline-none">
                <option value="">— No factory —</option>
                {factoryRegisters.map(fr => (
                  <option key={fr.id} value={String(fr.id)}>{fr.name}{fr.location ? ` (${fr.location})` : ''}</option>
                ))}
              </select>
              <input type="text" value={editQueueNumber} onChange={e => setEditQueueNumber(e.target.value)}
                placeholder="Queue no."
                className="w-28 px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-emerald-500 text-gray-900 text-sm outline-none" />
            </div>
            <div>
              <label className="text-xs text-gray-500 block mb-1">Expected Processing Date</label>
              <input type="date" value={editExpectedDate} onChange={e => setEditExpectedDate(e.target.value)}
                className="w-full px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-emerald-500 text-gray-900 text-sm outline-none" />
            </div>
          </div>
          <div className="flex justify-end gap-2 pt-2">
            <button onClick={() => setShowEditModal(false)} className="px-4 py-2 rounded-lg bg-gray-100 hover:bg-gray-200 text-gray-900 text-sm">Cancel</button>
            <button onClick={saveEdit} disabled={editSaving || !editVariantId || !editBagCount || !editPrice}
              className="px-4 py-2 rounded-lg bg-emerald-600 hover:bg-emerald-500 disabled:opacity-60 text-white text-sm">
              {editSaving ? 'Saving…' : 'Save Changes'}
            </button>
          </div>
        </div>
      </Modal>

      {/* Expense Modal */}
      <Modal open={showExpModal} onClose={() => setShowExpModal(false)} title={`Add Expense — ${expStock?.description ?? 'Stock'}`} maxWidth="max-w-sm">
        <div className="space-y-4">
          <Field label="Amount (PKR)">
            <Input type="number" value={expForm.amount} onChange={e => setExpForm(f => ({ ...f, amount: e.target.value }))} step="1" min="1" placeholder="0" autoFocus />
          </Field>
          <Field label="Note">
            <Input value={expForm.note} onChange={e => setExpForm(f => ({ ...f, note: e.target.value }))} placeholder="e.g. Transport, Loading..." />
          </Field>
          <div className="flex justify-end gap-2 pt-2">
            <button onClick={() => setShowExpModal(false)} className="px-4 py-2 rounded-lg bg-gray-100 hover:bg-gray-200 text-gray-900 text-sm">Cancel</button>
            <button onClick={saveExpense} disabled={expSaving || !expForm.amount} className="px-4 py-2 rounded-lg bg-orange-600 hover:bg-orange-500 disabled:opacity-60 text-gray-900 text-sm">
              {expSaving ? 'Saving…' : 'Add Expense'}
            </button>
          </div>
        </div>
      </Modal>

      {/* ── Schedule Processing Modal ───────────────────────────────────── */}
      <Modal
        open={showProcModal}
        onClose={() => setShowProcModal(false)}
        title="Send to Processing"
        maxWidth="max-w-xl"
      >
        {procLoading ? (
          <div className="py-12 text-center text-gray-500">Loading factory data…</div>
        ) : (
          <div className="space-y-4">
            {/* Factory select */}
            <div>
              <label className="block text-xs font-medium text-gray-500 mb-1.5">Select Factory</label>
              <select
                value={procFactoryId}
                onChange={e => { setProcFactoryId(e.target.value); setProcInputs({}); }}
                className="w-full px-3 py-2 rounded-lg bg-gray-100 border border-gray-300 text-gray-900 text-sm outline-none focus:border-blue-500"
              >
                <option value="">— Select factory —</option>
                {procFactoryRegs.map(fr => (
                  <option key={fr.id} value={String(fr.id)}>
                    {fr.name}{fr.location ? ` (${fr.location})` : ''} — {fr.stock_bags_count.toLocaleString()} bags
                  </option>
                ))}
              </select>
            </div>

            {/* Stock at selected factory */}
            {procSelectedFactory && (
              procStockGroups.length === 0 ? (
                <div className="rounded-lg bg-gray-50 border border-gray-300 p-4 text-center text-gray-400 text-sm">
                  No stock at this factory.
                </div>
              ) : (
                <div className="space-y-2">
                  <p className="text-xs text-gray-500">Enter bags to send to processing. Leave blank to skip a variant.</p>
                  {procStockGroups.map(g => {
                    const inputVal = procInputs[g.key] ?? '';
                    const n = Number(inputVal || 0);
                    const previewKg = n > 0 ? n * g.bag_weight_kg : 0;
                    const previewMann = previewKg > 0 ? Math.floor(previewKg / 40) : 0;
                    const previewRemKg = previewKg > 0 ? parseFloat((previewKg % 40).toFixed(1)) : 0;
                    return (
                      <div key={g.key} className="rounded-lg bg-gray-100 border border-gray-300 p-3 flex items-center gap-4">
                        <div className="flex-1 min-w-0">
                          <div className="font-medium text-gray-900 text-sm">{g.description}</div>
                          <div className="text-xs text-gray-500 mt-0.5">
                            {g.bag_weight_kg} kg/bag · <span className="text-gray-900">{g.total_bags.toLocaleString()}</span> bags available
                          </div>
                          {n > 0 && (
                            <div className="text-xs text-blue-700 mt-1">
                              → {previewMann > 0 ? `${previewMann} mann ` : ''}{previewRemKg > 0 ? `${previewRemKg} kg` : ''} ({previewKg.toFixed(0)} kg)
                            </div>
                          )}
                        </div>
                        <input
                          type="number"
                          min="1"
                          max={g.total_bags}
                          value={inputVal}
                          onChange={e => {
                            const v = e.target.value;
                            if (v === '') { setProcInputs(s => ({ ...s, [g.key]: '' })); return; }
                            const parsed = parseInt(v, 10);
                            const clamped = Math.min(Math.max(parsed, 1), g.total_bags);
                            setProcInputs(s => ({ ...s, [g.key]: String(clamped) }));
                          }}
                          onWheel={e => e.currentTarget.blur()}
                          placeholder="Bags"
                          className="w-24 px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-blue-500 text-gray-900 text-sm outline-none text-center"
                        />
                      </div>
                    );
                  })}
                </div>
              )
            )}

            {/* Total weight preview */}
            {procTotalInputKg > 0 && (
              <div className="rounded-lg bg-blue-50 border border-blue-200 px-4 py-3 text-sm">
                <span className="text-gray-500">Total going to processing: </span>
                <span className="font-semibold text-gray-900">
                  {Math.floor(procTotalInputKg / 40)} mann{' '}
                  {parseFloat((procTotalInputKg % 40).toFixed(1)) > 0
                    ? `${parseFloat((procTotalInputKg % 40).toFixed(1))} kg` : ''}
                </span>
                <span className="text-gray-400 ml-2">({procTotalInputKg.toFixed(0)} kg)</span>
              </div>
            )}

            {/* Date + notes */}
            <div className="grid grid-cols-2 gap-3">
              <div>
                <label className="block text-xs font-medium text-gray-500 mb-1.5">Date</label>
                <input
                  type="date"
                  value={procSentDate}
                  onChange={e => setProcSentDate(e.target.value)}
                  className="w-full px-3 py-2 rounded-lg bg-gray-100 border border-gray-300 text-gray-900 text-sm outline-none focus:border-blue-500"
                />
              </div>
              <div>
                <label className="block text-xs font-medium text-gray-500 mb-1.5">Notes (optional)</label>
                <input
                  type="text"
                  value={procNotes}
                  onChange={e => setProcNotes(e.target.value)}
                  placeholder="e.g. Batch 1"
                  className="w-full px-3 py-2 rounded-lg bg-gray-100 border border-gray-300 text-gray-900 text-sm outline-none focus:border-blue-500"
                />
              </div>
            </div>

            {procError && <div className="text-red-600 text-sm">{procError}</div>}

            <p className="text-xs text-gray-400">
              After sending, go to the Factory page to add output categories when processing is complete.
            </p>

            <div className="flex justify-end gap-2 pt-1">
              <button onClick={() => setShowProcModal(false)} className="px-4 py-2 rounded-lg bg-gray-100 hover:bg-gray-200 text-gray-900 text-sm">Cancel</button>
              <button
                onClick={procSubmit}
                disabled={procSaving || procInputItems.length === 0}
                className="px-4 py-2 rounded-lg bg-blue-600 hover:bg-blue-500 disabled:opacity-60 text-gray-900 text-sm font-medium"
              >
                {procSaving ? 'Sending…' : 'Send to Processing'}
              </button>
            </div>
          </div>
        )}
      </Modal>

      {/* Processing Schedule Modal */}
      {scheduleStock && (() => {
        const batches = scheduleStock.processing_batches ?? [];
        const scheduledPending = batches.filter(b => b.status === 'pending').reduce((s, b) => s + b.bags_count, 0);
        const remaining = scheduleStock.quantity - scheduledPending;
        const previewDays = Number(schedDays);
        const previewBags = Number(schedBags);
        const endDatePreview = schedStartDate && previewDays > 0
          ? new Date(new Date(schedStartDate).getTime() + (previewDays - 1) * 86400000).toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' })
          : null;
        return (
          <Modal open={showScheduleModal} onClose={() => setShowScheduleModal(false)}
            title={`Processing Schedule — ${scheduleStock.description}`} maxWidth="max-w-lg">
            <div className="space-y-4">
              {/* Summary bar */}
              <div className="flex gap-3 rounded-lg bg-gray-100 px-4 py-3 text-sm">
                <div className="flex-1">
                  <div className="text-gray-500 text-xs">Total Bags</div>
                  <div className="text-gray-900 font-semibold">{scheduleStock.quantity.toLocaleString()}</div>
                </div>
                <div className="flex-1">
                  <div className="text-gray-500 text-xs">Scheduled</div>
                  <div className="text-blue-700 font-semibold">{scheduledPending.toLocaleString()}</div>
                </div>
                <div className="flex-1">
                  <div className="text-gray-500 text-xs">Remaining</div>
                  <div className={`font-semibold ${remaining > 0 ? 'text-amber-700' : 'text-emerald-700'}`}>{remaining.toLocaleString()}</div>
                </div>
              </div>

              {/* Existing batches */}
              {batches.length > 0 && (
                <div className="rounded-xl border border-gray-200 divide-y divide-gray-100">
                  {batches.map(batch => (
                    <div key={batch.id} className="flex items-center gap-3 px-3 py-2.5">
                      <button
                        onClick={() => toggleBatchStatus(scheduleStock.id, batch)}
                        className={`w-5 h-5 rounded-full border-2 flex items-center justify-center shrink-0 transition-colors ${
                          batch.status === 'done'
                            ? 'bg-emerald-500 border-emerald-500'
                            : 'border-gray-400 hover:border-emerald-500'
                        }`}>
                        {batch.status === 'done' && (
                          <svg className="w-3 h-3 text-gray-900" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={3}>
                            <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                          </svg>
                        )}
                      </button>
                      <div className="flex-1 min-w-0">
                        <div className="flex items-center gap-2">
                          <span className={`text-sm font-medium ${batch.status === 'done' ? 'text-gray-400 line-through' : 'text-gray-900'}`}>
                            {batch.bags_count.toLocaleString()} bags
                          </span>
                          <span className={`text-xs px-1.5 py-0.5 rounded ${batch.status === 'done' ? 'bg-emerald-50 text-emerald-700' : 'bg-blue-500/15 text-blue-700'}`}>
                            {batch.status === 'done' ? 'Done' : 'Pending'}
                          </span>
                        </div>
                        <div className="text-xs text-gray-500 mt-0.5">
                          {fmtDate(batch.start_date)} → {fmtDate(batch.end_date)} · {batch.processing_days} day{batch.processing_days !== 1 ? 's' : ''}
                          {batch.notes && <span className="text-gray-400 ml-2">· {batch.notes}</span>}
                        </div>
                      </div>
                      <button onClick={() => deleteBatch(scheduleStock.id, batch.id)}
                        className="px-2 py-1 rounded-md bg-red-50 hover:bg-red-100 text-red-600 text-xs shrink-0">Del</button>
                    </div>
                  ))}
                </div>
              )}

              {/* Add new batch */}
              {remaining > 0 && (
                <div className="rounded-xl border border-gray-300 bg-gray-50 p-3 space-y-3">
                  <p className="text-xs font-medium text-gray-700">Add Next Batch</p>
                  <div className="grid grid-cols-2 gap-2">
                    <div>
                      <label className="text-xs text-gray-500 block mb-1">Bags to process</label>
                      <input
                        type="number" min="1" max={remaining}
                        value={schedBags}
                        onChange={e => {
                          const n = parseInt(e.target.value, 10);
                          if (e.target.value === '') { setSchedBags(''); }
                          else if (n > remaining) { setSchedBags(String(remaining)); }
                          else if (n < 1) { setSchedBags('1'); }
                          else { setSchedBags(String(n)); }
                          setSchedError('');
                        }}
                        onWheel={e => e.currentTarget.blur()}
                        placeholder={`Max ${remaining}`}
                        className="w-full px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-blue-500 text-gray-900 text-sm outline-none"
                      />
                    </div>
                    <div>
                      <label className="text-xs text-gray-500 block mb-1">Processing days</label>
                      <input
                        type="number" min="1"
                        value={schedDays}
                        onChange={e => { setSchedDays(e.target.value); setSchedError(''); }}
                        onWheel={e => e.currentTarget.blur()}
                        placeholder="e.g. 5"
                        className="w-full px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-blue-500 text-gray-900 text-sm outline-none"
                      />
                    </div>
                    <div className="col-span-2">
                      <label className="text-xs text-gray-500 block mb-1">Start date</label>
                      <input
                        type="date"
                        value={schedStartDate}
                        onChange={e => { setSchedStartDate(e.target.value); setSchedError(''); }}
                        className="w-full px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-blue-500 text-gray-900 text-sm outline-none"
                      />
                    </div>
                    <div className="col-span-2">
                      <label className="text-xs text-gray-500 block mb-1">Notes (optional)</label>
                      <input
                        type="text"
                        value={schedNotes}
                        onChange={e => setSchedNotes(e.target.value)}
                        placeholder="e.g. First batch"
                        className="w-full px-3 py-2 rounded-lg bg-white border border-gray-300 focus:border-blue-500 text-gray-900 text-sm outline-none"
                      />
                    </div>
                  </div>
                  {endDatePreview && previewBags > 0 && (
                    <div className="rounded-lg bg-blue-50 border border-blue-200 px-3 py-2 text-xs text-blue-300">
                      {previewBags.toLocaleString()} bags · {schedStartDate && fmtDate(schedStartDate)} → {endDatePreview} ({previewDays} day{previewDays !== 1 ? 's' : ''})
                    </div>
                  )}
                  {schedError && <p className="text-xs text-red-600">{schedError}</p>}
                  <div className="flex justify-end">
                    <button onClick={addBatch} disabled={schedSaving || !schedBags || !schedStartDate || !schedDays}
                      className="px-4 py-2 rounded-lg bg-blue-600 hover:bg-blue-500 disabled:opacity-60 text-gray-900 text-sm">
                      {schedSaving ? 'Adding…' : '+ Add Batch'}
                    </button>
                  </div>
                </div>
              )}
              {remaining === 0 && batches.length > 0 && (
                <p className="text-center text-xs text-emerald-700 py-2">All bags are scheduled.</p>
              )}

              <div className="flex justify-end pt-1">
                <button onClick={() => setShowScheduleModal(false)} className="px-4 py-2 rounded-lg bg-gray-100 hover:bg-gray-200 text-gray-900 text-sm">Close</button>
              </div>
            </div>
          </Modal>
        );
      })()}
    </div>
  );
}
