import React, { useState, useEffect, useCallback, useRef } from 'react';
import { useParams, useNavigate, useSearchParams } from 'react-router-dom';
import {
  FaArrowLeft, FaSave, FaEdit, FaTimes, FaPlus, FaTrash,
  FaSpinner, FaTruck, FaPaperPlane, FaFileInvoiceDollar,
  FaChevronDown, FaChevronRight, FaPencilAlt,
} from 'react-icons/fa';
import { toast, ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import deliveryNoteService, { DeliveryNote, DeliveryNoteItem } from '../services/deliveryNoteService';
import salesOrderService from '../services/salesOrderService';
import LinkField from '../components/LinkField';
import ActivityLog from '../components/ActivityLog';
import { formatFrappeApiError } from '../utils/frappeErrorMessage';
import {
  DEFAULT_COMPANY, DEFAULT_CURRENCY, DEFAULT_SALES_TAXES_TEMPLATE,
  taxRatePercent, displayTxnCurrency,
} from '../constants/orgDefaults';

// ── Helpers ───────────────────────────────────────────────────────────────────
const FL: React.FC<{ children: React.ReactNode; required?: boolean }> = ({ children, required }) => (
  <label className="block text-[11px] font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-1">
    {children}{required && <span className="text-red-500 ml-0.5">*</span>}
  </label>
);
const RV: React.FC<{ children?: React.ReactNode }> = ({ children }) => (
  <div className="px-3 py-2 text-sm text-gray-800 dark:text-gray-200 bg-gray-50 dark:bg-gray-800/60 rounded min-h-[34px] flex items-center">
    {children || <span className="text-gray-400">-</span>}
  </div>
);
const inputCls = 'w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-teal-400';
const inlineTxt = 'w-full px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 focus:outline-none focus:ring-1 focus:ring-teal-400';
const inlineNum = 'w-full px-2 py-1 text-sm text-right border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 focus:outline-none focus:ring-1 focus:ring-teal-400';
const editorInput = 'w-full px-3 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-teal-400';
const editorNum = 'w-full px-3 py-2 text-sm text-right border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 text-gray-900 dark:text-white focus:outline-none focus:ring-1 focus:ring-teal-400';
const roField = 'w-full px-3 py-2 text-sm bg-gray-50 dark:bg-gray-800/60 text-gray-600 dark:text-gray-400 rounded min-h-[34px] flex items-center';

// ── Collapsible group ─────────────────────────────────────────────────────────
const RGroup: React.FC<{ label: string; children: React.ReactNode; defaultOpen?: boolean }> = ({ label, children, defaultOpen = false }) => {
  const [open, setOpen] = useState(defaultOpen);
  return (
    <div className="border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden mt-3">
      <button type="button" onClick={() => setOpen(o => !o)}
        className="w-full flex items-center gap-2 px-3 py-2 text-[11px] font-bold text-gray-500 dark:text-gray-400 uppercase tracking-wider bg-gray-50 dark:bg-gray-800/80 hover:bg-gray-100 dark:hover:bg-gray-700/60 transition-colors text-left">
        {open ? <FaChevronDown size={9} /> : <FaChevronRight size={9} />}{label}
      </button>
      {open && <div className="p-3 grid grid-cols-1 sm:grid-cols-2 gap-3 bg-white dark:bg-gray-800">{children}</div>}
    </div>
  );
};

// ── Create Dropdown ───────────────────────────────────────────────────────────
const CreateDropdown: React.FC<{ items: { label: string; icon: React.ReactNode; onClick: () => void }[] }> = ({ items }) => {
  const [open, setOpen] = useState(false);
  const ref = useRef<HTMLDivElement>(null);
  useEffect(() => {
    const h = (e: MouseEvent) => { if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false); };
    document.addEventListener('mousedown', h);
    return () => document.removeEventListener('mousedown', h);
  }, []);
  return (
    <div className="relative" ref={ref}>
      <button onClick={() => setOpen(o => !o)}
        className="flex items-center gap-1.5 px-4 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700 text-sm font-medium shadow-sm">
        Create <FaChevronDown size={10} className={`transition-transform ${open ? 'rotate-180' : ''}`} />
      </button>
      {open && (
        <div className="absolute right-0 mt-1 w-52 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl shadow-xl z-50 py-1.5">
          <div className="px-3 py-1.5 text-[10px] font-bold text-gray-400 uppercase tracking-wider border-b border-gray-100 dark:border-gray-700 mb-1">Create from this note</div>
          {items.map(({ label, icon, onClick }) => (
            <button key={label} onClick={() => { onClick(); setOpen(false); }}
              className="w-full flex items-center gap-3 px-4 py-2.5 text-sm text-gray-700 dark:text-gray-300 hover:bg-teal-50 dark:hover:bg-teal-900/20 hover:text-teal-700 transition-colors text-left">
              <span className="text-gray-400">{icon}</span>{label}
            </button>
          ))}
        </div>
      )}
    </div>
  );
};

// ── DN Item Row Editor ────────────────────────────────────────────────────────
interface TaxRow { charge_type?: string; account_head?: string; description?: string; included_in_print_rate?: number; rate?: number; tax_amount?: number; total?: number; cost_center?: string; account_currency?: string; idx?: number; [k: string]: any; }

