'use client';

import { useCallback, useEffect, useMemo, useState } from 'react';
import { Plus, Search, Trash2, Pencil, Copy, Archive, ArchiveRestore, Upload, Ticket, History, Share2, X, Lock, Download, BarChart3 } from 'lucide-react';
import { BarChart, Bar, XAxis, YAxis, Tooltip, CartesianGrid } from 'recharts';
import { SafeChart } from '@client/components/ui/SafeChart';
import Link from 'next/link';
import { toast } from 'sonner';
import { useAuth } from '@client/contexts/AuthContext';
import { useLanguage } from '@client/contexts/LanguageContext';
import { usePageHeader } from '@client/contexts/PageHeaderContext';
import FeatureGuard from '@client/components/FeatureGuard';
import { isFeatureLockedError } from '@client/utils/isFeatureLockedError';
import { isForbiddenError } from '@client/utils/isForbiddenError';
import PermissionDenied from '@client/components/ui/PermissionDenied';
import { listBranches, type Branch } from '@client/api/branches';
import { listMenuItems, listMenuCategories } from '@client/api/menu';
import { InlineTableSkeleton } from '@client/components/skeletons/PageSkeletons';
import ConfirmModal from '@client/components/ui/ConfirmModal';
import {
  listCoupons, createCoupon, updateCoupon, deleteCoupon, archiveCoupon, activateCoupon,
  duplicateCoupon, listRedemptions, bulkImportCoupons,
  getCouponAnalytics, redemptionsCsvUrl,
  type Coupon, type CouponRedemption, type CouponAnalytics,
} from '@client/api/coupons';

type StatusFilter = 'active' | 'archived' | 'all';

const ORDER_TYPES = ['dine-in', 'takeaway', 'delivery'] as const;
const CHANNELS = ['chat', 'whatsapp', 'storefront', 'voice'] as const;

interface BogoConfigForm {
  buy_target_type: 'item' | 'category' | '';
  buy_target_id: string;
  get_target_type: 'item' | 'category' | '';
  get_target_id: string;
  get_discount_kind: 'free' | 'percent';
  get_discount_percent: string;
}

interface FormState {
  code: string;
  display_name: string;
  description: string;
  type: 'percent' | 'fixed' | 'bogo';
  value: string;
  valid_from: string;
  valid_until: string;
  total_redemption_cap: string;
  per_customer_cap: string;
  min_order_value: string;
  applicable_order_types: string[];
  applicable_channels: string[];
  applicable_branches: string[];
  branch_id: string;
  status: 'active' | 'archived';
  stack_with_loyalty: boolean;
  stack_with_gift_card: boolean;
  bogo_config: BogoConfigForm;
}

const emptyBogoConfig = (): BogoConfigForm => ({
  buy_target_type: '',
  buy_target_id: '',
  get_target_type: '',
  get_target_id: '',
  get_discount_kind: 'free',
  get_discount_percent: '100',
});

const emptyForm = (branchId: string): FormState => ({
  code: '',
  display_name: '',
  description: '',
  type: 'percent',
  value: '10',
  valid_from: '',
  valid_until: '',
  total_redemption_cap: '',
  per_customer_cap: '',
  min_order_value: '0',
  applicable_order_types: [...ORDER_TYPES],
  applicable_channels: [...CHANNELS],
  applicable_branches: branchId ? [branchId] : [],
  branch_id: branchId,
  status: 'active',
  stack_with_loyalty: true,
  stack_with_gift_card: true,
  bogo_config: emptyBogoConfig(),
});

export default function CouponsPage() {
  return (
    <FeatureGuard feature="coupons" featureName="Coupons">
      <CouponsPageInner />
    </FeatureGuard>
  );
}

