/**
 * PostalDispatch.tsx
 *
 * Front-office page: postal dispatch / receive log. Tabs split the list
 * by direction (dispatch / receive) plus an "all" view. Status filter
 * chips narrow the visible rows further.
 *
 * Backend (see `server/src/controllers/front-office.controller.js`,
 * block "POSTAL DISPATCH"):
 *   GET    /api/front-office/postal?type=&status=
 *   POST   /api/front-office/postal               (admin only)
 *   PUT    /api/front-office/postal/:id           (admin only)
 *   PUT    /api/front-office/postal/:id/mark-sent       (admin only)
 *   PUT    /api/front-office/postal/:id/mark-delivered  (admin only)
 *   DELETE /api/front-office/postal/:id           (admin only)
 *
 * The page is mounted for school_admin / systems_admin / principal /
 * teacher. Backend permission is admin-only for writes; the page itself
 * hides the "New postal" / "Mark sent" / "Mark delivered" buttons for
 * non-admin roles so non-admins see a read-only audit view.
 */

import { useEffect, useMemo, useState, useRef } from 'react';
import { createPortal } from 'react-dom';
import {
  Send, Inbox, Plus, X, Search, Calendar, MapPin, Truck,
  FileText, CheckCircle2, Filter, Hash, AlertCircle, Mail,
  Upload, Check, Sparkles, Trash2, Edit2
} from 'lucide-react';
import { useFrontOfficeStore, PostalCreate, PostalItem } from '../../../store/frontOffice';
import { useAuthStore } from '../../../store/auth';
import api from '../../../store/auth';

type Tab = 'dispatch' | 'receive' | 'all';
type StatusFilter = 'all' | 'pending' | 'sent' | 'delivered' | 'returned';

const STATUS_COLORS: Record<PostalItem['status'], { bg: string; text: string; border: string; label: string }> = {
  pending:   { bg: 'bg-amber-500/10',   text: 'text-amber-600',   border: 'border-amber-500/20',   label: 'Pending' },
  sent:      { bg: 'bg-blue-500/10',    text: 'text-blue-600',    border: 'border-blue-500/20',    label: 'Sent' },
  delivered: { bg: 'bg-emerald-500/10', text: 'text-emerald-600', border: 'border-emerald-500/20', label: 'Delivered' },
  returned:  { bg: 'bg-rose-500/10',    text: 'text-rose-600',    border: 'border-rose-500/20',    label: 'Returned' },
};

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

interface FormState {
  type: PostalItem['type'];
  reference_number: string;
  sender: string;
  receiver: string;
  address: string;
  courier: string;
  tracking_number: string;
  dispatch_date: string;
  description: string;
  status: PostalItem['status'];
}

const emptyForm = (): FormState => ({
  type: 'dispatch',
  reference_number: '',
  sender: '',
  receiver: '',
  address: '',
  courier: '',
  tracking_number: '',
  dispatch_date: todayIso(),
  description: '',
  status: 'pending'
});