const DNItemRowEditor: React.FC<{
  item: Partial<DeliveryNoteItem>;
  rowNo: number;
  currency: string;
  onChange: (k: string, v: any) => void;
  onClose: () => void;
  onDelete: () => void;
  onInsertBelow: () => void;
}> = ({ item, rowNo, currency, onChange, onClose, onDelete, onInsertBelow }) => {
  const set = (k: string, v: any) => onChange(k, v);
  const cur = currency || DEFAULT_CURRENCY;
  return (
    <tr>
      <td colSpan={8} className="p-0">
        <div className="bg-blue-50/60 dark:bg-blue-900/10 border-b border-blue-200 dark:border-blue-800 px-4 py-3">
          {/* editor header */}
          <div className="flex items-center justify-between mb-3">
            <span className="text-xs font-bold text-teal-700 dark:text-teal-300 uppercase tracking-wider">Editing Row #{rowNo}</span>
            <div className="flex gap-1">
              <button onClick={onInsertBelow} className="px-2 py-1 text-[11px] bg-teal-600 text-white rounded hover:bg-teal-700">Insert Below</button>
              <button onClick={onDelete} className="px-2 py-1 text-[11px] bg-red-500 text-white rounded hover:bg-red-600">Delete</button>
              <button onClick={onClose} className="px-2 py-1 text-[11px] bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded hover:bg-gray-300">ESC</button>
            </div>
          </div>

          {/* top fields */}
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
            <div><FL required>Item Code</FL><LinkField label="Item Code" hideLabel doctype="Item" value={item.item_code || ''} onChange={v => set('item_code', v)} /></div>
            <div><FL>Item Name</FL><input value={item.item_name || ''} onChange={e => set('item_name', e.target.value)} className={editorInput} /></div>
          </div>

          <RGroup label="Description">
            <div className="sm:col-span-2">
              <FL>Description</FL>
              <textarea value={item.description || ''} onChange={e => set('description', e.target.value)} rows={2} className={editorInput + ' resize-none'} />
            </div>
          </RGroup>

          <RGroup label="Quantity and Warehouse" defaultOpen>
            <div><FL required>Quantity</FL><input type="number" min={0} step="1" value={item.qty ?? 1} onChange={e => set('qty', parseFloat(e.target.value) || 0)} className={editorNum} /></div>
            <div><FL required>UOM</FL><LinkField label="UOM" hideLabel doctype="UOM" value={item.uom || ''} onChange={v => set('uom', v)} /></div>
            <div><FL>Stock UOM</FL><LinkField label="Stock UOM" hideLabel doctype="UOM" value={item.stock_uom || ''} onChange={v => set('stock_uom', v)} /></div>
            <div><FL>UOM Conversion Factor</FL><input type="number" min={0} step="0.0001" value={item.conversion_factor ?? 1} onChange={e => set('conversion_factor', parseFloat(e.target.value) || 1)} className={editorNum} /></div>
            <div><FL>Stock Qty (auto)</FL><div className={roField}>{((item.qty || 1) * (item.conversion_factor || 1)).toFixed(3)}</div></div>
          </RGroup>

          <RGroup label={`Discount and Margin (${cur})`} defaultOpen>
            <div><FL>Price List Rate ({cur})</FL><input type="number" min={0} step="0.01" value={item.price_list_rate ?? 0} onChange={e => set('price_list_rate', parseFloat(e.target.value) || 0)} className={editorNum} /></div>
            <div><FL>Discount %</FL><input type="number" min={0} max={100} step="0.01" value={item.discount_percentage ?? 0} onChange={e => set('discount_percentage', parseFloat(e.target.value) || 0)} className={editorNum} /></div>
            <div><FL>Discount Amount ({cur})</FL><input type="number" min={0} step="0.01" value={item.discount_amount ?? 0} onChange={e => set('discount_amount', parseFloat(e.target.value) || 0)} className={editorNum} /></div>
            <div><FL>Rate ({cur})</FL><input type="number" min={0} step="0.01" value={item.rate ?? 0} onChange={e => set('rate', parseFloat(e.target.value) || 0)} className={editorNum} /></div>
            <div><FL>Amount ({cur}) (auto)</FL><div className={roField}>{((item.qty || 0) * (item.rate || 0)).toFixed(2)}</div></div>
            <div className="flex items-center gap-2 pt-4">
              <input type="checkbox" id={`fi-${rowNo}`} checked={!!item.is_free_item} onChange={e => set('is_free_item', e.target.checked ? 1 : 0)} className="w-4 h-4 text-teal-600 rounded" />
              <label htmlFor={`fi-${rowNo}`} className="text-sm text-gray-700 dark:text-gray-300">Is Free Item</label>
            </div>
            <div className="flex items-center gap-2 pt-4">
              <input type="checkbox" id={`gc-${rowNo}`} checked={!!item.grant_commission} onChange={e => set('grant_commission', e.target.checked ? 1 : 0)} className="w-4 h-4 text-teal-600 rounded" />
              <label htmlFor={`gc-${rowNo}`} className="text-sm text-gray-700 dark:text-gray-300">Grant Commission</label>
            </div>
          </RGroup>

          <RGroup label="Warehouse and Reference">
            <div><FL>Warehouse</FL><LinkField label="Warehouse" hideLabel doctype="Warehouse" value={(item as any).warehouse || ''} onChange={v => set('warehouse', v)} /></div>
            <div><FL>Against Sales Order</FL><div className={roField}>{(item as any).against_sales_order || '-'}</div></div>
          </RGroup>

          <RGroup label="Available Quantity">
            <div><FL>Actual Qty (Warehouse)</FL><div className={roField}>{(item as any).actual_qty ?? 0}</div></div>
            <div><FL>Company Total Stock</FL><div className={roField}>{(item as any).company_total_stock ?? 0}</div></div>
          </RGroup>

          <RGroup label="Item Weight Details">
            <div><FL>Weight Per Unit</FL><input type="number" min={0} step="0.001" value={(item as any).weight_per_unit ?? 0} onChange={e => set('weight_per_unit', parseFloat(e.target.value) || 0)} className={editorNum} /></div>
            <div><FL>Total Weight (auto)</FL><div className={roField}>{(((item as any).weight_per_unit || 0) * (item.qty || 0)).toFixed(3)}</div></div>
          </RGroup>

          <RGroup label="Accounting Details">
            <div className="sm:col-span-2"><FL>Expense Account</FL><LinkField label="Expense Account" hideLabel doctype="Account" value={(item as any).expense_account || ''} onChange={v => set('expense_account', v)} /></div>
          </RGroup>

          <RGroup label="Accounting Dimensions">
            <div><FL>Cost Center</FL><LinkField label="Cost Center" hideLabel doctype="Cost Center" value={(item as any).cost_center || ''} onChange={v => set('cost_center', v)} /></div>
            <div><FL>Project</FL><LinkField label="Project" hideLabel doctype="Project" value={(item as any).project || ''} onChange={v => set('project', v)} /></div>
          </RGroup>
        </div>
      </td>
    </tr>
  );
};