function CouponsPageInner() {
  const { t } = useLanguage();
  usePageHeader(t('nav.coupons', 'Coupons'), t('coupons.subtitle', 'Create branch-level promo codes for chat, WhatsApp and your storefront.'));
  const { branchId, restaurantId } = useAuth();

  const [branches, setBranches] = useState<Branch[]>([]);
  const [activeBranchId, setActiveBranchId] = useState<string>('');
  const [coupons, setCoupons] = useState<Coupon[]>([]);
  const [loading, setLoading] = useState(true);
  const [forbidden, setForbidden] = useState(false);
  const [search, setSearch] = useState('');
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('active');

  const [editing, setEditing] = useState<Coupon | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [form, setForm] = useState<FormState>(emptyForm(''));
  const [saving, setSaving] = useState(false);

  const [confirmDelete, setConfirmDelete] = useState<Coupon | null>(null);
  const [historyOpen, setHistoryOpen] = useState<Coupon | null>(null);
  const [historyRows, setHistoryRows] = useState<CouponRedemption[]>([]);
  const [historyLoading, setHistoryLoading] = useState(false);

  const [importOpen, setImportOpen] = useState(false);

  const todayIso = useMemo(() => new Date().toISOString().slice(0, 10), []);
  const monthAgoIso = useMemo(() => {
    const d = new Date();
    d.setDate(d.getDate() - 29);
    return d.toISOString().slice(0, 10);
  }, []);
  const [analyticsFrom, setAnalyticsFrom] = useState<string>(monthAgoIso);
  const [analyticsTo, setAnalyticsTo] = useState<string>(todayIso);
  const [analytics, setAnalytics] = useState<CouponAnalytics | null>(null);
  const [analyticsLoading, setAnalyticsLoading] = useState(false);

  // Menu items + categories used to populate BOGO target selectors.
  // Loaded lazily once when the form opens so the page itself stays light.
  const [menuItems, setMenuItems] = useState<{ id: string; name: string }[]>([]);
  const [menuCategories, setMenuCategories] = useState<{ id: string; name: string }[]>([]);
  const [menuLoaded, setMenuLoaded] = useState(false);

  const reload = useCallback(async (bid?: string) => {
    if (!restaurantId) { setLoading(false); return; }
    const branchToUse = bid ?? activeBranchId;
    if (!branchToUse) { setLoading(false); return; }
    setLoading(true);
    try {
      const params: Record<string, string> = { branch_id: branchToUse, limit: '200' };
      if (statusFilter !== 'all') params.status = statusFilter;
      if (search.trim()) params.search = search.trim();
      const res = await listCoupons(params);
      setCoupons(res.data ?? []);
    } catch (err) {
      if (isForbiddenError(err)) {
        setForbidden(true);
      } else if (!isFeatureLockedError(err)) {
        toast.error((err as Error).message || 'Failed to load coupons');
      }
    } finally {
      setLoading(false);
    }
  }, [restaurantId, activeBranchId, statusFilter, search]);

  // Initial load: branches
  useEffect(() => {
    (async () => {
      try {
        const res = await listBranches({ limit: '100' });
        const list = (res.branches as Branch[]) ?? [];
        setBranches(list);
        const initial = branchId && list.some(b => b.id === branchId) ? branchId : list[0]?.id ?? '';
        setActiveBranchId(initial);
        setForm(emptyForm(initial));
      } catch (err) {
        toast.error((err as Error).message || 'Failed to load branches');
        setLoading(false);
      }
    })();
  }, [branchId]);

  useEffect(() => { if (activeBranchId) reload(activeBranchId); }, [activeBranchId, statusFilter, reload]);

  const loadAnalytics = useCallback(async () => {
    if (!activeBranchId) return;
    setAnalyticsLoading(true);
    try {
      const params: Record<string, string> = { branch_id: activeBranchId };
      if (analyticsFrom) params.from = new Date(analyticsFrom + 'T00:00:00').toISOString();
      if (analyticsTo) params.to = new Date(analyticsTo + 'T23:59:59.999').toISOString();
      const res = await getCouponAnalytics(params);
      setAnalytics(res);
    } catch (err) {
      toast.error((err as Error).message || 'Failed to load analytics');
    } finally {
      setAnalyticsLoading(false);
    }
  }, [activeBranchId, analyticsFrom, analyticsTo]);

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

  const filtered = useMemo(() => coupons, [coupons]);
  const activeBranch = branches.find(b => b.id === activeBranchId);

  async function ensureMenuLoaded() {
    if (menuLoaded) return;
    try {
      const [itemsRes, catsRes] = await Promise.all([
        listMenuItems({ limit: '500' }) as Promise<{ items?: { id: string; name: string }[] }>,
        listMenuCategories() as Promise<{ categories?: { id: string; name: string }[] }>,
      ]);
      setMenuItems(itemsRes.items ?? []);
      setMenuCategories(catsRes.categories ?? []);
      setMenuLoaded(true);
    } catch {
      // Non-fatal: form still works without selectors (e.g. percent/fixed coupons).
    }
  }

  function openNew() {
    setEditing(null);
    setForm(emptyForm(activeBranchId));
    setShowForm(true);
    ensureMenuLoaded();
  }

  function openEdit(c: Coupon) {
    setEditing(c);
    const bogo = (c.bogo_config ?? {}) as Partial<{
      buy_target_type: 'item' | 'category';
      buy_target_id: string;
      get_target_type: 'item' | 'category';
      get_target_id: string;
      get_discount_kind: 'free' | 'percent';
      get_discount_percent: number;
    }>;
    setForm({
      code: c.code,
      display_name: c.display_name ?? '',
      description: c.description ?? '',
      type: c.type,
      value: String(c.value ?? 0),
      valid_from: c.valid_from ? c.valid_from.slice(0, 16) : '',
      valid_until: c.valid_until ? c.valid_until.slice(0, 16) : '',
      total_redemption_cap: c.total_redemption_cap != null ? String(c.total_redemption_cap) : '',
      per_customer_cap: c.per_customer_cap != null ? String(c.per_customer_cap) : '',
      min_order_value: String(c.min_order_value ?? 0),
      applicable_order_types: c.applicable_order_types ?? [...ORDER_TYPES],
      applicable_channels: c.applicable_channels ?? [...CHANNELS],
      applicable_branches: c.applicable_branches && c.applicable_branches.length > 0
        ? c.applicable_branches
        : [c.branch_id],
      branch_id: c.branch_id,
      status: c.status,
      stack_with_loyalty: c.stack_with_loyalty ?? true,
      stack_with_gift_card: c.stack_with_gift_card ?? true,
      bogo_config: {
        buy_target_type: (bogo.buy_target_type as 'item' | 'category' | undefined) ?? '',
        buy_target_id: bogo.buy_target_id ?? '',
        get_target_type: (bogo.get_target_type as 'item' | 'category' | undefined) ?? '',
        get_target_id: bogo.get_target_id ?? '',
        get_discount_kind: bogo.get_discount_kind ?? 'free',
        get_discount_percent: String(bogo.get_discount_percent ?? 100),
      },
    });
    setShowForm(true);
    ensureMenuLoaded();
  }

  function buildPayload(): Record<string, unknown> {
    const payload: Record<string, unknown> = {
      code: form.code.trim().toUpperCase(),
      display_name: form.display_name.trim() || undefined,
      description: form.description.trim() || undefined,
      type: form.type,
      value: Number(form.value || 0),
      valid_from: form.valid_from ? new Date(form.valid_from).toISOString() : null,
      valid_until: form.valid_until ? new Date(form.valid_until).toISOString() : null,
      total_redemption_cap: form.total_redemption_cap ? Number(form.total_redemption_cap) : null,
      per_customer_cap: form.per_customer_cap ? Number(form.per_customer_cap) : null,
      min_order_value: Number(form.min_order_value || 0),
      applicable_order_types: form.applicable_order_types,
      applicable_channels: form.applicable_channels,
      // applicable_branches lets a single coupon work across several branches
      // (e.g. a chain-wide promo). Always include the owning branch_id so the
      // coupon resolves on its home branch even if the user de-selected it.
      applicable_branches: Array.from(new Set([form.branch_id, ...form.applicable_branches])).filter(Boolean),
      branch_id: form.branch_id,
      status: form.status,
      stack_with_loyalty: form.stack_with_loyalty,
      stack_with_gift_card: form.stack_with_gift_card,
    };
    if (form.type === 'bogo') {
      const b = form.bogo_config;
      payload.bogo_config = {
        ...(b.buy_target_type ? { buy_target_type: b.buy_target_type } : {}),
        ...(b.buy_target_id ? { buy_target_id: b.buy_target_id } : {}),
        ...(b.get_target_type ? { get_target_type: b.get_target_type } : {}),
        ...(b.get_target_id ? { get_target_id: b.get_target_id } : {}),
        get_discount_kind: b.get_discount_kind,
        ...(b.get_discount_kind === 'percent'
          ? { get_discount_percent: Number(b.get_discount_percent || 0) }
          : {}),
      };
    }
    return payload;
  }

  async function handleSave() {
    if (!form.code.trim()) { toast.error('Code is required'); return; }
    if (!form.branch_id) { toast.error('Choose a branch'); return; }
    setSaving(true);
    try {
      if (editing) {
        await updateCoupon(editing.id, buildPayload());
        toast.success('Coupon updated');
      } else {
        await createCoupon(buildPayload());
        toast.success('Coupon created');
      }
      setShowForm(false);
      reload();
    } catch (err) {
      toast.error((err as Error).message || 'Save failed');
    } finally {
      setSaving(false);
    }
  }

  async function handleDuplicate(c: Coupon) {
    try {
      await duplicateCoupon(c.id);
      toast.success(`Duplicated ${c.code}`);
      reload();
    } catch (err) {
      toast.error((err as Error).message || 'Duplicate failed');
    }
  }

  async function handleArchiveToggle(c: Coupon) {
    try {
      if (c.status === 'archived') {
        await activateCoupon(c.id);
        toast.success(`${c.code} reactivated`);
      } else {
        await archiveCoupon(c.id);
        toast.success(`${c.code} archived`);
      }
      reload();
    } catch (err) {
      toast.error((err as Error).message || 'Update failed');
    }
  }

  async function handleDelete() {
    if (!confirmDelete) return;
    try {
      await deleteCoupon(confirmDelete.id);
      toast.success('Coupon deleted');
      setConfirmDelete(null);
      reload();
    } catch (err) {
      toast.error((err as Error).message || 'Delete failed');
    }
  }

  async function openHistory(c: Coupon) {
    setHistoryOpen(c);
    setHistoryRows([]);
    setHistoryLoading(true);
    try {
      const res = await listRedemptions(c.id, { limit: '100' });
      setHistoryRows(res.data ?? []);
    } catch (err) {
      toast.error((err as Error).message || 'Failed to load history');
    } finally {
      setHistoryLoading(false);
    }
  }

  function copyShareText(c: Coupon) {
    const text = c.type === 'percent'
      ? `Use code ${c.code} for ${c.value}% off your order!`
      : c.type === 'fixed'
      ? `Use code ${c.code} for $${c.value.toFixed(2)} off!`
      : `Use code ${c.code} for a special BOGO offer!`;
    navigator.clipboard.writeText(text).then(
      () => toast.success('Copied share text'),
      () => toast.error('Copy failed'),
    );
  }

  if (forbidden) {
    return <PermissionDenied sectionName="the Coupons section" />;
  }

  return (
    <div className="p-6 max-w-6xl mx-auto space-y-4">
      {/* Toolbar */}
      <div className="flex flex-wrap items-center gap-2 justify-between">
        <div className="flex items-center gap-2 flex-wrap">
          {branches.length > 1 && (
            <select
              className="border border-slate-300 rounded-lg px-3 py-2 text-sm"
              value={activeBranchId}
              onChange={(e) => setActiveBranchId(e.target.value)}
            >
              {branches.map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
            </select>
          )}
          <div className="relative">
            <Search size={14} className="absolute left-2.5 top-1/2 -translate-y-1/2 text-slate-400" />
            <input
              type="text"
              placeholder="Search code or name…"
              className="pl-8 pr-3 py-2 border border-slate-300 rounded-lg text-sm w-64"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && reload()}
            />
          </div>
          <select
            className="border border-slate-300 rounded-lg px-3 py-2 text-sm"
            value={statusFilter}
            onChange={(e) => setStatusFilter(e.target.value as StatusFilter)}
          >
            <option value="active">Active</option>
            <option value="archived">Archived</option>
            <option value="all">All</option>
          </select>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={() => setImportOpen(true)}
            className="inline-flex items-center gap-1.5 px-3 py-2 text-sm font-semibold rounded-lg border border-slate-300 hover:bg-slate-50"
          >
            <Upload size={14} /> Import CSV
          </button>
          <button
            onClick={openNew}
            className="inline-flex items-center gap-1.5 px-3 py-2 text-sm font-semibold rounded-lg bg-orange-600 text-white hover:bg-orange-700"
          >
            <Plus size={14} /> New Coupon
          </button>
        </div>
      </div>

      {/* Analytics */}
      <CouponAnalyticsSection
        analytics={analytics}
        loading={analyticsLoading}
        from={analyticsFrom}
        to={analyticsTo}
        onChangeFrom={setAnalyticsFrom}
        onChangeTo={setAnalyticsTo}
        onRefresh={loadAnalytics}
      />

      {/* Table */}
      <div className="bg-white border border-slate-200 rounded-xl overflow-hidden">
        {loading ? (
          <InlineTableSkeleton columns={6} />
        ) : filtered.length === 0 ? (
          <div className="p-10 text-center text-slate-500 text-sm">
            <Ticket size={28} className="mx-auto text-slate-300 mb-2" />
            No coupons {statusFilter === 'archived' ? 'archived' : 'yet'}.
            {statusFilter !== 'archived' && (
              <button onClick={openNew} className="block mx-auto mt-3 text-orange-600 font-semibold">
                Create your first coupon
              </button>
            )}
          </div>
        ) : (
          <table className="w-full text-sm">
            <thead className="bg-slate-50 text-slate-600 text-xs uppercase tracking-wide">
              <tr>
                <th className="text-left px-4 py-3">Code</th>
                <th className="text-left px-4 py-3">Type</th>
                <th className="text-left px-4 py-3">Value</th>
                <th className="text-left px-4 py-3">Valid</th>
                <th className="text-left px-4 py-3">Used</th>
                <th className="text-left px-4 py-3">Status</th>
                <th className="text-right px-4 py-3">Actions</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-slate-100">
              {filtered.map(c => (
                <tr key={c.id} className="hover:bg-slate-50/60">
                  <td className="px-4 py-3">
                    <div className="font-mono font-bold text-slate-900">{c.code}</div>
                    {c.display_name && <div className="text-xs text-slate-500">{c.display_name}</div>}
                  </td>
                  <td className="px-4 py-3 capitalize">{c.type}</td>
                  <td className="px-4 py-3">
                    {c.type === 'percent' ? `${c.value}%` : c.type === 'fixed' ? `$${Number(c.value).toFixed(2)}` : 'BOGO'}
                  </td>
                  <td className="px-4 py-3 text-xs text-slate-600">
                    {c.valid_from ? new Date(c.valid_from).toLocaleDateString() : 'Anytime'}
                    {c.valid_until ? ` → ${new Date(c.valid_until).toLocaleDateString()}` : ''}
                  </td>
                  <td className="px-4 py-3">
                    <span className="text-slate-700">{c.redemption_count ?? 0}</span>
                    {c.total_redemption_cap != null && <span className="text-slate-400"> / {c.total_redemption_cap}</span>}
                  </td>
                  <td className="px-4 py-3">
                    <span className={`px-2 py-0.5 rounded-full text-[11px] font-semibold ${
                      c.status === 'active' ? 'bg-emerald-100 text-emerald-700' : 'bg-slate-100 text-slate-600'
                    }`}>
                      {c.status}
                    </span>
                  </td>
                  <td className="px-4 py-3">
                    <div className="flex items-center gap-1 justify-end">
                      <IconBtn label="Share text" onClick={() => copyShareText(c)}><Share2 size={14} /></IconBtn>
                      <IconBtn label="Redemptions" onClick={() => openHistory(c)}><History size={14} /></IconBtn>
                      <IconBtn label="Duplicate" onClick={() => handleDuplicate(c)}><Copy size={14} /></IconBtn>
                      <IconBtn label="Edit" onClick={() => openEdit(c)}><Pencil size={14} /></IconBtn>
                      <IconBtn label={c.status === 'archived' ? 'Reactivate' : 'Archive'} onClick={() => handleArchiveToggle(c)}>
                        {c.status === 'archived' ? <ArchiveRestore size={14} /> : <Archive size={14} />}
                      </IconBtn>
                      <IconBtn label="Delete" onClick={() => setConfirmDelete(c)}><Trash2 size={14} className="text-red-600" /></IconBtn>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      {showForm && (
        <CouponFormModal
          form={form}
          setForm={setForm}
          onClose={() => setShowForm(false)}
          onSave={handleSave}
          saving={saving}
          editing={!!editing}
          branches={branches}
          activeBranchName={activeBranch?.name ?? ''}
          menuItems={menuItems}
          menuCategories={menuCategories}
        />
      )}

      {historyOpen && (
        <RedemptionHistoryDrawer
          coupon={historyOpen}
          rows={historyRows}
          loading={historyLoading}
          onClose={() => setHistoryOpen(null)}
        />
      )}

      {importOpen && activeBranchId && (
        <CsvImportModal
          branchId={activeBranchId}
          onClose={() => setImportOpen(false)}
          onDone={() => { setImportOpen(false); reload(); }}
        />
      )}

      <ConfirmModal
        isOpen={!!confirmDelete}
        onClose={() => setConfirmDelete(null)}
        onConfirm={handleDelete}
        title={`Delete "${confirmDelete?.code ?? ''}"?`}
        description="This permanently deletes the coupon. Redemption history is kept for accounting."
        confirmLabel="Delete"
      />
    </div>
  );
}

function IconBtn({ children, label, onClick }: { children: React.ReactNode; label: string; onClick: () => void }) {
  return (
    <button
      title={label}
      onClick={onClick}
      className="p-1.5 rounded hover:bg-slate-100 text-slate-600"
    >
      {children}
    </button>
  );
}

function CouponFormModal({
  form, setForm, onClose, onSave, saving, editing, branches, activeBranchName,
  menuItems, menuCategories,
}: {
  form: FormState;
  setForm: (f: FormState) => void;
  onClose: () => void;
  onSave: () => void;
  saving: boolean;
  editing: boolean;
  branches: Branch[];
  activeBranchName: string;
  menuItems: { id: string; name: string }[];
  menuCategories: { id: string; name: string }[];
}) {
  const toggleArr = (arr: string[], v: string) =>
    arr.includes(v) ? arr.filter(x => x !== v) : [...arr, v];
  const setBogo = (patch: Partial<BogoConfigForm>) =>
    setForm({ ...form, bogo_config: { ...form.bogo_config, ...patch } });

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4" style={{ background: 'rgba(0,0,0,0.45)' }} onClick={onClose}>
      <div className="bg-white rounded-xl shadow-xl w-full max-w-2xl max-h-[90vh] overflow-y-auto" onClick={e => e.stopPropagation()}>
        <div className="flex items-center justify-between p-4 border-b border-slate-200">
          <h2 className="font-semibold text-slate-900">{editing ? 'Edit Coupon' : 'New Coupon'}</h2>
          <button onClick={onClose} className="p-1 hover:bg-slate-100 rounded"><X size={16} /></button>
        </div>
        <div className="p-5 space-y-4">
          <div className="grid grid-cols-2 gap-3">
            <div>
              <label className="block text-xs font-semibold text-slate-700 mb-1">Code *</label>
              <input
                type="text"
                value={form.code}
                onChange={(e) => setForm({ ...form, code: e.target.value.toUpperCase().replace(/[^A-Z0-9_-]/g, '') })}
                className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm font-mono"
                placeholder="WELCOME10"
              />
            </div>
            <div>
              <label className="block text-xs font-semibold text-slate-700 mb-1">Branch</label>
              <select
                className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm"
                value={form.branch_id}
                onChange={(e) => setForm({ ...form, branch_id: e.target.value })}
                disabled={editing}
              >
                {branches.length === 0 && <option value="">{activeBranchName}</option>}
                {branches.map(b => <option key={b.id} value={b.id}>{b.name}</option>)}
              </select>
            </div>
          </div>

          <div>
            <label className="block text-xs font-semibold text-slate-700 mb-1">Display name</label>
            <input
              type="text"
              value={form.display_name}
              onChange={(e) => setForm({ ...form, display_name: e.target.value })}
              className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm"
              placeholder="Welcome offer"
            />
          </div>

          <div>
            <label className="block text-xs font-semibold text-slate-700 mb-1">Description</label>
            <textarea
              value={form.description}
              onChange={(e) => setForm({ ...form, description: e.target.value })}
              className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm"
              rows={2}
              placeholder="Internal note shown only in dashboard"
            />
          </div>

          <div className="grid grid-cols-3 gap-3">
            <div>
              <label className="block text-xs font-semibold text-slate-700 mb-1">Type *</label>
              <select
                className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm"
                value={form.type}
                onChange={(e) => setForm({ ...form, type: e.target.value as FormState['type'] })}
              >
                <option value="percent">Percent off</option>
                <option value="fixed">Fixed amount</option>
                <option value="bogo">Buy one, get one</option>
              </select>
            </div>
            <div>
              <label className="block text-xs font-semibold text-slate-700 mb-1">
                {form.type === 'percent' ? 'Percent (1-100)' : form.type === 'fixed' ? 'Amount' : 'Value (unused for BOGO)'}
              </label>
              <input
                type="number"
                value={form.value}
                onChange={(e) => setForm({ ...form, value: e.target.value })}
                className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm"
                step="0.01"
                disabled={form.type === 'bogo'}
              />
            </div>
            <div>
              <label className="block text-xs font-semibold text-slate-700 mb-1">Min order value</label>
              <input
                type="number"
                value={form.min_order_value}
                onChange={(e) => setForm({ ...form, min_order_value: e.target.value })}
                className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm"
                step="0.01"
              />
            </div>
          </div>

          {form.type === 'bogo' && (
            <div className="rounded-lg border border-slate-200 bg-slate-50 p-3 space-y-3">
              <div className="text-xs font-semibold text-slate-700">BOGO configuration</div>
              <div className="grid grid-cols-2 gap-3">
                <div>
                  <label className="block text-xs font-medium text-slate-600 mb-1">Buy target</label>
                  <select
                    className="w-full border border-slate-300 rounded-lg px-2 py-1.5 text-sm bg-white"
                    value={form.bogo_config.buy_target_type}
                    onChange={(e) => setBogo({ buy_target_type: e.target.value as BogoConfigForm['buy_target_type'], buy_target_id: '' })}
                  >
                    <option value="">Any item</option>
                    <option value="item">Specific item</option>
                    <option value="category">Specific category</option>
                  </select>
                </div>
                <div>
                  <label className="block text-xs font-medium text-slate-600 mb-1">Buy {form.bogo_config.buy_target_type || 'target'}</label>
                  <select
                    className="w-full border border-slate-300 rounded-lg px-2 py-1.5 text-sm bg-white disabled:bg-slate-100"
                    value={form.bogo_config.buy_target_id}
                    onChange={(e) => setBogo({ buy_target_id: e.target.value })}
                    disabled={!form.bogo_config.buy_target_type}
                  >
                    <option value="">Select…</option>
                    {form.bogo_config.buy_target_type === 'item' && menuItems.map(i => (
                      <option key={i.id} value={i.id}>{i.name}</option>
                    ))}
                    {form.bogo_config.buy_target_type === 'category' && menuCategories.map(c => (
                      <option key={c.id} value={c.id}>{c.name}</option>
                    ))}
                  </select>
                </div>
              </div>
              <div className="grid grid-cols-2 gap-3">
                <div>
                  <label className="block text-xs font-medium text-slate-600 mb-1">Get target</label>
                  <select
                    className="w-full border border-slate-300 rounded-lg px-2 py-1.5 text-sm bg-white"
                    value={form.bogo_config.get_target_type}
                    onChange={(e) => setBogo({ get_target_type: e.target.value as BogoConfigForm['get_target_type'], get_target_id: '' })}
                  >
                    <option value="">Any item</option>
                    <option value="item">Specific item</option>
                    <option value="category">Specific category</option>
                  </select>
                </div>
                <div>
                  <label className="block text-xs font-medium text-slate-600 mb-1">Get {form.bogo_config.get_target_type || 'target'}</label>
                  <select
                    className="w-full border border-slate-300 rounded-lg px-2 py-1.5 text-sm bg-white disabled:bg-slate-100"
                    value={form.bogo_config.get_target_id}
                    onChange={(e) => setBogo({ get_target_id: e.target.value })}
                    disabled={!form.bogo_config.get_target_type}
                  >
                    <option value="">Select…</option>
                    {form.bogo_config.get_target_type === 'item' && menuItems.map(i => (
                      <option key={i.id} value={i.id}>{i.name}</option>
                    ))}
                    {form.bogo_config.get_target_type === 'category' && menuCategories.map(c => (
                      <option key={c.id} value={c.id}>{c.name}</option>
                    ))}
                  </select>
                </div>
              </div>
              <div className="grid grid-cols-2 gap-3">
                <div>
                  <label className="block text-xs font-medium text-slate-600 mb-1">Discount</label>
                  <select
                    className="w-full border border-slate-300 rounded-lg px-2 py-1.5 text-sm bg-white"
                    value={form.bogo_config.get_discount_kind}
                    onChange={(e) => setBogo({ get_discount_kind: e.target.value as BogoConfigForm['get_discount_kind'] })}
                  >
                    <option value="free">Free</option>
                    <option value="percent">% off</option>
                  </select>
                </div>
                {form.bogo_config.get_discount_kind === 'percent' && (
                  <div>
                    <label className="block text-xs font-medium text-slate-600 mb-1">Percent off the second item</label>
                    <input
                      type="number"
                      min={0}
                      max={100}
                      step="1"
                      value={form.bogo_config.get_discount_percent}
                      onChange={(e) => setBogo({ get_discount_percent: e.target.value })}
                      className="w-full border border-slate-300 rounded-lg px-2 py-1.5 text-sm bg-white"
                    />
                  </div>
                )}
              </div>
            </div>
          )}

          <div className="grid grid-cols-2 gap-3">
            <div>
              <label className="block text-xs font-semibold text-slate-700 mb-1">Valid from</label>
              <input
                type="datetime-local"
                value={form.valid_from}
                onChange={(e) => setForm({ ...form, valid_from: e.target.value })}
                className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm"
              />
            </div>
            <div>
              <label className="block text-xs font-semibold text-slate-700 mb-1">Valid until</label>
              <input
                type="datetime-local"
                value={form.valid_until}
                onChange={(e) => setForm({ ...form, valid_until: e.target.value })}
                className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm"
              />
            </div>
          </div>

          <div className="grid grid-cols-2 gap-3">
            <div>
              <label className="block text-xs font-semibold text-slate-700 mb-1">Total redemption cap</label>
              <input
                type="number"
                value={form.total_redemption_cap}
                onChange={(e) => setForm({ ...form, total_redemption_cap: e.target.value })}
                className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm"
                placeholder="Unlimited"
              />
            </div>
            <div>
              <label className="block text-xs font-semibold text-slate-700 mb-1">Per-customer cap</label>
              <input
                type="number"
                value={form.per_customer_cap}
                onChange={(e) => setForm({ ...form, per_customer_cap: e.target.value })}
                className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm"
                placeholder="Unlimited"
              />
            </div>
          </div>

          <div>
            <label className="block text-xs font-semibold text-slate-700 mb-1">Order types</label>
            <div className="flex flex-wrap gap-2">
              {ORDER_TYPES.map(o => (
                <label key={o} className={`px-3 py-1.5 rounded-full text-xs font-semibold border cursor-pointer ${
                  form.applicable_order_types.includes(o)
                    ? 'bg-orange-50 border-orange-300 text-orange-700'
                    : 'border-slate-300 text-slate-500'
                }`}>
                  <input
                    type="checkbox"
                    className="sr-only"
                    checked={form.applicable_order_types.includes(o)}
                    onChange={() => setForm({ ...form, applicable_order_types: toggleArr(form.applicable_order_types, o) })}
                  />
                  {o}
                </label>
              ))}
            </div>
          </div>

          <div>
            <label className="block text-xs font-semibold text-slate-700 mb-1">Channels</label>
            <div className="flex flex-wrap gap-2">
              {CHANNELS.map(o => (
                <label key={o} className={`px-3 py-1.5 rounded-full text-xs font-semibold border cursor-pointer ${
                  form.applicable_channels.includes(o)
                    ? 'bg-orange-50 border-orange-300 text-orange-700'
                    : 'border-slate-300 text-slate-500'
                }`}>
                  <input
                    type="checkbox"
                    className="sr-only"
                    checked={form.applicable_channels.includes(o)}
                    onChange={() => setForm({ ...form, applicable_channels: toggleArr(form.applicable_channels, o) })}
                  />
                  {o}
                </label>
              ))}
            </div>
          </div>

          {branches.length > 1 && (
            <div>
              <label className="block text-xs font-semibold text-slate-700 mb-1">
                Other branches that may also accept this code
              </label>
              <div className="flex flex-wrap gap-2">
                {branches.filter(b => b.id !== form.branch_id).map(b => (
                  <label key={b.id} className={`px-3 py-1.5 rounded-full text-xs font-semibold border cursor-pointer ${
                    form.applicable_branches.includes(b.id)
                      ? 'bg-orange-50 border-orange-300 text-orange-700'
                      : 'border-slate-300 text-slate-500'
                  }`}>
                    <input
                      type="checkbox"
                      className="sr-only"
                      checked={form.applicable_branches.includes(b.id)}
                      onChange={() => setForm({ ...form, applicable_branches: toggleArr(form.applicable_branches, b.id) })}
                    />
                    {b.name}
                  </label>
                ))}
              </div>
              <p className="text-xs text-slate-500 mt-1">The owning branch is always included.</p>
            </div>
          )}

          <div>
            <label className="block text-xs font-semibold text-slate-700 mb-1">Stacking</label>
            <div className="flex flex-col gap-2 text-sm text-slate-700">
              <label className="inline-flex items-center gap-2">
                <input
                  type="checkbox"
                  checked={form.stack_with_loyalty}
                  onChange={(e) => setForm({ ...form, stack_with_loyalty: e.target.checked })}
                />
                Allow combining with loyalty points
              </label>
              <label className="inline-flex items-center gap-2">
                <input
                  type="checkbox"
                  checked={form.stack_with_gift_card}
                  onChange={(e) => setForm({ ...form, stack_with_gift_card: e.target.checked })}
                />
                Allow combining with gift cards
              </label>
            </div>
          </div>

          <div>
            <label className="block text-xs font-semibold text-slate-700 mb-1">Status</label>
            <select
              className="w-full border border-slate-300 rounded-lg px-3 py-2 text-sm"
              value={form.status}
              onChange={(e) => setForm({ ...form, status: e.target.value as 'active' | 'archived' })}
            >
              <option value="active">Active</option>
              <option value="archived">Archived</option>
            </select>
          </div>
        </div>
        <div className="border-t border-slate-200 p-4 flex justify-end gap-2 sticky bottom-0 bg-white">
          <button onClick={onClose} className="px-4 py-2 rounded-lg text-sm font-semibold text-slate-700 hover:bg-slate-100">Cancel</button>
          <button
            onClick={onSave}
            disabled={saving}
            className="px-4 py-2 rounded-lg text-sm font-semibold bg-orange-600 text-white hover:bg-orange-700 disabled:opacity-50"
          >
            {saving ? 'Saving…' : editing ? 'Save changes' : 'Create coupon'}
          </button>
        </div>
      </div>
    </div>
  );
}

function RedemptionHistoryDrawer({ coupon, rows, loading, onClose }: {
  coupon: Coupon; rows: CouponRedemption[]; loading: boolean; onClose: () => void;
}) {
  return (
    <div className="fixed inset-0 z-50 flex justify-end" style={{ background: 'rgba(0,0,0,0.4)' }} onClick={onClose}>
      <div className="w-full max-w-md h-full bg-white shadow-xl overflow-y-auto" onClick={e => e.stopPropagation()}>
        <div className="flex items-center justify-between p-4 border-b">
          <div>
            <p className="text-xs text-slate-500">Redemptions</p>
            <h2 className="font-bold text-slate-900 font-mono">{coupon.code}</h2>
          </div>
          <div className="flex items-center gap-1">
            <a
              href={redemptionsCsvUrl(coupon.id)}
              download={`coupon-${coupon.code}-redemptions.csv`}
              className="inline-flex items-center gap-1 px-2.5 py-1.5 rounded text-xs font-semibold border border-slate-300 text-slate-700 hover:bg-slate-50"
              title="Download CSV"
            >
              <Download size={12} /> CSV
            </a>
            <button onClick={onClose} className="p-1 hover:bg-slate-100 rounded"><X size={16} /></button>
          </div>
        </div>
        <div className="p-4 space-y-2">
          {loading ? (
            <p className="text-sm text-slate-500">Loading…</p>
          ) : rows.length === 0 ? (
            <p className="text-sm text-slate-500 text-center py-8">No redemptions yet.</p>
          ) : rows.map(r => (
            <div key={r.id} className="flex items-center justify-between border border-slate-200 rounded-lg px-3 py-2">
              <div>
                <p className="text-sm font-semibold text-slate-900">
                  {r.order_number ? `#${r.order_number}` : 'Order'}
                  <span className="ml-2 text-xs uppercase text-slate-500">{r.channel}</span>
                </p>
                <p className="text-xs text-slate-500">
                  {r.customer_name ?? 'Guest'} · {new Date(r.created_at).toLocaleString()}
                </p>
              </div>
              <p className="text-sm font-bold text-emerald-600">−${Number(r.discount_amount).toFixed(2)}</p>
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

function CsvImportModal({ branchId, onClose, onDone }: { branchId: string; onClose: () => void; onDone: () => void }) {
  const [file, setFile] = useState<File | null>(null);
  const [busy, setBusy] = useState(false);
  const [result, setResult] = useState<{ created: number; failed: { code: string; error: string }[] } | null>(null);

  function parseCSV(text: string): Record<string, string>[] {
    const lines = text.split(/\r?\n/).filter(l => l.trim().length > 0);
    if (lines.length === 0) return [];
    const headers = lines[0].split(',').map(h => h.trim());
    return lines.slice(1).map(line => {
      const cells = line.split(',').map(c => c.trim());
      const row: Record<string, string> = {};
      headers.forEach((h, i) => { row[h] = cells[i] ?? ''; });
      return row;
    });
  }

  async function handleImport() {
    if (!file) return;
    setBusy(true);
    try {
      const text = await file.text();
      const csvRows = parseCSV(text);
      const rows = csvRows.map(r => ({
        code: r.code,
        display_name: r.display_name || undefined,
        type: (r.type || 'percent') as 'percent' | 'fixed' | 'bogo',
        value: Number(r.value || 0),
        min_order_value: Number(r.min_order_value || 0),
        applicable_order_types: r.applicable_order_types
          ? r.applicable_order_types.split('|').map(s => s.trim()).filter(Boolean)
          : ['dine-in', 'takeaway', 'delivery'],
        applicable_channels: r.applicable_channels
          ? r.applicable_channels.split('|').map(s => s.trim()).filter(Boolean)
          : ['chat', 'whatsapp', 'storefront'],
        applicable_branches: [branchId],
        valid_from: r.valid_from || null,
        valid_until: r.valid_until || null,
        total_redemption_cap: r.total_redemption_cap ? Number(r.total_redemption_cap) : null,
        per_customer_cap: r.per_customer_cap ? Number(r.per_customer_cap) : null,
        status: 'active' as const,
      }));
      const res = await bulkImportCoupons({ branch_id: branchId, rows });
      setResult(res);
      if (res.failed.length === 0) {
        toast.success(`Imported ${res.created} coupons`);
        onDone();
      } else {
        toast.error(`${res.created} imported, ${res.failed.length} failed`);
      }
    } catch (err) {
      toast.error((err as Error).message || 'Import failed');
    } finally {
      setBusy(false);
    }
  }

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4" style={{ background: 'rgba(0,0,0,0.45)' }} onClick={onClose}>
      <div className="bg-white rounded-xl shadow-xl w-full max-w-lg" onClick={e => e.stopPropagation()}>
        <div className="flex items-center justify-between p-4 border-b">
          <h2 className="font-semibold text-slate-900">Import Coupons (CSV)</h2>
          <button onClick={onClose} className="p-1 hover:bg-slate-100 rounded"><X size={16} /></button>
        </div>
        <div className="p-5 space-y-3">
          <p className="text-sm text-slate-600">
            CSV columns: <code className="text-xs bg-slate-100 px-1 rounded">code, display_name, type, value, min_order_value, valid_from, valid_until, total_redemption_cap, per_customer_cap, applicable_order_types, applicable_channels</code>
          </p>
          <p className="text-xs text-slate-500">
            For multi-value columns, separate values with the <code>|</code> character (e.g. <code>dine-in|takeaway</code>).
          </p>
          <input
            type="file"
            accept=".csv,text/csv"
            onChange={(e) => setFile(e.target.files?.[0] ?? null)}
            className="block w-full text-sm"
          />
          {result && result.failed.length > 0 && (
            <div className="bg-red-50 border border-red-200 rounded p-3 text-xs text-red-700 max-h-32 overflow-y-auto">
              <p className="font-semibold mb-1">Failed rows:</p>
              {result.failed.map((f, i) => <p key={i}>{f.code || '(no code)'}: {f.error}</p>)}
            </div>
          )}
        </div>
        <div className="border-t p-4 flex justify-end gap-2">
          <button onClick={onClose} className="px-4 py-2 rounded-lg text-sm font-semibold text-slate-700 hover:bg-slate-100">Close</button>
          <button
            onClick={handleImport}
            disabled={!file || busy}
            className="px-4 py-2 rounded-lg text-sm font-semibold bg-orange-600 text-white hover:bg-orange-700 disabled:opacity-50"
          >
            {busy ? 'Importing…' : 'Import'}
          </button>
        </div>
      </div>
    </div>
  );
}

function CouponAnalyticsSection({
  analytics, loading, from, to, onChangeFrom, onChangeTo, onRefresh,
}: {
  analytics: CouponAnalytics | null;
  loading: boolean;
  from: string;
  to: string;
  onChangeFrom: (v: string) => void;
  onChangeTo: (v: string) => void;
  onRefresh: () => void;
}) {
  const totals = analytics?.totals;
  const perDay = analytics?.per_day ?? [];
  const top = analytics?.top_coupons ?? [];
  const perChannel = analytics?.per_channel ?? [];
  const reconcileDelta = totals
    ? Math.abs(totals.discount_value - totals.orders_discount_total)
    : 0;
  const voiceMentions = totals?.voice_mentions ?? 0;
  const voiceChannel = perChannel.find(c => c.channel === 'voice');
  const voiceConversion = voiceChannel && voiceChannel.mentions > 0
    ? Math.round((voiceChannel.redemptions / voiceChannel.mentions) * 100)
    : null;

  return (
    <div className="bg-white border border-slate-200 rounded-xl p-4 space-y-4">
      <div className="flex flex-wrap items-center justify-between gap-2">
        <div className="flex items-center gap-2">
          <BarChart3 size={16} className="text-orange-600" />
          <h2 className="font-semibold text-slate-900 text-sm">Coupon Performance</h2>
        </div>
        <div className="flex items-center gap-2 flex-wrap">
          <label className="text-xs text-slate-500">From</label>
          <input
            type="date"
            value={from}
            onChange={(e) => onChangeFrom(e.target.value)}
            className="border border-slate-300 rounded-lg px-2 py-1 text-xs"
          />
          <label className="text-xs text-slate-500">To</label>
          <input
            type="date"
            value={to}
            onChange={(e) => onChangeTo(e.target.value)}
            className="border border-slate-300 rounded-lg px-2 py-1 text-xs"
          />
          <button
            onClick={onRefresh}
            className="px-2.5 py-1 rounded-lg text-xs font-semibold border border-slate-300 hover:bg-slate-50"
          >
            Refresh
          </button>
        </div>
      </div>

      <div className="grid grid-cols-2 md:grid-cols-4 gap-3">
        <StatCard
          label="Total redemptions"
          value={loading ? '…' : String(totals?.redemptions ?? 0)}
        />
        <StatCard
          label="Discount issued"
          value={loading ? '…' : `$${(totals?.discount_value ?? 0).toFixed(2)}`}
          hint={
            totals && !totals.reconciled
              ? `Orders show $${totals.orders_discount_total.toFixed(2)} (Δ $${reconcileDelta.toFixed(2)})`
              : totals
              ? 'Reconciles with orders'
              : undefined
          }
          hintTone={totals && !totals.reconciled ? 'warn' : 'ok'}
        />
        <StatCard
          label="Voice mentions"
          value={loading ? '…' : String(voiceMentions)}
          hint={voiceConversion != null ? `${voiceConversion}% redeemed` : undefined}
        />
        <StatCard
          label="Days in range"
          value={loading ? '…' : String(perDay.length)}
        />
      </div>

      {!loading && perChannel.length > 0 && (
        <div className="border border-slate-200 rounded-lg p-3">
          <p className="text-xs font-semibold text-slate-600 mb-2">By channel</p>
          <table className="w-full text-sm">
            <thead className="text-[11px] uppercase tracking-wide text-slate-500">
              <tr>
                <th className="text-left font-semibold py-1">Channel</th>
                <th className="text-right font-semibold py-1">Mentions</th>
                <th className="text-right font-semibold py-1">Redemptions</th>
                <th className="text-right font-semibold py-1">Discount</th>
                <th className="text-right font-semibold py-1">Conv.</th>
              </tr>
            </thead>
            <tbody className="divide-y divide-slate-100">
              {perChannel.map(c => {
                const conv = c.mentions > 0 ? `${Math.round((c.redemptions / c.mentions) * 100)}%` : '—';
                return (
                  <tr key={c.channel}>
                    <td className="py-1.5 capitalize text-slate-800">{c.channel}</td>
                    <td className="py-1.5 text-right text-slate-700">{c.mentions || (c.channel === 'voice' ? 0 : '—')}</td>
                    <td className="py-1.5 text-right text-slate-900 font-semibold">{c.redemptions}</td>
                    <td className="py-1.5 text-right text-emerald-600">−${c.discount.toFixed(2)}</td>
                    <td className="py-1.5 text-right text-slate-600">{c.channel === 'voice' ? conv : '—'}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
          <p className="text-[11px] text-slate-400 mt-2">
            Mentions are tracked when the voice agent surfaces an offer during a call. Conversion = voice redemptions ÷ voice mentions.
          </p>
        </div>
      )}

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
        <div className="lg:col-span-2 border border-slate-200 rounded-lg p-3">
          <p className="text-xs font-semibold text-slate-600 mb-2">Redemptions per day</p>
          {loading ? (
            <div className="h-48 flex items-center justify-center text-xs text-slate-400">Loading…</div>
          ) : perDay.length === 0 ? (
            <div className="h-48 flex items-center justify-center text-xs text-slate-400">
              No redemptions in this range.
            </div>
          ) : (
            <SafeChart height={200}>
              <BarChart data={perDay}>
                <CartesianGrid strokeDasharray="3 3" stroke="#f1f5f9" />
                <XAxis dataKey="date" tick={{ fontSize: 10 }} />
                <YAxis allowDecimals={false} tick={{ fontSize: 10 }} />
                <Tooltip
                  formatter={(val: number, name: string) =>
                    name === 'discount' ? [`$${Number(val).toFixed(2)}`, 'Discount'] : [val, 'Redemptions']
                  }
                />
                <Bar dataKey="redemptions" fill="#ea580c" radius={[3, 3, 0, 0]} />
              </BarChart>
            </SafeChart>
          )}
        </div>
        <div className="border border-slate-200 rounded-lg p-3">
          <p className="text-xs font-semibold text-slate-600 mb-2">Top 5 coupons</p>
          {loading ? (
            <p className="text-xs text-slate-400">Loading…</p>
          ) : top.length === 0 ? (
            <p className="text-xs text-slate-400">No data yet.</p>
          ) : (
            <ul className="space-y-2">
              {top.map((t) => (
                <li key={t.coupon_id} className="flex items-center justify-between text-sm">
                  <div className="min-w-0">
                    <p className="font-mono font-bold text-slate-900 truncate">{t.code}</p>
                    {t.display_name && (
                      <p className="text-[11px] text-slate-500 truncate">{t.display_name}</p>
                    )}
                  </div>
                  <div className="text-right">
                    <p className="text-xs font-semibold text-slate-900">{t.redemptions}×</p>
                    <p className="text-[11px] text-emerald-600">−${t.discount.toFixed(2)}</p>
                    {(t.voice_mentions ?? 0) > 0 && (
                      <p className="text-[11px] text-slate-500">{t.voice_mentions} voice mention{t.voice_mentions === 1 ? '' : 's'}</p>
                    )}
                  </div>
                </li>
              ))}
            </ul>
          )}
        </div>
      </div>
    </div>
  );
}

function StatCard({
  label, value, hint, hintTone,
}: { label: string; value: string; hint?: string; hintTone?: 'ok' | 'warn' }) {
  return (
    <div className="border border-slate-200 rounded-lg p-3">
      <p className="text-[11px] uppercase tracking-wide text-slate-500 font-semibold">{label}</p>
      <p className="text-xl font-bold text-slate-900 mt-1">{value}</p>
      {hint && (
        <p className={`text-[11px] mt-1 ${hintTone === 'warn' ? 'text-amber-600' : 'text-slate-500'}`}>
          {hint}
        </p>
      )}
    </div>
  );
}