export default function PostalDispatch() {
  const { user } = useAuthStore();
  const isAdmin = user?.role === 'school_admin' || user?.role === 'systems_admin';

  const {
    postal, loading, error,
    fetchPostal, createPostalItem, updatePostalItem, markSent, markDelivered, deletePostalItem,
  } = useFrontOfficeStore();

  const [tab, setTab] = useState<Tab>('all');
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('all');
  const [search, setSearch] = useState('');
  const [from, setFrom] = useState('');
  const [to, setTo] = useState('');
  const [showAdd, setShowAdd] = useState(false);
  const [showBulkModal, setShowBulkModal] = useState(false);
  const [form, setForm] = useState<FormState>(emptyForm());
  const [editingId, setEditingId] = useState<number | null>(null);
  const [submitting, setSubmitting] = useState(false);
  const [busyId, setBusyId] = useState<number | null>(null);
  const [successMsg, setSuccessMsg] = useState<string | null>(null);

  useEffect(() => {
    fetchPostal();
  }, [fetchPostal]);

  // re-filter when the tab or date range changes
  useEffect(() => {
    const params: any = {};
    if (tab !== 'all') params.type = tab;
    if (from) params.from = `${from}T00:00:00`;
    if (to) params.to = `${to}T23:59:59`;
    
    if (Object.keys(params).length > 0 || tab === 'all') {
      fetchPostal(Object.keys(params).length > 0 ? params : undefined);
    }
  }, [tab, from, to, fetchPostal]);

  const setDateRange = (days: number) => {
    const end = new Date();
    const start = new Date();
    start.setDate(end.getDate() - days);
    
    if (days === 0) {
      setFrom(end.toISOString().split('T')[0]);
      setTo(end.toISOString().split('T')[0]);
      return;
    }
    
    setFrom(start.toISOString().split('T')[0]);
    setTo(end.toISOString().split('T')[0]);
  };

  const filtered = useMemo(() => {
    let rows = postal;
    if (statusFilter !== 'all') {
      rows = rows.filter(p => p.status === statusFilter);
    }
    const q = search.toLowerCase().trim();
    if (q) {
      rows = rows.filter(p =>
        p.sender?.toLowerCase().includes(q) ||
        p.receiver?.toLowerCase().includes(q) ||
        p.reference_number?.toLowerCase().includes(q) ||
        p.tracking_number?.toLowerCase().includes(q) ||
        p.courier?.toLowerCase().includes(q) ||
        p.sender_name?.toLowerCase().includes(q) ||
        p.receiver_name?.toLowerCase().includes(q)
      );
    }
    return rows;
  }, [postal, statusFilter, search]);

  const counts = useMemo(() => {
    const byStatus: Record<PostalItem['status'], number> = {
      pending: 0, sent: 0, delivered: 0, returned: 0,
    };
    postal.forEach(p => { byStatus[p.status] = (byStatus[p.status] || 0) + 1; });
    return byStatus;
  }, [postal]);

  const resetForm = () => setForm(emptyForm());

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!form.sender.trim() || !form.receiver.trim()) return;
    setSubmitting(true);
    try {
      const payload: PostalCreate & { status?: PostalItem['status'] } = {
        type: form.type,
        reference_number: form.reference_number.trim() || undefined,
        sender: form.sender.trim(),
        receiver: form.receiver.trim(),
        address: form.address.trim() || undefined,
        courier: form.courier.trim() || undefined,
        tracking_number: form.tracking_number.trim() || undefined,
        dispatch_date: form.dispatch_date || undefined,
        description: form.description.trim() || undefined,
        status: form.status,
      };
      
      if (editingId) {
        await updatePostalItem(editingId, payload);
        setSuccessMsg('Postal item updated.');
      } else {
        await createPostalItem(payload);
        setSuccessMsg('Postal item recorded.');
      }
      
      setShowAdd(false);
      resetForm();
      setTimeout(() => setSuccessMsg(null), 3000);
    } catch (err: any) {
      console.error('handleSubmit error', err);
      alert(err.response?.data?.error || 'Failed to save postal item');
    } finally {
      setSubmitting(false);
    }
  };

  const handleStatusChange = async (id: number, newStatus: PostalItem['status']) => {
    setBusyId(id);
    try {
      if (newStatus === 'sent') {
        await markSent(id);
        setSuccessMsg('Marked as sent.');
      } else if (newStatus === 'delivered') {
        await markDelivered(id);
        setSuccessMsg('Marked as delivered.');
      } else {
        await updatePostalItem(id, { status: newStatus });
        setSuccessMsg(`Status updated to ${newStatus}.`);
      }
      setTimeout(() => setSuccessMsg(null), 3000);
    } catch (err: any) {
      console.error(err);
      alert(err.response?.data?.error || 'Failed to update status');
    } finally {
      setBusyId(null);
    }
  };

  const handleDelete = async (id: number) => {
    if (!window.confirm('Delete this postal record? This cannot be undone.')) return;
    setBusyId(id);
    try { await deletePostalItem(id); setSuccessMsg('Deleted.'); setTimeout(() => setSuccessMsg(null), 3000); }
    catch (err: any) { 
      console.error(err);
      alert(err.response?.data?.error || 'Failed to delete postal item');
    }
    finally { setBusyId(null); }
  };

  const handleEdit = (p: PostalItem) => {
    setEditingId(p.id);
    setForm({
      type: p.type,
      reference_number: p.reference_number || '',
      sender: p.sender,
      receiver: p.receiver,
      address: p.address || '',
      courier: p.courier || '',
      tracking_number: p.tracking_number || '',
      dispatch_date: p.dispatch_date ? new Date(p.dispatch_date).toISOString().split('T')[0] : '',
      description: p.description || '',
      status: p.status
    });
    setShowAdd(true);
  };

  const BulkImportModal = () => {
    const [file, setFile] = useState<File | null>(null);
    const [importing, setImporting] = useState(false);
    const [isDragging, setIsDragging] = useState(false);
    const [progress, setProgress] = useState(0);
    const [result, setResult] = useState<any>(null);
    const [preview, setPreview] = useState<any[]>([]);
    const fileRef = useRef<HTMLInputElement>(null);

    const processFile = (f: File) => {
      setFile(f);
      const reader = new FileReader();
      reader.onload = (event) => {
        const text = event.target?.result as string;
        const rows = text.split('\n').slice(1, 6).map(row => row.split(','));
        setPreview(rows.map(r => ({ sender: r[0], receiver: r[1], type: r[2], courier: r[3] })));
      };
      reader.readAsText(f);
    };

    const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      const f = e.target.files?.[0];
      if (f) processFile(f);
    };

    const handleDragOver = (e: React.DragEvent) => {
      e.preventDefault();
      setIsDragging(true);
    };

    const handleDragLeave = () => {
      setIsDragging(false);
    };

    const handleDrop = (e: React.DragEvent) => {
      e.preventDefault();
      setIsDragging(false);
      const f = e.dataTransfer.files?.[0];
      if (f) processFile(f);
    };

    const runImport = async () => {
      if (!file) return;
      
      setImporting(true);
      setProgress(10);
      
      const progressInterval = setInterval(() => {
        setProgress(prev => {
          if (prev >= 90) return prev;
          return prev + (90 - prev) * 0.1;
        });
      }, 500);

      try {
        const reader = new FileReader();
        reader.onload = async (event) => {
          const text = event.target?.result as string;
          const rows = text.split('\n').map(row => row.split(',').map(cell => cell.trim()));
          const headers = rows[0].map(h => h.toLowerCase().replace(/ /g, '_'));
          const itemsToImport = rows.slice(1).filter(r => r.length > 1).map(row => {
            const obj: any = {};
            headers.forEach((h, i) => { obj[h] = row[i]; });
            return obj;
          });
          
          try {
            const res = await api.post('/front-office/postal/bulk', { items: itemsToImport });
            clearInterval(progressInterval);
            setProgress(100);
            setTimeout(() => {
              setResult(res.data);
              setImporting(false);
              fetchPostal();
            }, 500);
          } catch (err: any) {
            clearInterval(progressInterval);
            setImporting(false);
            alert(err.response?.data?.error || 'Import failed');
          }
        };
        reader.readAsText(file);
      } catch (err) {
        clearInterval(progressInterval);
        setImporting(false);
        alert('File reading failed');
      }
    };

    return createPortal(
      <div className="fixed inset-0 bg-slate-900/60 backdrop-blur-sm z-[1000] flex items-center justify-center p-4" onClick={() => setShowBulkModal(false)}>
        <div className="bg-card rounded-[2.5rem] w-full max-w-2xl shadow-2xl overflow-hidden animate-in zoom-in-95 duration-200 border border-border max-h-[90vh] flex flex-col" onClick={(e) => e.stopPropagation()}>
          <div className="px-10 py-8 bg-muted/50 border-b border-border flex justify-between items-center relative overflow-hidden shrink-0">
            <div className="absolute right-[-20px] top-[-20px] opacity-[0.03] rotate-12">
                <Upload size={180} />
            </div>
            <div className="relative z-10">
              <h2 className="text-2xl font-black text-text tracking-tight flex items-center gap-3 uppercase">
                Bulk Postal Import
              </h2>
              <p className="text-xs font-bold text-text-muted uppercase tracking-widest mt-1">Import CSV postal log</p>
            </div>
            <button onClick={() => setShowBulkModal(false)} className="relative z-10 w-10 h-10 flex items-center justify-center rounded-xl bg-card border border-border text-text-muted hover:text-rose-500 transition-all shadow-sm">
              <X size={20} />
            </button>
          </div>

          <div className="p-10 space-y-8 overflow-y-auto flex-1 custom-scrollbar">
            {!result && !importing && (
              <div className="bg-primary/5 rounded-2xl p-6 border border-primary/10">
                <h4 className="text-[0.65rem] font-black uppercase tracking-[2px] text-primary mb-4 flex items-center gap-2">
                  <FileText size={14} /> Column Protocol (Required Headers)
                </h4>
                <div className="flex flex-wrap gap-2">
                  {['sender', 'receiver', 'type', 'reference_number', 'address', 'courier', 'tracking_number', 'dispatch_date', 'description', 'status'].map(h => (
                    <span key={h} className="px-3 py-1 bg-card border border-border text-primary rounded-lg text-[0.65rem] font-bold font-mono">
                      {h}
                    </span>
                  ))}
                </div>
                <p className="text-[0.65rem] text-text-muted mt-4 italic font-medium">
                  * sender and receiver are required. type: dispatch, receive. status: pending, sent, delivered, returned.
                </p>
              </div>
            )}

            {importing && (
              <div className="py-20 text-center space-y-6 animate-in fade-in">
                <div className="w-16 h-16 bg-primary/10 text-primary rounded-2xl flex items-center justify-center mx-auto animate-bounce">
                  <Sparkles size={32} />
                </div>
                <div className="space-y-2">
                  <h3 className="text-xl font-black text-text uppercase">Processing Records</h3>
                  <p className="text-xs font-bold text-text-muted uppercase tracking-widest">Integrating postal logs...</p>
                </div>
                <div className="max-w-xs mx-auto space-y-2">
                  <div className="h-2 w-full bg-muted rounded-full overflow-hidden border border-border">
                    <div 
                      className="h-full bg-primary transition-all duration-500 ease-out"
                      style={{ width: `${progress}%` }}
                    />
                  </div>
                  <p className="text-[0.6rem] font-black text-primary text-right uppercase">{Math.round(progress)}% Complete</p>
                </div>
              </div>
            )}

            {result ? (
              <div className="space-y-6 text-center py-10 animate-in fade-in slide-in-from-bottom-4">
                <div className={`w-20 h-20 rounded-full flex items-center justify-center mx-auto shadow-inner ${result.failed > 0 ? 'bg-amber-100 dark:bg-amber-900/30 text-amber-600 dark:text-amber-400' : 'bg-emerald-100 dark:bg-emerald-900/30 text-emerald-600 dark:text-emerald-400'}`}>
                  {result.failed > 0 ? <AlertCircle size={40} strokeWidth={3} /> : <Check size={40} strokeWidth={3} />}
                </div>
                <div>
                  <h3 className="text-2xl font-black text-text uppercase tracking-tight">
                    {result.failed > 0 ? 'Import with Exceptions' : 'Import Complete!'}
                  </h3>
                  <p className="text-text-muted font-medium mt-2">Successfully processed postal logs.</p>
                </div>
                <div className="grid grid-cols-2 gap-4 max-w-xs mx-auto">
                  <div className="bg-emerald-50/10 p-4 rounded-2xl border border-emerald-100/20">
                    <p className="text-2xl font-black text-emerald-500">{result.created}</p>
                    <p className="text-[0.6rem] font-black uppercase tracking-widest text-emerald-500">Created</p>
                  </div>
                  <div className="bg-rose-50/10 p-4 rounded-2xl border border-rose-100/20">
                    <p className="text-2xl font-black text-rose-500">{result.failed}</p>
                    <p className="text-[0.6rem] font-black uppercase tracking-widest text-rose-500">Errors</p>
                  </div>
                </div>

                {result.results.filter((r: any) => !r.success).length > 0 && (
                  <div className="text-left space-y-2 mt-6">
                    <p className="text-[0.6rem] font-black uppercase tracking-[2px] text-rose-500 px-1">Failed Rows</p>
                    <div className="bg-rose-50/5 rounded-xl border border-rose-100/10 max-h-40 overflow-y-auto custom-scrollbar">
                      {result.results.filter((r: any) => !r.success).map((r: any, i: number) => (
                        <div key={i} className="px-4 py-2 border-b border-rose-100/5 last:border-0 flex justify-between items-center gap-4">
                          <span className="text-[0.65rem] font-bold text-text truncate">{r.sender} → {r.receiver}</span>
                          <span className="text-[0.6rem] font-black text-rose-500 uppercase shrink-0">{r.error}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                )}

                <button 
                  onClick={() => setShowBulkModal(false)}
                  className="mt-6 px-12 py-4 bg-primary hover:bg-primary/90 text-white font-black uppercase tracking-widest text-[0.7rem] rounded-2xl transition-all shadow-xl"
                >
                  Done
                </button>
              </div>
            ) : !importing && (
              <div className="space-y-6">
                <div 
                  onClick={() => fileRef.current?.click()}
                  onDragOver={handleDragOver}
                  onDragLeave={handleDragLeave}
                  onDrop={handleDrop}
                  className={`border-2 border-dashed rounded-3xl p-12 text-center transition-all cursor-pointer group ${isDragging ? 'border-primary bg-primary/10 scale-[1.02]' : 'border-border hover:border-primary hover:bg-primary/5'}`}
                >
                  <input type="file" ref={fileRef} className="hidden" accept=".csv,.txt" onChange={handleFileChange} />
                  <div className="w-16 h-16 bg-muted rounded-2xl flex items-center justify-center mx-auto mb-4 group-hover:scale-110 transition-transform">
                    <Upload className={`transition-colors ${isDragging ? 'text-primary' : 'text-text-muted group-hover:text-primary'}`} size={32} />
                  </div>
                  <p className="text-sm font-bold text-text">{file ? file.name : 'Select CSV file to import'}</p>
                  <p className="text-xs text-text-muted mt-1 font-medium uppercase tracking-widest">Drag and drop or click to browse</p>
                </div>

                {preview.length > 0 && (
                  <div className="space-y-3">
                    <p className="text-[0.6rem] font-black uppercase tracking-[2px] text-text-muted px-1">Data Preview (Top 5 rows)</p>
                    <div className="bg-muted/50 rounded-2xl border border-border overflow-hidden overflow-x-auto">
                      <table className="w-full text-left text-[0.65rem]">
                        <thead className="bg-muted border-b border-border">
                          <tr>
                            {Object.keys(preview[0]).map(h => <th key={h} className="px-4 py-2 font-black uppercase text-text-muted">{h}</th>)}
                          </tr>
                        </thead>
                        <tbody className="divide-y divide-border">
                          {preview.map((row, i) => (
                            <tr key={i}>
                              {Object.values(row).map((v: any, j) => <td key={j} className="px-4 py-2 font-medium text-text-secondary">{v}</td>)}
                            </tr>
                          ))}
                        </tbody>
                      </table>
                    </div>
                  </div>
                )}

                <div className="flex gap-4 pt-4">
                  <button 
                    disabled={!file || importing}
                    onClick={runImport}
                    className="flex-1 py-5 bg-primary hover:bg-primary/90 disabled:bg-muted disabled:text-text-muted text-white font-black uppercase tracking-widest text-[0.7rem] rounded-2xl transition-all shadow-xl active:scale-95 flex items-center justify-center gap-2"
                  >
                    <Sparkles size={16} />
                    Run Directory Import
                  </button>
                </div>
              </div>
            )}
          </div>
        </div>
      </div>
    ,
      document.body
    );
  };

  const tabs: { id: Tab; label: string; icon: any }[] = [
    { id: 'all', label: 'All', icon: Mail },
    { id: 'dispatch', label: 'Dispatch', icon: Send },
    { id: 'receive', label: 'Receive', icon: Inbox },
  ];

  return (
    <div className="p-6">
      <div className="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-6">
        <div>
          <h1 className="text-2xl font-bold text-text flex items-center gap-2">
            <Mail className="text-primary" />
            Postal Dispatch
          </h1>
          <p className="text-text-muted text-sm mt-1">
            Track incoming and outgoing mail, couriers, and deliveries.
            {!isAdmin && <span className="text-text-muted/80 ml-1">(Read-only — admin role required to log or update items.)</span>}
          </p>
        </div>
        {isAdmin && (
          <button
            onClick={() => { resetForm(); setShowAdd(true); }}
            className="flex items-center justify-center gap-2 px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-dark transition-colors shadow-sm"
          >
            <Plus size={20} />
            New Postal
          </button>
        )}
      </div>

      {successMsg && (
        <div className="mb-4 px-4 py-2 bg-emerald-500/10 text-emerald-600 border border-emerald-500/20 rounded-lg text-sm font-semibold flex items-center gap-2 animate-in fade-in duration-200">
          <CheckCircle2 size={16} /> {successMsg}
        </div>
      )}
      {error && (
        <div className="mb-4 px-4 py-2 bg-rose-500/10 text-rose-600 border border-rose-500/20 rounded-lg text-sm font-semibold flex items-center gap-2">
          <AlertCircle size={16} /> {error}
        </div>
      )}

      {/* Tabs */}
      <div className="flex flex-wrap items-center gap-2 mb-4">
        {tabs.map(t => {
          const Icon = t.icon;
          const active = tab === t.id;
          return (
            <button
              key={t.id}
              onClick={() => setTab(t.id)}
              className={`flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-semibold border transition-colors ${active
                ? 'bg-primary text-white border-primary shadow-sm'
                : 'bg-card text-text-secondary border-border hover:bg-background-alt'}`}
            >
              <Icon size={16} />
              {t.label}
            </button>
          );
        })}
        <div className="ml-auto flex items-center gap-2">
          <Filter size={14} className="text-text-muted" />
          {(['all', 'pending', 'sent', 'delivered', 'returned'] as StatusFilter[]).map(s => {
            const active = statusFilter === s;
            const count = s === 'all' ? postal.length : counts[s as PostalItem['status']] || 0;
            return (
              <button
                key={s}
                onClick={() => setStatusFilter(s)}
                className={`px-3 py-1.5 rounded-full text-xs font-semibold border transition-colors ${active
                  ? 'bg-card border-primary text-primary shadow-sm'
                  : 'bg-background border-border text-text-muted hover:text-text'}`}
              >
                {s === 'all' ? 'All' : s.charAt(0).toUpperCase() + s.slice(1)}
                <span className="ml-1.5 text-[0.6rem] opacity-70">{count}</span>
              </button>
            );
          })}
        </div>
      </div>

      <div className="bg-card rounded-xl shadow-sm border border-border overflow-hidden">
        <div className="p-4 border-b border-border flex flex-col md:flex-row gap-3 items-stretch md:items-center justify-between bg-background-alt/50">
          <div className="relative w-full md:w-96">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 text-text-muted" size={18} />
            <input
              type="text"
              placeholder="Search ref, sender, receiver, courier, tracking…"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="w-full pl-10 pr-4 py-2 bg-background border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all text-sm text-text"
            />
          </div>
        </div>

        <div className="overflow-x-auto">
          <table className="w-full text-left">
            <thead>
              <tr className="bg-background-alt/50 border-b border-border text-xs uppercase tracking-wider text-text-muted font-semibold">
                <th className="px-6 py-4">Reference / Type</th>
                <th className="px-6 py-4">Sender → Receiver</th>
                <th className="px-6 py-4">Courier / Tracking</th>
                <th className="px-6 py-4">Dispatched</th>
                <th className="px-6 py-4">Status</th>
                {isAdmin && <th className="px-6 py-4 text-right">Actions</th>}
              </tr>
            </thead>
            <tbody className="divide-y divide-border/50 text-sm">
              {loading ? (
                <tr>
                  <td colSpan={isAdmin ? 6 : 5} className="px-6 py-12 text-center text-text-muted">
                    <div className="flex flex-col items-center gap-2">
                      <div className="w-8 h-8 border-4 border-primary border-t-transparent rounded-full animate-spin"></div>
                      <span>Loading postal items…</span>
                    </div>
                  </td>
                </tr>
              ) : filtered.length === 0 ? (
                <tr>
                  <td colSpan={isAdmin ? 6 : 5} className="px-6 py-12 text-center text-text-muted">
                    <Mail size={48} className="mx-auto mb-4 opacity-20" />
                    <p>No postal items match your filters.</p>
                  </td>
                </tr>
              ) : (
                filtered.map(p => {
                  const colors = STATUS_COLORS[p.status];
                  return (
                    <tr key={p.id} className="hover:bg-background-alt/40 transition-colors">
                      <td className="px-6 py-4">
                        <div className="space-y-1">
                          <div className="flex items-center gap-1.5 text-xs font-mono text-text-secondary">
                            <Hash size={12} className="text-text-muted" />
                            {p.reference_number || `PS-${p.id}`}
                          </div>
                          <div className="flex items-center gap-1.5 text-xs">
                            {p.type === 'dispatch'
                              ? <><Send size={12} className="text-blue-500" /> <span className="text-text-muted">Outgoing</span></>
                              : <><Inbox size={12} className="text-emerald-500" /> <span className="text-text-muted">Incoming</span></>}
                          </div>
                        </div>
                      </td>
                      <td className="px-6 py-4 max-w-xs">
                        <div className="space-y-0.5">
                          <p className="text-text font-semibold truncate">{p.sender_name || p.sender}</p>
                          <p className="text-xs text-text-muted truncate">→ {p.receiver_name || p.receiver}</p>
                          {p.address && (
                            <p className="text-xs text-text-muted/80 flex items-center gap-1 mt-0.5 truncate">
                              <MapPin size={10} /> {p.address}
                            </p>
                          )}
                        </div>
                      </td>
                      <td className="px-6 py-4 text-text-secondary">
                        <div className="space-y-0.5 text-xs">
                          {p.courier ? (
                            <div className="flex items-center gap-1.5"><Truck size={12} className="text-text-muted" /> {p.courier}</div>
                          ) : <span className="text-text-muted/60">—</span>}
                          {p.tracking_number && (
                            <div className="font-mono text-text-muted/80">#{p.tracking_number}</div>
                          )}
                        </div>
                      </td>
                      <td className="px-6 py-4 text-text-secondary text-xs">
                        <div className="flex items-center gap-1.5">
                          <Calendar size={12} className="text-primary" />
                          {p.dispatch_date ? new Date(p.dispatch_date).toLocaleDateString() : '—'}
                        </div>
                        {p.received_date && (
                          <div className="text-[0.65rem] text-text-muted mt-1">
                            Delivered {new Date(p.received_date).toLocaleDateString()}
                          </div>
                        )}
                      </td>
                      <td className="px-6 py-4">
                        <span className={`inline-flex items-center gap-1 px-2.5 py-1 rounded-full text-[0.65rem] font-black uppercase ${colors.bg} ${colors.text} border ${colors.border}`}>
                          {colors.label}
                        </span>
                      </td>
                      {isAdmin && (
                        <td className="px-6 py-4 text-right">
                          <div className="flex items-center justify-end gap-2">
                            <select
                              value={p.status}
                              disabled={busyId === p.id}
                              onChange={(e) => handleStatusChange(p.id, e.target.value as PostalItem['status'])}
                              className="text-xs font-semibold bg-background border border-border rounded-lg px-2 py-1.5 focus:outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary transition-all cursor-pointer"
                            >
                              <option value="pending">Mark Pending</option>
                              <option value="sent">Mark Sent</option>
                              <option value="delivered">Mark Delivered</option>
                              <option value="returned">Mark Returned</option>
                            </select>
                            <button
                              onClick={() => handleEdit(p)}
                              className="p-1.5 text-text-muted hover:text-primary hover:bg-primary/10 rounded-lg transition-colors"
                              title="Edit"
                            >
                              <Edit2 size={16} />
                            </button>
                            <button
                              disabled={busyId === p.id}
                              onClick={() => handleDelete(p.id)}
                              className="p-1.5 text-text-muted hover:text-rose-600 hover:bg-rose-500/10 rounded-lg transition-colors disabled:opacity-50"
                              title="Delete"
                            >
                              <Trash2 size={16} />
                            </button>
                          </div>
                        </td>
                      )}
                    </tr>
                  );
                })
              )}
            </tbody>
          </table>
        </div>
      </div>

      {/* Add modal */}
      {showAdd && createPortal(
        <div className="fixed inset-0 bg-slate-900/60 backdrop-blur-sm z-[1000] flex items-center justify-center p-4" onClick={() => setShowAdd(false)}>
          <div className="bg-card rounded-[2.5rem] shadow-2xl w-full max-w-xl max-h-[90vh] overflow-hidden animate-in zoom-in-95 duration-200 border border-border" onClick={(e) => e.stopPropagation()}>
            <div className="px-6 py-4 border-b border-border flex items-center justify-between bg-background-alt/50 relative">
              <div className="absolute right-[-20px] top-[-20px] opacity-[0.03] rotate-12">
                  <FileText size={180} />
              </div>
              <div className="relative z-10">
                <h2 className="text-lg font-bold text-text flex items-center gap-2">
                  {editingId ? <Edit2 className="text-primary" size={20} /> : <Plus className="text-primary" size={20} />}
                  {editingId ? 'Edit Postal Item' : 'New Postal Item'}
                </h2>
              </div>
              <button
                onClick={() => { setShowAdd(false); resetForm(); setEditingId(null); }}
                className="relative z-10 p-2 text-text-muted hover:text-text hover:bg-background-alt rounded-lg transition-colors"
                aria-label="Close"
              >
                <X size={20} />
              </button>
            </div>

            <form onSubmit={handleSubmit} className="p-6">
              <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
                <div className="space-y-4">
                  <div className="grid grid-cols-2 gap-3">
                    <div>
                      <label className="block text-sm font-semibold text-text-secondary mb-1.5">Type</label>
                      <select
                        value={form.type}
                        onChange={e => setForm({ ...form, type: e.target.value as FormState['type'] })}
                        className="form-input w-full px-3 py-2 bg-background border border-border rounded-lg text-text"
                      >
                        <option value="dispatch">Dispatch (outgoing)</option>
                        <option value="receive">Receive (incoming)</option>
                      </select>
                    </div>
                    <div>
                      <label className="block text-sm font-semibold text-text-secondary mb-1.5">Status</label>
                      <select
                        value={form.status}
                        onChange={e => setForm({ ...form, status: e.target.value as FormState['status'] })}
                        className="form-input w-full px-3 py-2 bg-background border border-border rounded-lg text-text"
                      >
                        <option value="pending">Pending</option>
                        <option value="sent">Sent</option>
                        <option value="delivered">Delivered</option>
                        <option value="returned">Returned</option>
                      </select>
                    </div>
                  </div>
                  <div>
                    <label className="block text-sm font-semibold text-text-secondary mb-1.5">Reference #</label>
                    <input
                      type="text"
                      value={form.reference_number}
                      onChange={e => setForm({ ...form, reference_number: e.target.value })}
                      className="form-input w-full px-3 py-2 bg-background border border-border rounded-lg text-text"
                      placeholder="PS-2026-001"
                    />
                  </div>
                  <div>
                    <label className="block text-sm font-semibold text-text-secondary mb-1.5">
                      Sender <span className="text-rose-500">*</span>
                    </label>
                    <input
                      required
                      type="text"
                      value={form.sender}
                      onChange={e => setForm({ ...form, sender: e.target.value })}
                      className="form-input w-full px-3 py-2 bg-background border border-border rounded-lg text-text"
                      placeholder="Name or organisation"
                    />
                  </div>
                  <div>
                    <label className="block text-sm font-semibold text-text-secondary mb-1.5">
                      Receiver <span className="text-rose-500">*</span>
                    </label>
                    <input
                      required
                      type="text"
                      value={form.receiver}
                      onChange={e => setForm({ ...form, receiver: e.target.value })}
                      className="form-input w-full px-3 py-2 bg-background border border-border rounded-lg text-text"
                      placeholder="Name or organisation"
                    />
                  </div>
                  <div>
                    <label className="block text-sm font-semibold text-text-secondary mb-1.5">Address</label>
                    <input
                      type="text"
                      value={form.address}
                      onChange={e => setForm({ ...form, address: e.target.value })}
                      className="form-input w-full px-3 py-2 bg-background border border-border rounded-lg text-text"
                      placeholder="Delivery address"
                    />
                  </div>
                </div>

                <div className="space-y-4">
                  <div className="grid grid-cols-2 gap-3">
                    <div>
                      <label className="block text-sm font-semibold text-text-secondary mb-1.5">Courier</label>
                      <input
                        type="text"
                        value={form.courier}
                        onChange={e => setForm({ ...form, courier: e.target.value })}
                        className="form-input w-full px-3 py-2 bg-background border border-border rounded-lg text-text"
                        placeholder="e.g. DHL, EMS"
                      />
                    </div>
                    <div>
                      <label className="block text-sm font-semibold text-text-secondary mb-1.5">Tracking #</label>
                      <input
                        type="text"
                        value={form.tracking_number}
                        onChange={e => setForm({ ...form, tracking_number: e.target.value })}
                        className="form-input w-full px-3 py-2 bg-background border border-border rounded-lg text-text"
                      />
                    </div>
                  </div>
                  <div>
                    <label className="block text-sm font-semibold text-text-secondary mb-1.5">Dispatch Date</label>
                    <input
                      type="date"
                      value={form.dispatch_date}
                      onChange={e => setForm({ ...form, dispatch_date: e.target.value })}
                      className="form-input w-full px-3 py-2 bg-background border border-border rounded-lg text-text"
                    />
                  </div>
                  <div>
                    <label className="block text-sm font-semibold text-text-secondary mb-1.5">Description</label>
                    <textarea
                      rows={4}
                      value={form.description}
                      onChange={e => setForm({ ...form, description: e.target.value })}
                      className="form-input w-full px-3 py-2 bg-background border border-border rounded-lg text-text resize-none"
                      placeholder="What's inside / notes…"
                    />
                  </div>
                </div>
              </div>

              <div className="mt-8 pt-6 border-t border-border flex items-center justify-end gap-3">
                <button
                  type="button"
                  onClick={() => { setShowAdd(false); resetForm(); }}
                  className="px-6 py-2 text-text-secondary hover:bg-background-alt rounded-lg transition-colors font-semibold"
                >
                  Cancel
                </button>
                <button
                  type="submit"
                  disabled={submitting}
                  className="px-8 py-2 bg-primary text-white rounded-lg hover:bg-primary-dark transition-colors shadow-lg shadow-primary/20 font-semibold disabled:opacity-50"
                >
                  {submitting ? 'Saving…' : 'Record'}
                </button>
              </div>
            </form>
          </div>
        </div>
      ,
        document.body
      )}
    </div>
  );
}