// ── Tax Row Editor ────────────────────────────────────────────────────────────
const DNTaxRowEditor: React.FC<{
  tax: TaxRow; rowNo: number;
  onChange: (k: string, v: any) => void;
  onClose: () => void; onDelete: () => void;
}> = ({ tax, rowNo, onChange, onClose, onDelete }) => {
  const set = (k: string, v: any) => onChange(k, v);
  return (
    <tr>
      <td colSpan={7} className="p-0">
        <div className="bg-blue-50/60 dark:bg-blue-900/10 border-b border-blue-200 dark:border-blue-800 px-4 py-3">
          <div className="flex items-center justify-between mb-3">
            <span className="text-xs font-bold text-teal-700 dark:text-teal-300 uppercase tracking-wider">Editing Tax Row #{rowNo}</span>
            <div className="flex gap-1">
              <button onClick={onDelete} className="px-2 py-1 text-[11px] bg-red-500 text-white rounded hover:bg-red-600">Delete</button>
              <button onClick={onClose} className="px-2 py-1 text-[11px] bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded hover:bg-gray-300">ESC</button>
            </div>
          </div>
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
            <div><FL required>Type</FL>
              <select value={tax.charge_type || ''} onChange={e => set('charge_type', e.target.value)} className={editorInput}>
                <option value="">Select…</option>
                <option value="Actual">Actual</option>
                <option value="On Net Total">On Net Total</option>
                <option value="On Previous Row Amount">On Previous Row Amount</option>
                <option value="On Previous Row Total">On Previous Row Total</option>
                <option value="On Item Quantity">On Item Quantity</option>
              </select>
            </div>
            <div><FL>Description</FL><input value={tax.description || ''} onChange={e => set('description', e.target.value)} className={editorInput} /></div>
            <div><FL required>Account Head</FL><LinkField label="Account Head" hideLabel doctype="Account" value={tax.account_head || ''} onChange={v => set('account_head', v)} /></div>
            <div className="flex items-center gap-2 pt-5">
              <input type="checkbox" id={`incl-${rowNo}`} checked={!!tax.included_in_print_rate} onChange={e => set('included_in_print_rate', e.target.checked ? 1 : 0)} className="w-4 h-4 text-teal-600 rounded" />
              <label htmlFor={`incl-${rowNo}`} className="text-sm text-gray-700 dark:text-gray-300">Included in Basic Rate</label>
            </div>
          </div>
          <RGroup label="Accounting Dimensions">
            <div><FL>Cost Center</FL><LinkField label="Cost Center" hideLabel doctype="Cost Center" value={tax.cost_center || ''} onChange={v => set('cost_center', v)} /></div>
            <div><FL>Account Currency</FL><input value={tax.account_currency || ''} onChange={e => set('account_currency', e.target.value)} className={editorInput} /></div>
          </RGroup>
        </div>
      </td>
    </tr>
  );
};

// ── Empty helpers ─────────────────────────────────────────────────────────────
const emptyItem = (): Partial<DeliveryNoteItem> => ({ item_code: '', item_name: '', qty: 1, rate: 0, amount: 0, uom: '', conversion_factor: 1 });
const emptyTax = (): TaxRow => ({ charge_type: 'On Net Total', account_head: '', rate: 15 });

// ── Component ─────────────────────────────────────────────────────────────────
const DeliveryNoteDetail: React.FC = () => {
  const { dnName } = useParams<{ dnName: string }>();
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const isNew = dnName === 'new';

  const contextSO       = searchParams.get('so')       || '';
  const contextCustomer = searchParams.get('customer') || '';
  const contextCompany  = searchParams.get('company')  || DEFAULT_COMPANY;
  const contextProject  = searchParams.get('project')  || '';

  const [doc, setDoc]           = useState<DeliveryNote | null>(null);
  const [loading, setLoading]   = useState(!isNew);
  const [saving, setSaving]     = useState(false);
  const [submitting, setSubmitting] = useState(false);
  const [isEditing, setIsEditing] = useState(isNew);
  const [expandedItem, setExpandedItem] = useState<number | null>(null);
  const [expandedTax, setExpandedTax]   = useState<number | null>(null);
  const [taxes, setTaxes] = useState<TaxRow[]>([]);

  const today = new Date().toISOString().split('T')[0];

  const [form, setForm] = useState<Partial<DeliveryNote>>({
    customer: contextCustomer, company: contextCompany, project: contextProject,
    posting_date: today, currency: DEFAULT_CURRENCY,
    taxes_and_charges: DEFAULT_SALES_TAXES_TEMPLATE,
    items: [],
  } as any);

  const syncForm = useCallback((d: DeliveryNote) => {
    setForm({
      customer: d.customer || '', company: d.company || DEFAULT_COMPANY, project: d.project || '',
      posting_date: d.posting_date || today,
      currency: d.currency === 'INR' ? DEFAULT_CURRENCY : (d.currency || DEFAULT_CURRENCY),
      cost_center: d.cost_center || '', items: d.items || [],
      selling_price_list: (d as any).selling_price_list || '',
      price_list_currency: (d as any).price_list_currency || '',
      conversion_rate: (d as any).conversion_rate || 1,
      plc_conversion_rate: (d as any).plc_conversion_rate || 1,
      tax_category: (d as any).tax_category || '',
      taxes_and_charges: (d as any).taxes_and_charges || '',
    } as any);
    setTaxes((d as any).taxes || []);
  }, [today]);

  // Auto-fetch company currency when company changes on new form
  useEffect(() => {
    const company = (form as any).company;
    if (!isNew || !company) return;
    fetch(`/api/resource/Company/${encodeURIComponent(company)}`, { credentials: 'include' })
      .then(r => r.json()).then(b => {
        if (b.data?.default_currency) {
          const cur = displayTxnCurrency(b.data.default_currency);
          setForm(f => ({ ...f, currency: cur,
            selling_price_list: (f as any).selling_price_list || 'Standard Selling',
            price_list_currency: (f as any).price_list_currency || cur,
          } as any));
        }
      }).catch(() => {});
  }, [(form as any).company, isNew]);

  // Pre-fill from SO
  useEffect(() => {
    if (!isNew || !contextSO) return;
    salesOrderService.getSalesOrder(contextSO).then(so => {
      setForm(f => ({
        ...f,
        customer: so.customer || f.customer,
        company: so.company || f.company,
        project: so.project || (f as any).project,
        cost_center: so.cost_center || (f as any).cost_center,
        currency: so.currency || (f as any).currency,
        selling_price_list: (so as any).selling_price_list || 'Standard Selling',
        price_list_currency: (so as any).price_list_currency || so.currency,
        conversion_rate: (so as any).conversion_rate || 1,
        plc_conversion_rate: (so as any).plc_conversion_rate || 1,
        taxes_and_charges: (so as any).taxes_and_charges || '',
        tax_category: (so as any).tax_category || '',
        items: (so.items || []).map(it => ({
          item_code: it.item_code, item_name: it.item_name,
          description: (it as any).description || it.item_name || it.item_code,
          qty: it.qty, uom: it.uom, stock_uom: it.stock_uom,
          rate: it.rate, amount: it.amount,
          against_sales_order: contextSO,
          so_detail: (it as any).name || undefined,
          conversion_factor: it.conversion_factor ?? 1,
          warehouse: (it as any).warehouse || undefined,
          expense_account: (it as any).expense_account || undefined,
          cost_center: (it as any).cost_center || so.cost_center || undefined,
          project: (it as any).project || so.project || undefined,
        })),
      } as any));
      // Also load the taxes from SO's tax template
      if ((so as any).taxes_and_charges) {
        loadTaxTemplate((so as any).taxes_and_charges);
      } else if ((so as any).taxes?.length) {
        setTaxes((so as any).taxes.map((tx: any) => ({
          charge_type: tx.charge_type, account_head: tx.account_head,
          description: tx.description, rate: tx.rate ?? tx.tax_rate ?? 0,
          cost_center: tx.cost_center, account_currency: tx.account_currency,
          included_in_print_rate: tx.included_in_print_rate ?? 0,
        })));
      }
    }).catch(() => {});
  }, [isNew, contextSO]);

  useEffect(() => {
    if (isNew) return;
    setLoading(true);
    deliveryNoteService.getDeliveryNote(dnName!)
      .then(d => { setDoc(d); syncForm(d); })
      .catch(e => toast.error(e.message))
      .finally(() => setLoading(false));
  }, [dnName, isNew, syncForm]);

  const set = (k: keyof DeliveryNote, v: any) => setForm(f => ({ ...f, [k]: v }));

  const updateItem = (idx: number, k: string, v: any) =>
    setForm(f => {
      const items = [...(f.items || [])];
      const updated: any = { ...items[idx], [k]: v };
      if (k === 'qty' || k === 'rate') {
        const qty  = parseFloat(String(k === 'qty'  ? v : updated.qty))  || 0;
        const rate = parseFloat(String(k === 'rate' ? v : updated.rate)) || 0;
        updated.amount = parseFloat((qty * rate).toFixed(4));
      }
      items[idx] = updated;
      return { ...f, items };
    });

  const handleItemCode = async (idx: number, code: string) => {
    updateItem(idx, 'item_code', code);
    if (!code) return;
    try {
      const r = await fetch(`/api/resource/Item/${encodeURIComponent(code)}`, { credentials: 'include' });
      const body = await r.json();
      const d = body.data;
      if (!d) return;
      setForm(f => {
        const items = [...(f.items || [])];
        items[idx] = { ...items[idx], item_code: code, item_name: d.item_name || code, stock_uom: d.stock_uom || '', uom: d.sales_uom || d.stock_uom || '', description: d.description || '' };
        return { ...f, items };
      });
    } catch { /* ignore */ }
  };

  const addItem = (after?: number) => {
    setForm(f => {
      const items = [...(f.items || [])];
      const pos = after !== undefined ? after + 1 : items.length;
      items.splice(pos, 0, emptyItem());
      return { ...f, items };
    });
  };
  const removeItem = (idx: number) => { setForm(f => { const items = [...(f.items || [])]; items.splice(idx, 1); return { ...f, items }; }); setExpandedItem(null); };

  const updateTax = (idx: number, k: string, v: any) => setTaxes(prev => { const t = [...prev]; t[idx] = { ...t[idx], [k]: v }; return t; });
  const addTax    = () => setTaxes(prev => [...prev, emptyTax()]);
  const removeTax = (idx: number) => { setTaxes(prev => { const t = [...prev]; t.splice(idx, 1); return t; }); setExpandedTax(null); };

  // Totals
  const netTotal   = (form.items || []).reduce((s, it) => s + (it.amount || 0), 0);
  const taxTotal   = taxes.reduce((s, tx) => {
    const pct = taxRatePercent(tx);
    if (tx.charge_type === 'On Net Total') return s + netTotal * (pct / 100);
    if (tx.charge_type === 'Actual') return s + (tx.tax_amount || 0);
    return s + netTotal * (pct / 100);
  }, 0);
  const grandTotal = netTotal + taxTotal;

  const loadTaxTemplate = async (templateName: string) => {
    if (!templateName) return;
    try {
      const r = await fetch(`/api/resource/Sales Taxes and Charges Template/${encodeURIComponent(templateName)}`, { credentials: 'include' });
      const body = await r.json();
      const tmpl = body.data;
      if (tmpl?.taxes?.length) {
        setTaxes(tmpl.taxes.map((tx: any) => ({
          charge_type: tx.charge_type, account_head: tx.account_head,
          description: tx.description, rate: tx.rate,
          cost_center: tx.cost_center, account_currency: tx.account_currency,
          included_in_print_rate: tx.included_in_print_rate ?? 0,
        })));
      }
    } catch { /* ignore */ }
  };

  useEffect(() => {
    if (!isNew || contextSO) return;
    void loadTaxTemplate(DEFAULT_SALES_TAXES_TEMPLATE);
  }, [isNew, contextSO]);

  const buildPayload = (resolvedItems?: any[]): Partial<DeliveryNote> => ({
    customer: form.customer, company: (form as any).company || undefined,
    project: (form as any).project || undefined, cost_center: (form as any).cost_center || undefined,
    posting_date: form.posting_date, currency: form.currency || undefined,
    selling_price_list: (form as any).selling_price_list || 'Standard Selling',
    price_list_currency: (form as any).price_list_currency || form.currency || undefined,
    conversion_rate: (form as any).conversion_rate || 1,
    plc_conversion_rate: (form as any).plc_conversion_rate || 1,
    tax_category: (form as any).tax_category || undefined,
    taxes_and_charges: (form as any).taxes_and_charges || undefined,
    items: (resolvedItems || form.items || []).filter((it: any) => it.item_code).map((it: any, i: number) => ({
      item_code: it.item_code, item_name: it.item_name || it.item_code,
      description: it.description || undefined,
      qty: it.qty ?? 1, uom: it.uom || undefined, stock_uom: it.stock_uom || undefined,
      conversion_factor: it.conversion_factor ?? 1,
      price_list_rate: it.price_list_rate ?? 0,
      discount_percentage: it.discount_percentage ?? 0,
      discount_amount: it.discount_amount ?? 0,
      rate: it.rate ?? 0, amount: it.amount ?? 0,
      is_free_item: it.is_free_item ?? 0, grant_commission: it.grant_commission ?? 0,
      warehouse: it.warehouse || undefined, expense_account: it.expense_account || undefined,
      cost_center: it.cost_center || undefined, project: it.project || (form as any).project || undefined,
      against_sales_order: it.against_sales_order || undefined,
      so_detail: it.so_detail || undefined,
      weight_per_unit: it.weight_per_unit ?? 0, total_weight: it.total_weight ?? 0,
      idx: i + 1,
    })),
    taxes: taxes.filter(tx => tx.account_head).map((tx, i) => ({
      charge_type: tx.charge_type || 'On Net Total',
      account_head: tx.account_head, description: tx.description || tx.account_head,
      included_in_print_rate: tx.included_in_print_rate ?? 0,
      rate: tx.rate ?? 0, cost_center: tx.cost_center || undefined,
      account_currency: tx.account_currency || undefined, idx: i + 1,
    })),
  } as any);

  /** Fetch SO item row names to fill so_detail on items that have against_sales_order but missing so_detail */
  const resolveSoDetails = async (items: any[]): Promise<any[]> => {
    const needsResolve = items.filter(it => it.against_sales_order && !it.so_detail);
    if (!needsResolve.length) return items;
    const soName = needsResolve[0].against_sales_order;
    try {
      const r = await fetch(
        `/api/resource/Sales%20Order%20Item?filters=${encodeURIComponent(JSON.stringify([["parent","=",soName]]))}&fields=${encodeURIComponent(JSON.stringify(["name","item_code","idx"]))}&limit=100`,
        { credentials: 'include' }
      );
      const j = await r.json();
      const soRows: any[] = (j.data || []).sort((a: any, b: any) => (a.idx || 0) - (b.idx || 0));
      const used = new Set<string>();
      return items.map(it => {
        if (!it.against_sales_order || it.so_detail) return it;
        const match = soRows.find((s: any) => s.item_code === it.item_code && !used.has(s.name));
        if (match) { used.add(match.name); return { ...it, so_detail: match.name }; }
        return it;
      });
    } catch { return items; }
  };

  const handleSave = async () => {
    if (!form.customer) { toast.error('Customer is required'); return; }
    try {
      setSaving(true);
      const resolvedItems = await resolveSoDetails([...(form.items || [])]);
      if (isNew) {
        const created = await deliveryNoteService.createDeliveryNote(buildPayload(resolvedItems));
        toast.success('Delivery Note created');
        setIsEditing(false);
        navigate(`/delivery-notes/${created.name}`);
      } else {
        const updated = await deliveryNoteService.updateDeliveryNote(dnName!, buildPayload(resolvedItems));
        setDoc(updated); syncForm(updated);
        toast.success('Delivery Note saved');
        setIsEditing(false);
      }
    } catch (e: unknown) { toast.error(formatFrappeApiError(e) || 'Error saving'); }
    finally { setSaving(false); }
  };

  const handleSubmit = async () => {
    if (!dnName || isNew) return;
    try {
      setSubmitting(true);
      const updated = await deliveryNoteService.submitDeliveryNote(dnName);
      setDoc(updated); syncForm(updated);
      toast.success('Delivery Note submitted');
    } catch (e: unknown) { toast.error(formatFrappeApiError(e) || 'Error submitting'); }
    finally { setSubmitting(false); }
  };

  const createSI = () => {
    const p = new URLSearchParams();
    p.set('dn', dnName!);
    if (form.customer) p.set('customer', form.customer);
    if ((form as any).company) p.set('company', String((form as any).company));
    if ((form as any).project) p.set('project', String((form as any).project));
    navigate(`/invoices/new?${p.toString()}`);
  };

  const editable = isNew || isEditing;
  const isSubmitted = !isNew && doc?.docstatus === 1;

  if (loading) return <div className="flex items-center justify-center min-h-[400px]"><FaSpinner className="animate-spin text-teal-500 text-3xl" /></div>;

  return (
    <div className="min-h-screen bg-gray-50 dark:bg-gray-900 px-6 py-6">
      <ToastContainer position="top-right" autoClose={3500} />

      <div className="flex items-center gap-2 text-sm mb-6 text-gray-500">
        <button onClick={() => navigate('/projects')} className="hover:text-indigo-600">Project Management</button>
        <span>/</span>
        <button onClick={() => navigate('/delivery-notes')} className="hover:text-indigo-600">Delivery Notes</button>
        <span>/</span>
        <span className="text-gray-700 dark:text-gray-300">{isNew ? 'New Delivery Note' : dnName}</span>
      </div>

      <div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 shadow-sm overflow-hidden">

        {/* Header */}
        <div className="px-6 py-4 border-b border-gray-100 dark:border-gray-700 flex items-center justify-between gap-4 flex-wrap">
          <div className="flex items-center gap-3">
            <button onClick={() => navigate('/delivery-notes')} className="text-gray-400 hover:text-gray-700"><FaArrowLeft /></button>
            <FaTruck className="text-teal-500" />
            <div>
              <div className="flex items-center gap-2 flex-wrap">
                <h1 className="text-xl font-bold text-gray-900 dark:text-white">
                  {isNew ? 'New Delivery Note' : (form.customer || dnName)}
                </h1>
                {!isNew && <span className="text-sm text-gray-400 font-normal">{dnName}</span>}
                {!isNew && (
                  <span className={`px-2 py-0.5 rounded text-xs font-semibold ${(() => { const s = doc?.status || ''; if (doc?.docstatus === 2 || s === 'Cancelled') return 'bg-red-100 text-red-700'; if (!doc || doc.docstatus === 0) return 'bg-yellow-100 text-yellow-800'; if (s === 'Completed') return 'bg-green-100 text-green-800'; if (s === 'To Bill') return 'bg-blue-100 text-blue-800'; if (s === 'Return Issued') return 'bg-orange-100 text-orange-800'; if (s === 'Closed') return 'bg-gray-100 text-gray-700'; return 'bg-green-100 text-green-800'; })()}`}>
                    {doc?.docstatus === 2 ? 'Cancelled' : doc?.docstatus === 0 ? 'Draft' : (doc?.status || 'Submitted')}
                  </span>
                )}
              </div>
            </div>
          </div>
          <div className="flex items-center gap-2 flex-wrap">
            {isSubmitted && (
              <CreateDropdown items={[
                { label: 'Sales Invoice', icon: <FaFileInvoiceDollar size={13} />, onClick: createSI },
              ]} />
            )}
            {!isNew && !isEditing && doc?.docstatus === 0 && (
              <button onClick={handleSubmit} disabled={submitting} className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 text-sm font-medium">
                {submitting ? <FaSpinner className="animate-spin" /> : <FaPaperPlane size={12} />} Submit
              </button>
            )}
            {!isNew && !isEditing && !isSubmitted && (
              <button onClick={() => setIsEditing(true)} className="flex items-center gap-2 px-4 py-2 border border-teal-500 text-teal-600 rounded-lg hover:bg-teal-50 text-sm"><FaEdit /> Edit</button>
            )}
            {editable && (
              <>
                <button onClick={handleSave} disabled={saving} className="flex items-center gap-2 px-4 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700 disabled:opacity-50 text-sm font-medium">
                  {saving ? <FaSpinner className="animate-spin" /> : <FaSave />}{saving ? 'Saving…' : 'Save'}
                </button>
                {!isNew && <button onClick={() => { if (doc) syncForm(doc); setIsEditing(false); }} className="px-3 py-2 border border-gray-300 rounded-lg text-gray-600 text-sm"><FaTimes /></button>}
              </>
            )}
          </div>
        </div>

        {/* Main Fields */}
        <div className="px-6 pt-5 pb-4">
          <div className="grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-4">
            <div><FL required>Customer</FL>
              {editable ? <LinkField label="Customer" hideLabel doctype="Customer" value={form.customer || ''} onChange={v => set('customer', v)} placeholder="Select customer…" /> : <RV>{form.customer}</RV>}
            </div>
            <div><FL required>Posting Date</FL>
              {editable ? <input type="date" value={form.posting_date || ''} onChange={e => set('posting_date', e.target.value)} className={inputCls} /> : <RV>{form.posting_date}</RV>}
            </div>
            <div><FL>Company</FL>
              {editable ? <LinkField label="Company" hideLabel doctype="Company" value={(form as any).company || ''} onChange={v => set('company' as any, v)} placeholder="Select company…" /> : <RV>{(form as any).company}</RV>}
            </div>
            <div><FL>Project</FL>
              {editable ? <LinkField label="Project" hideLabel doctype="Project" value={(form as any).project || ''} onChange={v => set('project' as any, v)} placeholder="Select project…" /> : <RV>{(form as any).project}</RV>}
            </div>
            <div><FL>Currency</FL>
              {editable
                ? <select value={form.currency || DEFAULT_CURRENCY} onChange={e => set('currency', e.target.value)} className={inputCls}>
                    <option value="SAR">SAR</option><option value="USD">USD</option><option value="EUR">EUR</option>
                  </select>
                : <RV>{form.currency}</RV>}
            </div>
            <div><FL>Cost Center</FL>
              {editable ? <LinkField label="Cost Center" hideLabel doctype="Cost Center" value={(form as any).cost_center || ''} onChange={v => set('cost_center' as any, v)} /> : <RV>{(form as any).cost_center}</RV>}
            </div>
            {contextSO && <div><FL>Against Sales Order</FL><RV>{contextSO}</RV></div>}
          </div>
        </div>

        {/* Items Section */}
        <div className="border-t border-gray-100 dark:border-gray-700">
          <div className="px-6 py-3 bg-gray-50 dark:bg-gray-900/20 border-b border-gray-100 dark:border-gray-700">
            <span className="text-sm font-semibold text-gray-700 dark:text-gray-300">Items</span>
          </div>
          <div className="px-6 pb-4">
            <div className="overflow-x-auto -mx-2 mt-3">
              <table className="min-w-full text-sm">
                <thead>
                  <tr className="border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/40">
                    <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 w-8">No.</th>
                    <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 min-w-[180px]">Item Code <span className="text-red-400">*</span></th>
                    <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 w-28">UOM <span className="text-red-400">*</span></th>
                    <th className="text-right text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 w-24">Qty <span className="text-red-400">*</span></th>
                    <th className="text-right text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 w-28">Rate ({form.currency || DEFAULT_CURRENCY})</th>
                    <th className="text-right text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 w-28">Amount ({form.currency || DEFAULT_CURRENCY})</th>
                    {editable && <th className="w-16 py-2 px-2" />}
                  </tr>
                </thead>
                <tbody>
                  {(form.items || []).map((it: any, idx) => (
                    <React.Fragment key={idx}>
                      <tr className={`border-b border-gray-100 dark:border-gray-700 align-middle ${expandedItem === idx ? 'bg-blue-50/60 dark:bg-blue-900/10' : ''}`}>
                        <td className="py-1.5 px-3 text-gray-400 text-xs">{idx + 1}</td>
                        <td className="py-1.5 px-2 min-w-[180px]">
                          {editable
                            ? <LinkField label="Item" hideLabel doctype="Item" value={it.item_code || ''} onChange={v => handleItemCode(idx, v)} placeholder="Item Code" />
                            : <span className="font-medium text-gray-800 dark:text-gray-200">{it.item_code || '-'}</span>}
                        </td>
                        <td className="py-1.5 px-2 w-28">
                          {editable
                            ? <LinkField label="UOM" hideLabel doctype="UOM" value={it.uom || ''} onChange={v => updateItem(idx, 'uom', v)} placeholder="UOM" />
                            : <span className="text-gray-500 text-sm">{it.uom || '-'}</span>}
                        </td>
                        <td className="py-1.5 px-2 w-24">
                          {editable ? <input type="number" min={0} step="1" value={it.qty ?? 1} onChange={e => updateItem(idx, 'qty', parseFloat(e.target.value) || 0)} className={inlineNum} /> : <span className="block text-right text-sm pr-1">{it.qty ?? 0}</span>}
                        </td>
                        <td className="py-1.5 px-2 w-28">
                          {editable ? <input type="number" min={0} step="0.01" value={it.rate ?? 0} onChange={e => updateItem(idx, 'rate', parseFloat(e.target.value) || 0)} className={inlineNum} /> : <span className="block text-right text-sm pr-1">{(it.rate ?? 0).toFixed(2)}</span>}
                        </td>
                        <td className="py-1.5 px-3 text-right font-semibold text-gray-900 dark:text-white text-sm">{((it.qty || 0) * (it.rate || 0)).toFixed(2)}</td>
                        {editable && (
                          <td className="py-1.5 px-2">
                            <div className="flex items-center gap-1">
                              <button onClick={() => setExpandedItem(expandedItem === idx ? null : idx)}
                                className={`p-1.5 rounded text-xs ${expandedItem === idx ? 'bg-teal-600 text-white' : 'text-teal-600 hover:bg-teal-50'}`} title="More fields">
                                <FaPencilAlt size={11} />
                              </button>
                              <button onClick={() => removeItem(idx)} className="p-1.5 text-red-400 hover:text-red-600 hover:bg-red-50 rounded"><FaTrash size={11} /></button>
                            </div>
                          </td>
                        )}
                      </tr>
                      {editable && expandedItem === idx && (
                        <DNItemRowEditor
                          item={it} rowNo={idx + 1} currency={form.currency || DEFAULT_CURRENCY}
                          onChange={(k, v) => { if (k === 'item_code') handleItemCode(idx, v as string); else updateItem(idx, k, v); }}
                          onClose={() => setExpandedItem(null)}
                          onDelete={() => removeItem(idx)}
                          onInsertBelow={() => addItem(idx)}
                        />
                      )}
                    </React.Fragment>
                  ))}
                  {editable && (
                    <tr><td colSpan={7} className="py-2 px-3">
                      <button onClick={() => addItem()} className="flex items-center gap-1.5 text-teal-600 hover:text-teal-700 text-sm font-medium"><FaPlus size={10} /> Add Row</button>
                    </td></tr>
                  )}
                </tbody>
              </table>
            </div>
          </div>
        </div>

        {/* Taxes Section */}
        <div className="border-t border-gray-100 dark:border-gray-700">
          <div className="px-6 py-3 bg-gray-50 dark:bg-gray-900/20 border-b border-gray-100 dark:border-gray-700">
            <span className="text-sm font-semibold text-gray-700 dark:text-gray-300">Taxes and Charges</span>
          </div>
          <div className="px-6 pt-4 pb-2 grid grid-cols-1 sm:grid-cols-2 gap-x-8 gap-y-3">
            <div><FL>Tax Category</FL>
              {editable ? <LinkField label="Tax Category" hideLabel doctype="Tax Category" value={(form as any).tax_category || ''} onChange={v => set('tax_category' as any, v)} placeholder="Select tax category…" /> : <RV>{(form as any).tax_category}</RV>}
            </div>
            <div><FL>Sales Taxes and Charges Template</FL>
              {editable
                ? <LinkField label="Sales Taxes and Charges Template" hideLabel doctype="Sales Taxes and Charges Template" value={(form as any).taxes_and_charges || ''} onChange={v => { set('taxes_and_charges' as any, v); loadTaxTemplate(v); }} placeholder="Select template…" />
                : <RV>{(form as any).taxes_and_charges}</RV>}
            </div>
          </div>
          <div className="px-6 pb-4 mt-3">
            <div className="overflow-x-auto -mx-2">
              <table className="min-w-full text-sm">
                <thead>
                  <tr className="border-b border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/40">
                    <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 w-8">No.</th>
                    <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 w-36">Type <span className="text-red-400">*</span></th>
                    <th className="text-left text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 min-w-[180px]">Account Head <span className="text-red-400">*</span></th>
                    <th className="text-right text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 w-24">Tax Rate</th>
                    <th className="text-right text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 w-28">Amount</th>
                    <th className="text-right text-[10px] font-semibold text-gray-500 uppercase py-2 px-3 w-28">Total</th>
                    {editable && <th className="w-16 py-2 px-2" />}
                  </tr>
                </thead>
                <tbody>
                  {taxes.map((tx, idx) => {
                    const txAmt = tx.charge_type === 'On Net Total' ? netTotal * ((tx.rate || 0) / 100) : (tx.tax_amount || 0);
                    const txTotal = netTotal + taxes.slice(0, idx + 1).reduce((s, t) => {
                      return s + (t.charge_type === 'On Net Total' ? netTotal * ((t.rate || 0) / 100) : (t.tax_amount || 0));
                    }, 0);
                    return (
                      <React.Fragment key={idx}>
                        <tr className={`border-b border-gray-100 dark:border-gray-700 align-middle ${expandedTax === idx ? 'bg-blue-50/60 dark:bg-blue-900/10' : ''}`}>
                          <td className="py-1.5 px-3 text-gray-400 text-xs">{idx + 1}</td>
                          <td className="py-1.5 px-2 w-36">
                            {editable
                              ? <select value={tx.charge_type || ''} onChange={e => updateTax(idx, 'charge_type', e.target.value)} className={inlineTxt}>
                                  <option value="">Type…</option>
                                  <option value="Actual">Actual</option>
                                  <option value="On Net Total">On Net Total</option>
                                  <option value="On Previous Row Amount">On Previous Row Amount</option>
                                </select>
                              : <span className="text-sm text-gray-700">{tx.charge_type || '-'}</span>}
                          </td>
                          <td className="py-1.5 px-2 min-w-[180px]">
                            {editable
                              ? <LinkField label="Account Head" hideLabel doctype="Account" value={tx.account_head || ''} onChange={v => updateTax(idx, 'account_head', v)} placeholder="Account…" />
                              : <span className="text-sm text-gray-700">{tx.account_head || '-'}</span>}
                          </td>
                          <td className="py-1.5 px-2 w-24">
                            {editable ? <input type="number" min={0} step="0.01" value={tx.rate ?? 0} onChange={e => updateTax(idx, 'rate', parseFloat(e.target.value) || 0)} className={inlineNum} /> : <span className="block text-right text-sm pr-1">{tx.rate ?? 0}</span>}
                          </td>
                          <td className="py-1.5 px-3 text-right text-sm text-gray-700 dark:text-gray-300">{txAmt.toFixed(2)}</td>
                          <td className="py-1.5 px-3 text-right text-sm font-semibold text-gray-900 dark:text-white">{txTotal.toFixed(2)}</td>
                          {editable && (
                            <td className="py-1.5 px-2">
                              <div className="flex items-center gap-1">
                                <button onClick={() => setExpandedTax(expandedTax === idx ? null : idx)}
                                  className={`p-1.5 rounded text-xs ${expandedTax === idx ? 'bg-teal-600 text-white' : 'text-teal-600 hover:bg-teal-50'}`}><FaPencilAlt size={11} /></button>
                                <button onClick={() => removeTax(idx)} className="p-1.5 text-red-400 hover:text-red-600 hover:bg-red-50 rounded"><FaTrash size={11} /></button>
                              </div>
                            </td>
                          )}
                        </tr>
                        {editable && expandedTax === idx && (
                          <DNTaxRowEditor tax={tx} rowNo={idx + 1}
                            onChange={(k, v) => updateTax(idx, k, v)}
                            onClose={() => setExpandedTax(null)} onDelete={() => removeTax(idx)} />
                        )}
                      </React.Fragment>
                    );
                  })}
                  {editable && (
                    <tr><td colSpan={7} className="py-2 px-3">
                      <button onClick={addTax} className="flex items-center gap-1.5 text-teal-600 hover:text-teal-700 text-sm font-medium"><FaPlus size={10} /> Add Tax Row</button>
                    </td></tr>
                  )}
                </tbody>
              </table>
            </div>
          </div>
        </div>

        {/* Totals */}
        <div className="border-t border-gray-100 dark:border-gray-700 px-6 py-4">
          <div className="flex justify-end">
            <div className="w-full max-w-xs space-y-2 text-sm">
              <div className="flex justify-between text-gray-600 dark:text-gray-400">
                <span>Net Total ({displayTxnCurrency(form.currency)})</span>
                <span className="font-medium">{netTotal.toFixed(2)}</span>
              </div>
              <div className="flex justify-between text-gray-600 dark:text-gray-400">
                <span>Total Taxes and Charges ({displayTxnCurrency(form.currency)})</span>
                <span className="font-medium">{(doc?.total_taxes_and_charges ?? taxTotal).toFixed(2)}</span>
              </div>
              <div className="flex justify-between font-bold text-gray-900 dark:text-white border-t border-gray-200 dark:border-gray-700 pt-2 text-base">
                <span>Grand Total ({displayTxnCurrency(form.currency)})</span>
                <span>{grandTotal.toFixed(2)}</span>
              </div>
            </div>
          </div>
        </div>

        {/* Meta */}
        {!isNew && doc && (
          <div className="border-t border-gray-100 dark:border-gray-700 px-6 py-4 grid grid-cols-3 gap-4 text-sm bg-gray-50 dark:bg-gray-900/20">
            <div><FL>Created By</FL><RV>{doc.owner}</RV></div>
            <div><FL>Created</FL><RV>{doc.creation ? new Date(doc.creation).toLocaleString() : '-'}</RV></div>
            <div><FL>Modified</FL><RV>{doc.modified ? new Date(doc.modified).toLocaleString() : '-'}</RV></div>
          </div>
        )}

        {!isNew && (
          <ActivityLog
            doctype="Delivery Note"
            docname={doc?.name || dnName || ''}
            creationDate={doc?.creation}
            createdBy={doc?.owner}
            compact={false}
            initialVisible={5}
            collapsible
            startCollapsed
          />
        )}
      </div>
    </div>
  );
};

export default DeliveryNoteDetail;
