import React, { useState, useEffect, useMemo, useCallback } from "react";
import { Boxes, Plus, X, Trash2, Users, ChevronDown, ChevronRight, Archive, History, Pencil, Check, Loader2, AlertCircle, FileBarChart, Wallet, TrendingUp, Printer } from "lucide-react";

const COLORS = {
  teal900: "#22284A",
  teal700: "#343B6B",
  aqua500: "#5B6EF5",
  aqua300: "#B4BEFA",
  gold500: "#E8734D",
  ink: "#1A1A2E",
  paper: "#F7F7FB",
  paperDeep: "#ECECF5",
  line: "#DCDCE8",
  muted: "#5C5C72",
  danger: "#B3432B",
};

const DEFAULT_RATE = 220;
const PAYMENT_METHODS = ["Cash", "Credit", "Easypaisa/JazzCash", "Bank Transfer"];
const EXPENSE_CATEGORIES = ["Petrol", "Food", "Vehicle Maintenance", "Other"];

const AREAS = [
  "E-7, Islamabad", "E-8, Islamabad", "E-9, Islamabad", "E-11, Islamabad",
  "F-6, Islamabad", "F-7, Islamabad", "F-8, Islamabad", "F-10, Islamabad", "F-11, Islamabad",
  "G-6, Islamabad", "G-7, Islamabad", "G-8, Islamabad", "G-9, Islamabad", "G-10, Islamabad", "G-11, Islamabad", "G-13, Islamabad",
  "H-8, Islamabad", "H-9, Islamabad", "H-11, Islamabad", "H-13, Islamabad",
  "I-8, Islamabad", "I-9, Islamabad", "I-10, Islamabad",
  "Blue Area, Islamabad",
  "Bahria Town, Rawalpindi", "Bahria Enclave, Islamabad",
  "DHA Phase 1, Islamabad", "DHA Phase 2, Islamabad",
  "Bani Gala, Islamabad", "Bhara Kahu, Islamabad", "Tarlai, Islamabad", "Margalla Enclave, Islamabad",
  "Soan Garden, Islamabad", "PWD Housing Society, Islamabad", "Gulberg Greens, Islamabad",
  "Chak Shahzad, Islamabad", "Tarnol, Islamabad", "Golra Sharif, Islamabad",
  "Shahzad Town, Islamabad", "Korang Town, Islamabad", "Airport Road, Islamabad",
  "Abpara, Islamabad", "Ahmed Town, Islamabad", "Abdullah Town, Islamabad", "Nain Sukh, Islamabad",
  "B.K. Chowk", "Bahria Town", "Bally Town", "Bani Gala", "Chattha", "D.H.A",
  "Green Avenue", "Green Town", "Green Two", "Jabi", "Jalani", "Jasmine", "Kuri", "Mansha Town",
  "Margalla", "Market", "New Mall", "P.H.A", "Shahpur", "Shazad Town", "Taramari",
];

const REST_URL = "https://wzyjngkxfubsyjvsptbd.supabase.co/rest/v1";
const AUTH_URL = "https://wzyjngkxfubsyjvsptbd.supabase.co/auth/v1";
const ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Ind6eWpuZ2t4ZnVic3lqdnNwdGJkIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODY5ODkyODQsImV4cCI6MjEwMjU2NTI4NH0.fbuBafbNfFIgaEodtsTEU4-H756HLS3DhOI-YJv-Mec";

let CURRENT_ACCESS_TOKEN = null;

function getHeaders() {
  return {
    apikey: ANON_KEY,
    Authorization: `Bearer ${CURRENT_ACCESS_TOKEN || ANON_KEY}`,
    "Content-Type": "application/json",
  };
}

async function api(path, options = {}) {
  const res = await fetch(`${REST_URL}${path}`, {
    ...options,
    headers: { ...getHeaders(), ...(options.headers || {}) },
  });
  if (!res.ok) {
    const text = await res.text().catch(() => "");
    throw new Error(`Request failed (${res.status}): ${text}`);
  }
  const text = await res.text();
  return text ? JSON.parse(text) : null;
}

async function signInRequest(email, password) {
  const res = await fetch(`${AUTH_URL}/token?grant_type=password`, {
    method: "POST",
    headers: { apikey: ANON_KEY, "Content-Type": "application/json" },
    body: JSON.stringify({ email, password }),
  });
  const data = await res.json();
  if (!res.ok) {
    throw new Error(data.error_description || data.msg || "Login failed");
  }
  return data; // { access_token, refresh_token, user: { id, email, ... } }
}

function today() {
  return new Date().toISOString().slice(0, 10);
}
function fmtDate(d) {
  const dt = new Date(d + "T00:00:00");
  return dt.toLocaleDateString("en-GB", { day: "2-digit", month: "short", year: "numeric" });
}
function monthLabel(d = new Date()) {
  return d.toLocaleDateString("en-GB", { month: "long", year: "numeric" });
}
function money(n) {
  return "PKR " + Math.round(n).toLocaleString();
}

function printHtml(title, bodyHtml) {
  const w = window.open("", "_blank");
  if (!w) {
    alert("Please allow pop-ups for this site to print.");
    return;
  }
  const printedOn = new Date().toLocaleString("en-GB", { day: "2-digit", month: "short", year: "numeric", hour: "2-digit", minute: "2-digit" });
  w.document.write(`<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>${title}</title>
<style>
  body { font-family: 'Manrope', Arial, sans-serif; color: #16241F; padding: 24px; max-width: 640px; margin: 0 auto; }
  .brand-header { display: flex; align-items: center; gap: 10px; padding-bottom: 14px; margin-bottom: 18px; border-bottom: 2px solid #22284A; }
  .brand-mark { width: 34px; height: 34px; border-radius: 50%; background: #22284A; display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; }
  .brand-name { font-family: Georgia, serif; font-weight: 700; font-size: 18px; color: #22284A; line-height: 1.1; }
  .brand-sub { font-size: 11px; color: #5A655F; line-height: 1.2; }
  h1 { font-size: 20px; margin: 0 0 4px; }
  .muted { color: #5A655F; font-size: 12px; margin-bottom: 16px; }
  table { width: 100%; border-collapse: collapse; margin-top: 12px; }
  th, td { text-align: left; padding: 7px 8px; border-bottom: 1px solid #D8DED9; font-size: 13px; }
  th { color: #343B6B; text-transform: uppercase; font-size: 10px; letter-spacing: 0.04em; }
  .stat-row { display: flex; gap: 16px; margin: 14px 0; flex-wrap: wrap; }
  .stat { background: #EAEDE9; border-radius: 10px; padding: 10px 14px; min-width: 110px; }
  .stat-label { font-size: 10px; text-transform: uppercase; color: #343B6B; font-weight: 700; }
  .stat-value { font-size: 17px; font-weight: 700; margin-top: 2px; }
  .section-title { font-size: 11px; text-transform: uppercase; color: #343B6B; font-weight: 700; margin-top: 18px; }
  .print-footer { margin-top: 28px; padding-top: 10px; border-top: 1px solid #D8DED9; font-size: 10px; color: #5A655F; }
</style>
</head>
<body>
  <div class="brand-header">
    <div class="brand-mark">📦</div>
    <div>
      <div class="brand-name">ClearFlow</div>
      <div class="brand-sub">Delivery & Cash Ledger System</div>
    </div>
  </div>
  ${bodyHtml}
  <div class="print-footer">Printed on ${printedOn}</div>
</body>
</html>`);
  w.document.close();
  w.focus();
  setTimeout(() => {
    w.print();
  }, 300);
}

export default function BottleLedgerLive() {
  const [customers, setCustomers] = useState([]);
  const [transactions, setTransactions] = useState([]);
  const [expenses, setExpenses] = useState([]);
  const [profiles, setProfiles] = useState([]);
  const [loading, setLoading] = useState(true);
  const [errorMsg, setErrorMsg] = useState("");

  const [authState, setAuthState] = useState(null); // null = logged out, else { userId, email, name, role }
  const [authChecked, setAuthChecked] = useState(false);
  const [loginEmail, setLoginEmail] = useState("");
  const [loginPassword, setLoginPassword] = useState("");
  const [loginError, setLoginError] = useState("");
  const [loginLoading, setLoginLoading] = useState(false);

  const [newName, setNewName] = useState("");
  const [newDeposit, setNewDeposit] = useState("");
  const [newOpeningBottles, setNewOpeningBottles] = useState("");
  const [newDispenserCount, setNewDispenserCount] = useState("");
  const [newArea, setNewArea] = useState(AREAS[0]);
  const [showBulkAdd, setShowBulkAdd] = useState(false);
  const [bulkText, setBulkText] = useState("");
  const [bulkDefaultArea, setBulkDefaultArea] = useState(AREAS[0]);
  const [bulkResult, setBulkResult] = useState("");
  const [areaFilter, setAreaFilter] = useState("all");
  const [customerSearch, setCustomerSearch] = useState("");
  const [expanded, setExpanded] = useState(null);
  const [historyOpenFor, setHistoryOpenFor] = useState(null);

  const [entryDate, setEntryDate] = useState(today());
  const [entryBottles, setEntryBottles] = useState("");
  const [entryBottlesReturned, setEntryBottlesReturned] = useState("");
  const [entryRate, setEntryRate] = useState(String(DEFAULT_RATE));
  const [entryPaid, setEntryPaid] = useState("");
  const [entryPaymentMethod, setEntryPaymentMethod] = useState(PAYMENT_METHODS[0]);

  const [showCloseMonthConfirm, setShowCloseMonthConfirm] = useState(false);
  const [showReportModal, setShowReportModal] = useState(false);
  const [reportData, setReportData] = useState(null);

  const [editingTxId, setEditingTxId] = useState(null);
  const [editDraft, setEditDraft] = useState({ date: "", bottles: "", bottlesReturned: "", rate: "", paid: "", paymentMethod: PAYMENT_METHODS[0] });

  const [savingAction, setSavingAction] = useState(false);
  const [confirmDeleteCustomer, setConfirmDeleteCustomer] = useState(null);
  const [confirmDeleteTx, setConfirmDeleteTx] = useState(null);

  const [showExpenseForm, setShowExpenseForm] = useState(false);
  const [expenseDate, setExpenseDate] = useState(today());
  const [expenseCategory, setExpenseCategory] = useState(EXPENSE_CATEGORIES[0]);
  const [expenseAmount, setExpenseAmount] = useState("");
  const [expenseNote, setExpenseNote] = useState("");
  const [confirmDeleteExpense, setConfirmDeleteExpense] = useState(null);
  const [showTeamModal, setShowTeamModal] = useState(false);
  const [teamDateFrom, setTeamDateFrom] = useState(today());
  const [teamDateTo, setTeamDateTo] = useState(today());
  const [expandedTeamId, setExpandedTeamId] = useState(null);
  const [ownerPeriod, setOwnerPeriod] = useState("current");

  const loadAll = useCallback(async () => {
    setLoading(true);
    setErrorMsg("");
    try {
      const [custData, txData, expData, profData] = await Promise.all([
        api("/customers?select=*&order=serial.asc"),
        api("/transactions?select=*&order=date.asc"),
        api("/expenses?select=*&order=date.desc"),
        api("/profiles?select=*"),
      ]);
      setCustomers(custData || []);
      setTransactions(txData || []);
      setExpenses(expData || []);
      setProfiles(profData || []);
    } catch (err) {
      setErrorMsg("Couldn't load data from the database. Check your connection and try again.");
    } finally {
      setLoading(false);
    }
  }, []);

  async function fetchProfile(userId, accessToken) {
    CURRENT_ACCESS_TOKEN = accessToken;
    const rows = await api(`/profiles?id=eq.${userId}&select=*`);
    CURRENT_ACCESS_TOKEN = accessToken; // keep set; api() reads this each call
    if (!rows || rows.length === 0) throw new Error("No profile found for this account. Ask your admin to add one.");
    if (rows[0].active === false) throw new Error("This account has been blocked. Contact your admin.");
    return rows[0];
  }

  const restoreSession = useCallback(async () => {
    try {
      const saved = localStorage.getItem("clearflow_demo_session");
      if (!saved) return;
      const parsed = JSON.parse(saved);
      const profile = await fetchProfile(parsed.userId, parsed.accessToken);
      setAuthState({ userId: parsed.userId, email: parsed.email, accessToken: parsed.accessToken, name: profile.name, role: profile.role });
    } catch (err) {
      localStorage.removeItem("clearflow_demo_session");
      CURRENT_ACCESS_TOKEN = null;
    } finally {
      setAuthChecked(true);
    }
  }, []);

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

  useEffect(() => {
    if (authState) loadAll();
  }, [authState, loadAll]);

  const handleLogin = async () => {
    if (!loginEmail.trim() || !loginPassword) return;
    setLoginLoading(true);
    setLoginError("");
    try {
      const data = await signInRequest(loginEmail.trim(), loginPassword);
      const profile = await fetchProfile(data.user.id, data.access_token);
      const session = { userId: data.user.id, email: data.user.email, accessToken: data.access_token, name: profile.name, role: profile.role };
      setAuthState(session);
      localStorage.setItem("clearflow_demo_session", JSON.stringify({ userId: data.user.id, email: data.user.email, accessToken: data.access_token }));
    } catch (err) {
      setLoginError(err.message || "Couldn't log in. Check your email and password.");
      CURRENT_ACCESS_TOKEN = null;
    } finally {
      setLoginLoading(false);
    }
  };

  const handleLogout = () => {
    setAuthState(null);
    CURRENT_ACCESS_TOKEN = null;
    localStorage.removeItem("clearflow_demo_session");
    setCustomers([]);
    setTransactions([]);
    setExpenses([]);
    setProfiles([]);
  };

  const role = authState ? authState.role : null;

  const nextSerial = customers.length ? Math.max(...customers.map((c) => c.serial)) + 1 : 1;

  const currentTxByCustomer = useMemo(() => {
    const map = {};
    transactions.filter((t) => !t.closed).forEach((t) => {
      if (!map[t.customer_id]) map[t.customer_id] = [];
      map[t.customer_id].push(t);
    });
    return map;
  }, [transactions]);

  const lifetimeByCustomer = useMemo(() => {
    const map = {};
    transactions.forEach((t) => {
      if (!map[t.customer_id]) map[t.customer_id] = { bottles: 0, paid: 0, returned: 0 };
      map[t.customer_id].bottles += Number(t.bottles);
      map[t.customer_id].paid += Number(t.paid);
      map[t.customer_id].returned += Number(t.bottles_returned || 0);
    });
    return map;
  }, [transactions]);

  const historyByCustomer = useMemo(() => {
    const map = {};
    transactions.filter((t) => t.closed).forEach((t) => {
      if (!map[t.customer_id]) map[t.customer_id] = [];
      map[t.customer_id].push(t);
    });
    const grouped = {};
    Object.keys(map).forEach((cid) => {
      const byPeriod = {};
      map[cid].forEach((t) => {
        const key = `${t.period_label}__${t.closed_on}`;
        if (!byPeriod[key]) byPeriod[key] = { label: t.period_label, closedOn: t.closed_on, transactions: [] };
        byPeriod[key].transactions.push(t);
      });
      grouped[cid] = Object.values(byPeriod).sort((a, b) => (b.closedOn || "").localeCompare(a.closedOn || ""));
    });
    return grouped;
  }, [transactions]);

  function periodTotals(txList) {
    return txList.reduce(
      (acc, t) => ({ bottles: acc.bottles + Number(t.bottles), charged: acc.charged + Number(t.bottles) * Number(t.rate), paid: acc.paid + Number(t.paid), returned: acc.returned + Number(t.bottles_returned || 0) }),
      { bottles: 0, charged: 0, paid: 0, returned: 0 }
    );
  }

  const grandTotals = useMemo(() => {
    return customers.reduce(
      (acc, c) => {
        const t = periodTotals(currentTxByCustomer[c.id] || []);
        const balance = Number(c.carried_balance) + t.charged - t.paid;
        return { bottles: acc.bottles + t.bottles, paid: acc.paid + t.paid, balance: acc.balance + balance };
      },
      { bottles: 0, paid: 0, balance: 0 }
    );
  }, [customers, currentTxByCustomer]);

  const paymentBreakdown = useMemo(() => {
    const map = {};
    PAYMENT_METHODS.forEach((m) => { map[m] = { paid: 0, charged: 0 }; });
    transactions.filter((t) => !t.closed).forEach((t) => {
      const method = t.payment_method || "Cash";
      if (!map[method]) map[method] = { paid: 0, charged: 0 };
      map[method].paid += Number(t.paid);
      map[method].charged += Number(t.bottles) * Number(t.rate);
    });
    return map;
  }, [transactions]);

  const todaysSummary = useMemo(() => {
    const todayStr = today();
    const todaysTx = transactions.filter((t) => t.date === todayStr && !t.closed);
    const bottles = todaysTx.reduce((sum, t) => sum + Number(t.bottles), 0);
    const cashCollected = todaysTx
      .filter((t) => (t.payment_method || "Cash") === "Cash")
      .reduce((sum, t) => sum + Number(t.paid), 0);
    const otherCollected = todaysTx
      .filter((t) => (t.payment_method || "Cash") !== "Cash")
      .reduce((sum, t) => sum + Number(t.paid), 0);
    const totalCollected = cashCollected + otherCollected;
    const todaysExpenses = expenses.filter((e) => e.date === todayStr).reduce((sum, e) => sum + Number(e.amount), 0);
    return {
      bottles,
      cashCollected,
      otherCollected,
      totalCollected,
      expenses: todaysExpenses,
      net: cashCollected - todaysExpenses, // liquid cash in hand only — Easypaisa/JazzCash/Bank Transfer never sit in the salesperson's pocket
    };
  }, [transactions, expenses]);

  const usedAreas = useMemo(() => {
    const set = new Set(customers.map((c) => c.area).filter(Boolean));
    return AREAS.filter((a) => set.has(a));
  }, [customers]);

  const groupedCustomers = useMemo(() => {
    const bySearch = customerSearch.trim()
      ? customers.filter((c) => c.name.toLowerCase().includes(customerSearch.trim().toLowerCase()))
      : customers;
    const filtered = areaFilter === "all" ? bySearch : bySearch.filter((c) => c.area === areaFilter);
    if (areaFilter !== "all") return [{ area: areaFilter, customers: filtered }];
    const groups = {};
    filtered.forEach((c) => {
      const key = c.area || "No area set";
      if (!groups[key]) groups[key] = [];
      groups[key].push(c);
    });
    return Object.keys(groups).sort().map((area) => ({ area, customers: groups[area] }));
  }, [customers, areaFilter, customerSearch]);

  const addCustomer = async () => {
    if (!newName.trim() || savingAction) return;
    setSavingAction(true);
    try {
      const inserted = await api("/customers", {
        method: "POST",
        headers: { Prefer: "return=representation" },
        body: JSON.stringify([{ serial: nextSerial, name: newName.trim(), area: newArea, carried_balance: 0, security_deposit: parseFloat(newDeposit) || 0, opening_bottles: parseFloat(newOpeningBottles) || 0, dispenser_count: parseInt(newDispenserCount) || 0, created_by: authState.userId }]),
      });
      setCustomers((cs) => [...cs, ...inserted]);
      setNewName("");
      setNewDeposit("");
      setNewOpeningBottles("");
      setNewDispenserCount("");
    } catch (err) {
      setErrorMsg("Couldn't add customer — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const addCustomersBulk = async () => {
    const lines = bulkText.split("\n").map((l) => l.trim()).filter(Boolean);
    if (lines.length === 0 || savingAction) return;
    setSavingAction(true);
    setBulkResult("");
    try {
      let serial = nextSerial;
      const rows = lines.map((line) => {
        const parts = line.split(",");
        const name = parts[0].trim();
        const area = parts[1] ? parts[1].trim() : bulkDefaultArea;
        const deposit = parts[2] ? parseFloat(parts[2].trim()) || 0 : 0;
        const row = { serial, name, area, carried_balance: 0, security_deposit: deposit, created_by: authState.userId };
        serial += 1;
        return row;
      }).filter((r) => r.name);

      const inserted = await api("/customers", {
        method: "POST",
        headers: { Prefer: "return=representation" },
        body: JSON.stringify(rows),
      });
      setCustomers((cs) => [...cs, ...inserted]);
      setBulkResult(`Added ${inserted.length} customers.`);
      setBulkText("");
    } catch (err) {
      setErrorMsg("Couldn't add the list — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const [editingCustomerId, setEditingCustomerId] = useState(null);
  const [editCustomerDraft, setEditCustomerDraft] = useState({ name: "", area: "", deposit: "", openingBottles: "", dispenserCount: "" });

  const startEditCustomer = (c) => {
    setEditingCustomerId(c.id);
    setEditCustomerDraft({ name: c.name, area: c.area || AREAS[0], deposit: String(c.security_deposit || 0), openingBottles: String(c.opening_bottles || 0), dispenserCount: String(c.dispenser_count || 0) });
  };
  const cancelEditCustomer = () => setEditingCustomerId(null);

  const saveEditCustomer = async (id) => {
    const name = editCustomerDraft.name.trim();
    if (!name) return;
    const area = editCustomerDraft.area;
    const deposit = parseFloat(editCustomerDraft.deposit) || 0;
    const openingBottles = parseFloat(editCustomerDraft.openingBottles) || 0;
    const dispenserCount = parseInt(editCustomerDraft.dispenserCount) || 0;
    setSavingAction(true);
    try {
      await api(`/customers?id=eq.${id}`, {
        method: "PATCH",
        body: JSON.stringify({ name, area, security_deposit: deposit, opening_bottles: openingBottles, dispenser_count: dispenserCount }),
      });
      setCustomers((cs) => cs.map((c) => (c.id === id ? { ...c, name, area, security_deposit: deposit, opening_bottles: openingBottles, dispenser_count: dispenserCount } : c)));
      setEditingCustomerId(null);
    } catch (err) {
      setErrorMsg("Couldn't save changes — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const removeCustomer = async (id) => {
    setSavingAction(true);
    try {
      await api(`/customers?id=eq.${id}`, { method: "DELETE" });
      setCustomers((cs) => cs.filter((c) => c.id !== id));
      setTransactions((ts) => ts.filter((t) => t.customer_id !== id));
      if (expanded === id) setExpanded(null);
    } catch (err) {
      setErrorMsg("Couldn't remove customer — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const toggleExpand = (id) => {
    setExpanded((cur) => (cur === id ? null : id));
    setEntryDate(today());
    setEntryBottles("");
    setEntryRate(String(DEFAULT_RATE));
    setEntryPaid("");
  };

  const addTransaction = async (customerId) => {
    const bottles = parseFloat(entryBottles) || 0;
    const bottlesReturned = parseFloat(entryBottlesReturned) || 0;
    const rate = parseFloat(entryRate) || 0;
    const paid = parseFloat(entryPaid) || 0;
    if (bottles <= 0 && paid <= 0 && bottlesReturned <= 0) return;
    setSavingAction(true);
    try {
      const inserted = await api("/transactions", {
        method: "POST",
        headers: { Prefer: "return=representation" },
        body: JSON.stringify([{ customer_id: customerId, date: entryDate, bottles, bottles_returned: bottlesReturned, rate, paid, closed: false, payment_method: entryPaymentMethod, created_by: authState.userId }]),
      });
      setTransactions((ts) => [...ts, ...inserted]);
      setEntryBottles("");
      setEntryBottlesReturned("");
      setEntryPaid("");
    } catch (err) {
      setErrorMsg("Couldn't save entry — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const removeTransaction = async (txId) => {
    setSavingAction(true);
    try {
      await api(`/transactions?id=eq.${txId}`, { method: "DELETE" });
      setTransactions((ts) => ts.filter((t) => t.id !== txId));
    } catch (err) {
      setErrorMsg("Couldn't remove entry — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const startEditTx = (tx) => {
    setEditingTxId(tx.id);
    setEditDraft({ date: tx.date, bottles: String(tx.bottles), bottlesReturned: String(tx.bottles_returned || 0), rate: String(tx.rate), paid: String(tx.paid), paymentMethod: tx.payment_method || PAYMENT_METHODS[0] });
  };
  const cancelEditTx = () => setEditingTxId(null);

  const saveEditTx = async (txId) => {
    const bottles = parseFloat(editDraft.bottles) || 0;
    const bottlesReturned = parseFloat(editDraft.bottlesReturned) || 0;
    const rate = parseFloat(editDraft.rate) || 0;
    const paid = parseFloat(editDraft.paid) || 0;
    const date = editDraft.date || today();
    const paymentMethod = editDraft.paymentMethod || PAYMENT_METHODS[0];
    setSavingAction(true);
    try {
      await api(`/transactions?id=eq.${txId}`, {
        method: "PATCH",
        body: JSON.stringify({ date, bottles, bottles_returned: bottlesReturned, rate, paid, payment_method: paymentMethod }),
      });
      setTransactions((ts) => ts.map((t) => (t.id === txId ? { ...t, date, bottles, bottles_returned: bottlesReturned, rate, paid, payment_method: paymentMethod } : t)));
      setEditingTxId(null);
    } catch (err) {
      setErrorMsg("Couldn't save changes — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const closePeriod = async (customer) => {
    const open = currentTxByCustomer[customer.id] || [];
    if (open.length === 0) return;
    const t = periodTotals(open);
    const closingBalance = Number(customer.carried_balance) + t.charged - t.paid;
    const label = monthLabel();
    const closedOn = today();
    setSavingAction(true);
    try {
      await api(`/transactions?customer_id=eq.${customer.id}&closed=eq.false`, {
        method: "PATCH",
        body: JSON.stringify({ closed: true, period_label: label, closed_on: closedOn }),
      });
      await api(`/customers?id=eq.${customer.id}`, {
        method: "PATCH",
        body: JSON.stringify({ carried_balance: closingBalance }),
      });
      setTransactions((ts) => ts.map((t) => (t.customer_id === customer.id && !t.closed ? { ...t, closed: true, period_label: label, closed_on: closedOn } : t)));
      setCustomers((cs) => cs.map((c) => (c.id === customer.id ? { ...c, carried_balance: closingBalance } : c)));
    } catch (err) {
      setErrorMsg("Couldn't close the period — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const closeMonthAndReport = async () => {
    const allOpen = transactions.filter((t) => !t.closed);
    if (allOpen.length === 0) {
      setErrorMsg("No open entries to close this month.");
      setShowCloseMonthConfirm(false);
      return;
    }
    const label = monthLabel();
    const closedOn = today();

    // Build the report from current in-memory data before closing
    const customerById = {};
    customers.forEach((c) => { customerById[c.id] = c; });

    let totalBottles = 0, totalCharged = 0, totalPaid = 0;
    const byArea = {};
    const byPayment = {};
    const perCustomerAgg = {};

    allOpen.forEach((t) => {
      const cust = customerById[t.customer_id];
      const area = (cust && cust.area) || "No area set";
      const bottles = Number(t.bottles);
      const charged = bottles * Number(t.rate);
      const paid = Number(t.paid);
      const method = t.payment_method || "Cash";

      totalBottles += bottles;
      totalCharged += charged;
      totalPaid += paid;

      if (!byArea[area]) byArea[area] = { bottles: 0, charged: 0, paid: 0 };
      byArea[area].bottles += bottles;
      byArea[area].charged += charged;
      byArea[area].paid += paid;

      if (!byPayment[method]) byPayment[method] = 0;
      byPayment[method] += method === "Credit" ? charged : paid;

      if (!perCustomerAgg[t.customer_id]) perCustomerAgg[t.customer_id] = { charged: 0, paid: 0 };
      perCustomerAgg[t.customer_id].charged += charged;
      perCustomerAgg[t.customer_id].paid += paid;
    });

    setSavingAction(true);
    try {
      await api(`/transactions?closed=eq.false`, {
        method: "PATCH",
        body: JSON.stringify({ closed: true, period_label: label, closed_on: closedOn }),
      });

      const customerUpdates = Object.keys(perCustomerAgg).map((cid) => {
        const cust = customerById[cid];
        const agg = perCustomerAgg[cid];
        const newBalance = Number(cust.carried_balance) + agg.charged - agg.paid;
        return api(`/customers?id=eq.${cid}`, {
          method: "PATCH",
          body: JSON.stringify({ carried_balance: newBalance }),
        }).then(() => ({ id: cid, newBalance }));
      });
      const results = await Promise.all(customerUpdates);

      setTransactions((ts) => ts.map((t) => (!t.closed ? { ...t, closed: true, period_label: label, closed_on: closedOn } : t)));
      setCustomers((cs) => cs.map((c) => {
        const match = results.find((r) => String(r.id) === String(c.id));
        return match ? { ...c, carried_balance: match.newBalance } : c;
      }));

      const currentYearMonth = closedOn.slice(0, 7);
      const monthExpenses = expenses.filter((e) => e.date && e.date.slice(0, 7) === currentYearMonth);
      const totalExpensesThisMonth = monthExpenses.reduce((sum, e) => sum + Number(e.amount), 0);

      setReportData({
        label, closedOn, totalBottles, totalCharged, totalPaid,
        totalBalance: totalCharged - totalPaid,
        totalExpenses: totalExpensesThisMonth,
        netCash: totalPaid - totalExpensesThisMonth,
        byArea, byPayment,
      });
      setShowCloseMonthConfirm(false);
      setShowReportModal(true);
    } catch (err) {
      setErrorMsg("Couldn't close the month — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const printReport = () => {
    if (!reportData) return;
    const areaRows = Object.entries(reportData.byArea).sort((a, b) => b[1].bottles - a[1].bottles)
      .map(([area, agg]) => `<tr><td>${area}</td><td>${agg.bottles}</td><td>${money(agg.charged)}</td><td>${money(agg.paid)}</td></tr>`).join("");
    const paymentRows = Object.entries(reportData.byPayment)
      .map(([method, amount]) => `<tr><td>${method}</td><td>${money(amount)}</td></tr>`).join("");
    const html = `
      <h1>${reportData.label} — Monthly Report</h1>
      <div class="muted">Closed on ${fmtDate(reportData.closedOn)}</div>
      <div class="stat-row">
        <div class="stat"><div class="stat-label">Bottles sold</div><div class="stat-value">${reportData.totalBottles}</div></div>
        <div class="stat"><div class="stat-label">Collected</div><div class="stat-value">${money(reportData.totalPaid)}</div></div>
        <div class="stat"><div class="stat-label">Outstanding</div><div class="stat-value">${money(reportData.totalBalance)}</div></div>
        <div class="stat"><div class="stat-label">Expenses</div><div class="stat-value">${money(reportData.totalExpenses || 0)}</div></div>
        <div class="stat"><div class="stat-label">Net cash</div><div class="stat-value">${money(reportData.netCash != null ? reportData.netCash : reportData.totalPaid)}</div></div>
      </div>
      <div class="section-title">Cash flow by type</div>
      <table><thead><tr><th>Method</th><th>Amount</th></tr></thead><tbody>${paymentRows}</tbody></table>
      <div class="section-title">Distribution by area</div>
      <table><thead><tr><th>Area</th><th>Bottles</th><th>Charged</th><th>Collected</th></tr></thead><tbody>${areaRows}</tbody></table>
    `;
    printHtml(`${reportData.label} Report`, html);
  };

  const addExpense = async () => {
    const amount = parseFloat(expenseAmount) || 0;
    if (amount <= 0 || savingAction) return;
    setSavingAction(true);
    try {
      const inserted = await api("/expenses", {
        method: "POST",
        headers: { Prefer: "return=representation" },
        body: JSON.stringify([{ date: expenseDate, category: expenseCategory, amount, note: expenseNote.trim() || null, created_by: authState.userId }]),
      });
      setExpenses((es) => [...inserted, ...es]);
      setExpenseAmount("");
      setExpenseNote("");
    } catch (err) {
      setErrorMsg("Couldn't save expense — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const removeExpense = async (id) => {
    setSavingAction(true);
    try {
      await api(`/expenses?id=eq.${id}`, { method: "DELETE" });
      setExpenses((es) => es.filter((e) => e.id !== id));
    } catch (err) {
      setErrorMsg("Couldn't remove expense — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const [showManageTeam, setShowManageTeam] = useState(false);
  const [customerDetail, setCustomerDetail] = useState(null);
  const [customerDetailPeriod, setCustomerDetailPeriod] = useState("current");

  const toggleProfileActive = async (profileId, newActive) => {
    setSavingAction(true);
    try {
      await api(`/profiles?id=eq.${profileId}`, {
        method: "PATCH",
        body: JSON.stringify({ active: newActive }),
      });
      setProfiles((ps) => ps.map((p) => (p.id === profileId ? { ...p, active: newActive } : p)));
    } catch (err) {
      setErrorMsg("Couldn't update that account — try again.");
    } finally {
      setSavingAction(false);
    }
  };

  const profileNameById = useMemo(() => {
    const map = {};
    profiles.forEach((p) => { map[p.id] = p.name || p.role; });
    return map;
  }, [profiles]);

  const customerById = useMemo(() => {
    const map = {};
    customers.forEach((c) => { map[c.id] = c; });
    return map;
  }, [customers]);

  const teamRangeTx = useMemo(() => {
    return transactions.filter((t) => t.date >= teamDateFrom && t.date <= teamDateTo);
  }, [transactions, teamDateFrom, teamDateTo]);

  const outstandingBySalesperson = useMemo(() => {
    const map = {};
    customers.forEach((c) => {
      const key = c.created_by || "unassigned";
      const cur = periodTotals(currentTxByCustomer[c.id] || []);
      const balance = Number(c.carried_balance) + cur.charged - cur.paid;
      map[key] = (map[key] || 0) + balance;
    });
    return map;
  }, [customers, currentTxByCustomer]);

  const teamStats = useMemo(() => {
    const map = {};
    teamRangeTx.forEach((t) => {
      const key = t.created_by || "unassigned";
      if (!map[key]) map[key] = { entries: 0, bottles: 0, charged: 0, paid: 0, customerIds: new Set(), items: [] };
      map[key].entries += 1;
      map[key].bottles += Number(t.bottles);
      map[key].charged += Number(t.bottles) * Number(t.rate);
      map[key].paid += Number(t.paid);
      map[key].customerIds.add(t.customer_id);
      map[key].items.push(t);
    });
    return Object.entries(map)
      .map(([id, stats]) => ({
        id,
        name: id === "unassigned" ? "Before tracking / unassigned" : (profileNameById[id] || "Unknown user"),
        entries: stats.entries,
        bottles: stats.bottles,
        charged: stats.charged,
        paid: stats.paid,
        customers: stats.customerIds.size,
        outstanding: outstandingBySalesperson[id] || 0,
        items: stats.items.sort((a, b) => b.date.localeCompare(a.date)),
      }))
      .sort((a, b) => b.bottles - a.bottles);
  }, [teamRangeTx, profileNameById, outstandingBySalesperson]);

  const printTeamPerformance = () => {
    const rows = teamStats.map((s) => `
      <tr><td>${s.name}</td><td>${s.entries}</td><td>${s.bottles}</td><td>${s.customers}</td><td>${money(s.paid)}</td><td>${s.outstanding > 0 ? money(s.outstanding) : "Settled"}</td></tr>
    `).join("");
    const html = `
      <h1>Team Performance</h1>
      <div class="muted">${fmtDate(teamDateFrom)} – ${fmtDate(teamDateTo)}</div>
      <table>
        <thead><tr><th>Name</th><th>Entries</th><th>Bottles</th><th>Customers</th><th>Collected</th><th>Must collect</th></tr></thead>
        <tbody>${rows || '<tr><td colspan="6" class="muted">No entries in this date range.</td></tr>'}</tbody>
      </table>
    `;
    printHtml("Team Performance", html);
  };

  const expenseTotals = useMemo(() => {
    return expenses.reduce((sum, e) => sum + Number(e.amount), 0);
  }, [expenses]);

  function yearMonthFromLabel(label) {
    const d = new Date("1 " + label);
    if (isNaN(d.getTime())) return null;
    return d.toISOString().slice(0, 7);
  }

  const ownerPeriodExpenses = useMemo(() => {
    const targetYM = ownerPeriod === "current" ? today().slice(0, 7) : yearMonthFromLabel(ownerPeriod);
    if (!targetYM) return [];
    return expenses.filter((e) => e.date && e.date.slice(0, 7) === targetYM);
  }, [expenses, ownerPeriod]);

  const ownerPeriodExpenseTotal = useMemo(() => {
    return ownerPeriodExpenses.reduce((sum, e) => sum + Number(e.amount), 0);
  }, [ownerPeriodExpenses]);

  const closedPeriodLabels = useMemo(() => {
    const set = new Set();
    transactions.forEach((t) => { if (t.closed && t.period_label) set.add(t.period_label); });
    return Array.from(set);
  }, [transactions]);

  const ownerPeriodTx = useMemo(() => {
    return ownerPeriod === "current" ? transactions.filter((t) => !t.closed) : transactions.filter((t) => t.closed && t.period_label === ownerPeriod);
  }, [transactions, ownerPeriod]);

  const ownerStats = useMemo(() => {
    let bottles = 0, charged = 0, paid = 0;
    const byArea = {};
    const byPayment = {};
    ownerPeriodTx.forEach((t) => {
      const cust = customerById[t.customer_id];
      const area = (cust && cust.area) || "No area set";
      const b = Number(t.bottles);
      const c = b * Number(t.rate);
      const p = Number(t.paid);
      const method = t.payment_method || "Cash";
      bottles += b; charged += c; paid += p;
      if (!byArea[area]) byArea[area] = { bottles: 0, charged: 0, paid: 0 };
      byArea[area].bottles += b; byArea[area].charged += c; byArea[area].paid += p;
      if (!byPayment[method]) byPayment[method] = 0;
      byPayment[method] += method === "Credit" ? c : p;
    });
    return { bottles, charged, paid, balance: charged - paid, byArea, byPayment };
  }, [ownerPeriodTx, customerById]);

  const customerLifetime = useMemo(() => {
    return customers.map((c) => {
      const lt = lifetimeByCustomer[c.id] || { bottles: 0, paid: 0, returned: 0 };
      const cur = periodTotals(currentTxByCustomer[c.id] || []);
      const balance = Number(c.carried_balance) + cur.charged - cur.paid;
      return { ...c, lifetimeBottles: lt.bottles, lifetimePaid: lt.paid, bottlesOutstanding: Number(c.opening_bottles || 0) + lt.bottles - lt.returned, balance };
    }).sort((a, b) => b.lifetimeBottles - a.lifetimeBottles);
  }, [customers, lifetimeByCustomer, currentTxByCustomer]);

  const printOwnerDashboard = () => {
    const paymentRows = Object.entries(ownerStats.byPayment)
      .map(([method, amt]) => `<tr><td>${method}</td><td>${money(amt)}</td></tr>`).join("");
    const areaRows = Object.entries(ownerStats.byArea).sort((a, b) => b[1].bottles - a[1].bottles)
      .map(([area, agg]) => `<tr><td>${area}</td><td>${agg.bottles}</td><td>${money(agg.charged)}</td><td>${money(agg.paid)}</td></tr>`).join("");
    const customerRows = customerLifetime.map((c) => `
      <tr><td>${c.name}</td><td>${c.area || "—"}</td><td>${c.lifetimeBottles}</td><td>${c.bottlesOutstanding}</td><td>${Number(c.security_deposit) > 0 ? money(c.security_deposit) : "—"}</td><td>${money(c.lifetimePaid)}</td><td>${c.balance > 0 ? money(c.balance) : "Settled"}</td></tr>
    `).join("");
    const periodLabel = ownerPeriod === "current" ? "Current (not yet closed)" : ownerPeriod;
    const html = `
      <h1>Business Overview</h1>
      <div class="muted">${periodLabel}</div>
      <div class="stat-row">
        <div class="stat"><div class="stat-label">Bottles</div><div class="stat-value">${ownerStats.bottles}</div></div>
        <div class="stat"><div class="stat-label">Collected</div><div class="stat-value">${money(ownerStats.paid)}</div></div>
        <div class="stat"><div class="stat-label">Outstanding</div><div class="stat-value">${money(ownerStats.balance)}</div></div>
        <div class="stat"><div class="stat-label">Expenses</div><div class="stat-value">${money(ownerPeriodExpenseTotal)}</div></div>
        <div class="stat"><div class="stat-label">Net cash</div><div class="stat-value">${money(ownerStats.paid - ownerPeriodExpenseTotal)}</div></div>
      </div>
      <div class="section-title">Cash flow by type</div>
      <table><thead><tr><th>Method</th><th>Amount</th></tr></thead><tbody>${paymentRows}</tbody></table>
      <div class="section-title">Bottles &amp; cash by area</div>
      <table><thead><tr><th>Area</th><th>Bottles</th><th>Charged</th><th>Collected</th></tr></thead><tbody>${areaRows}</tbody></table>
      <div class="section-title">Customers — lifetime overview</div>
      <table><thead><tr><th>Customer</th><th>Area</th><th>Lifetime</th><th>With them</th><th>Deposit</th><th>Collected</th><th>Balance</th></tr></thead><tbody>${customerRows}</tbody></table>
    `;
    printHtml("Business Overview", html);
  };

  const customerDetailHistory = customerDetail ? (historyByCustomer[customerDetail.id] || []) : [];

  const customerDetailTx = useMemo(() => {
    if (!customerDetail) return [];
    if (customerDetailPeriod === "current") return currentTxByCustomer[customerDetail.id] || [];
    const period = customerDetailHistory.find((h) => `${h.label}__${h.closedOn}` === customerDetailPeriod);
    return period ? period.transactions : [];
  }, [customerDetail, customerDetailPeriod, currentTxByCustomer, customerDetailHistory]);

  const customerDetailTotals = useMemo(() => periodTotals(customerDetailTx), [customerDetailTx]);

  const printCustomerBill = () => {
    if (!customerDetail) return;
    const rows = [...customerDetailTx].sort((a, b) => a.date.localeCompare(b.date))
      .map((tx) => `<tr><td>${fmtDate(tx.date)}</td><td>${tx.bottles}</td><td>${tx.bottles_returned || 0}</td><td>${money(tx.rate)}</td><td>${money(tx.bottles * tx.rate)}</td><td>${money(tx.paid)}</td><td>${tx.payment_method || "Cash"}</td></tr>`)
      .join("");
    const periodLabel = customerDetailPeriod === "current" ? "Current period" : customerDetailPeriod.split("__")[0];
    const html = `
      <h1>#${customerDetail.serial} · ${customerDetail.name}</h1>
      <div class="muted">
        ${customerDetail.area || "No area set"}
        ${Number(customerDetail.security_deposit) > 0 ? " · Deposit held: " + money(customerDetail.security_deposit) : ""}
        ${customerDetail.dispenser_count > 0 ? " · Dispensers: " + customerDetail.dispenser_count : ""}
        · ${periodLabel}
      </div>
      <div class="stat-row">
        <div class="stat"><div class="stat-label">Bottles</div><div class="stat-value">${customerDetailTotals.bottles}</div></div>
        <div class="stat"><div class="stat-label">Charged</div><div class="stat-value">${money(customerDetailTotals.charged)}</div></div>
        <div class="stat"><div class="stat-label">Paid</div><div class="stat-value">${money(customerDetailTotals.paid)}</div></div>
        <div class="stat"><div class="stat-label">Balance</div><div class="stat-value">${money(customerDetailTotals.charged - customerDetailTotals.paid)}</div></div>
      </div>
      <table>
        <thead><tr><th>Date</th><th>Bottles</th><th>Returned</th><th>Rate</th><th>Charged</th><th>Paid</th><th>Method</th></tr></thead>
        <tbody>${rows || '<tr><td colspan="7" class="muted">No entries in this period.</td></tr>'}</tbody>
      </table>
    `;
    printHtml(`${customerDetail.name} — Bill`, html);
  };

  const exportBackup = () => {
    const payload = {
      exported_at: new Date().toISOString(),
      customers,
      transactions,
      expenses,
    };
    const blob = new Blob([JSON.stringify(payload, null, 2)], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `aab-e-saaf-backup-${today()}.json`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  const fraunces = { fontFamily: "'Fraunces', serif" };
  const roleLabel = role === "admin" ? "Admin" : role === "owner" ? "Owner" : "Salesperson";
  const manrope = { fontFamily: "'Manrope', sans-serif" };

  if (!authChecked) {
    return (
      <div className="min-h-screen flex items-center justify-center" style={{ background: COLORS.paper, ...manrope }}>
        <div className="flex items-center gap-2" style={{ color: COLORS.teal700 }}>
          <Loader2 size={18} className="animate-spin" /> Checking session…
        </div>
      </div>
    );
  }

  if (!authState) {
    return (
      <div className="min-h-screen flex items-center justify-center px-5" style={{ background: COLORS.teal900, ...manrope }}>
        <link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,600&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
        <div className="w-full max-w-sm rounded-2xl p-6" style={{ background: "white" }}>
          <div className="flex items-center gap-2.5 mb-5">
            <div className="w-9 h-9 rounded-full flex items-center justify-center" style={{ background: COLORS.teal900 }}>
              <Boxes size={16} color={COLORS.aqua300} />
            </div>
            <div className="font-semibold text-base" style={{ color: COLORS.ink, ...fraunces }}>ClearFlow — Customer Ledger (Demo)</div>
          </div>
          <label className="text-xs font-medium block mb-1.5" style={{ color: COLORS.muted }}>Email</label>
          <input
            value={loginEmail}
            onChange={(e) => setLoginEmail(e.target.value)}
            onKeyDown={(e) => e.key === "Enter" && handleLogin()}
            type="email"
            autoCapitalize="none"
            placeholder="you@yourcompany.com"
            className="w-full text-sm rounded-xl px-3 py-2.5 outline-none mb-3"
            style={{ border: `1px solid ${COLORS.line}`, color: COLORS.ink }}
          />
          <label className="text-xs font-medium block mb-1.5" style={{ color: COLORS.muted }}>Password</label>
          <input
            value={loginPassword}
            onChange={(e) => setLoginPassword(e.target.value)}
            onKeyDown={(e) => e.key === "Enter" && handleLogin()}
            type="password"
            placeholder="••••••••"
            className="w-full text-sm rounded-xl px-3 py-2.5 outline-none mb-1"
            style={{ border: `1px solid ${loginError ? COLORS.danger : COLORS.line}`, color: COLORS.ink }}
          />
          {loginError && <div className="text-xs mb-2 mt-1" style={{ color: COLORS.danger }}>{loginError}</div>}
          <button
            onClick={handleLogin}
            disabled={loginLoading}
            className="w-full mt-3 py-2.5 rounded-full text-sm font-semibold text-white flex items-center justify-center gap-2"
            style={{ background: COLORS.teal700, opacity: loginLoading ? 0.7 : 1 }}
          >
            {loginLoading ? <Loader2 size={15} className="animate-spin" /> : null} Log in
          </button>
        </div>
      </div>
    );
  }

  if (loading) {
    return (
      <div className="min-h-screen flex items-center justify-center" style={{ background: COLORS.paper, ...manrope }}>
        <div className="flex items-center gap-2" style={{ color: COLORS.teal700 }}>
          <Loader2 size={18} className="animate-spin" /> Loading ledger…
        </div>
      </div>
    );
  }

  return (
    <div className="min-h-screen" style={{ background: COLORS.paper, ...manrope }}>
      <link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,600&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet" />
      <style>{`
        @media print {
          body * { visibility: hidden; }
          .print-area, .print-area * { visibility: visible; }
          .print-area { position: absolute; left: 0; top: 0; width: 100%; background: white !important; }
          .no-print { display: none !important; }
        }
      `}</style>

      <header className="px-5 sm:px-10 py-5" style={{ background: COLORS.teal900 }}>
        <div className="max-w-5xl mx-auto flex items-center justify-between flex-wrap gap-3">
          <div className="flex items-center gap-3">
            <div className="w-9 h-9 rounded-full flex items-center justify-center" style={{ background: "rgba(255,255,255,0.1)" }}>
              <Boxes size={16} color={COLORS.aqua300} />
            </div>
            <div>
              <div className="text-base leading-tight text-white" style={{ ...fraunces, fontWeight: 600 }}>ClearFlow — Customer Ledger (Demo)</div>
              <div className="text-[11px] leading-tight" style={{ color: COLORS.aqua300 }}>Connected to your database — changes are saved for real</div>
            </div>
          </div>
          <div className="flex items-center gap-3">
            <div className="text-right">
              <div className="text-sm font-semibold text-white">{authState.name}</div>
              <div className="text-[11px]" style={{ color: COLORS.aqua300 }}>{roleLabel}</div>
            </div>
            <button onClick={handleLogout} className="px-4 py-1.5 rounded-full text-xs font-semibold" style={{ background: "rgba(255,255,255,0.1)", color: COLORS.aqua300 }}>
              Log out
            </button>
          </div>
        </div>
      </header>

      {showCloseMonthConfirm && (
        <div className="fixed inset-0 z-50 flex items-center justify-center px-4" style={{ background: "rgba(12,59,59,0.55)" }}>
          <div className="w-full max-w-sm rounded-2xl p-5" style={{ background: "white" }}>
            <div className="font-semibold text-sm mb-2" style={{ color: COLORS.ink, ...fraunces }}>Close this month for everyone?</div>
            <p className="text-xs mb-4" style={{ color: COLORS.muted }}>
              This closes the current period for every customer with activity, archives their entries, carries forward any unpaid balance, and generates a report for the whole month. This can't be undone.
            </p>
            <div className="flex gap-2">
              <button onClick={() => setShowCloseMonthConfirm(false)} className="flex-1 py-2 rounded-full text-xs font-semibold" style={{ border: `1.5px solid ${COLORS.line}`, color: COLORS.ink }}>Cancel</button>
              <button onClick={closeMonthAndReport} disabled={savingAction} className="flex-1 py-2 rounded-full text-xs font-semibold text-white flex items-center justify-center gap-1.5" style={{ background: COLORS.gold500, color: COLORS.teal900, opacity: savingAction ? 0.6 : 1 }}>
                {savingAction ? <Loader2 size={13} className="animate-spin" /> : <FileBarChart size={13} />} Close &amp; generate report
              </button>
            </div>
          </div>
        </div>
      )}

      {showReportModal && reportData && (
        <div className="fixed inset-0 z-50 flex items-center justify-center px-4 py-8 overflow-y-auto" style={{ background: "rgba(12,59,59,0.6)" }}>
          <div className={(showReportModal ? "print-area " : "") + "w-full max-w-lg rounded-2xl p-5 sm:p-6 my-auto"} style={{ background: "white" }}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-base" style={{ color: COLORS.ink, ...fraunces }}>{reportData.label} — Report</div>
              <button onClick={() => setShowReportModal(false)} aria-label="Close report" className="no-print"><X size={16} color={COLORS.muted} /></button>
            </div>
            <p className="text-xs mb-4" style={{ color: COLORS.muted }}>Closed on {fmtDate(reportData.closedOn)}</p>

            <div className="grid grid-cols-3 gap-2 mb-5">
              <div className="rounded-xl p-3" style={{ background: COLORS.paperDeep }}>
                <div className="text-[10px] uppercase font-bold" style={{ color: COLORS.teal700 }}>Bottles sold</div>
                <div className="text-lg font-semibold" style={{ ...fraunces, color: COLORS.ink }}>{reportData.totalBottles}</div>
              </div>
              <div className="rounded-xl p-3" style={{ background: COLORS.paperDeep }}>
                <div className="text-[10px] uppercase font-bold" style={{ color: COLORS.teal700 }}>Collected</div>
                <div className="text-lg font-semibold" style={{ ...fraunces, color: COLORS.ink }}>{money(reportData.totalPaid)}</div>
              </div>
              <div className="rounded-xl p-3" style={{ background: reportData.totalBalance > 0 ? COLORS.teal900 : COLORS.paperDeep }}>
                <div className="text-[10px] uppercase font-bold" style={{ color: reportData.totalBalance > 0 ? COLORS.aqua300 : COLORS.teal700 }}>Outstanding</div>
                <div className="text-lg font-semibold" style={{ ...fraunces, color: reportData.totalBalance > 0 ? "white" : COLORS.ink }}>{money(reportData.totalBalance)}</div>
              </div>
            </div>

            <div className="flex items-center justify-between text-sm rounded-xl px-4 py-3 mb-5" style={{ background: COLORS.paperDeep }}>
              <span style={{ color: COLORS.muted }}>Expenses this month</span>
              <span className="font-semibold" style={{ color: COLORS.danger }}>− {money(reportData.totalExpenses || 0)}</span>
            </div>
            <div className="flex items-center justify-between text-sm rounded-xl px-4 py-3 mb-5" style={{ background: COLORS.teal900 }}>
              <span style={{ color: COLORS.aqua300 }}>Net cash (collected − expenses)</span>
              <span className="font-semibold" style={{ color: "white" }}>{money(reportData.netCash != null ? reportData.netCash : reportData.totalPaid)}</span>
            </div>

            <div className="mb-5">
              <div className="text-xs font-bold uppercase tracking-wide mb-2" style={{ color: COLORS.teal700 }}>Cash situation by payment method</div>
              <div className="space-y-1.5">
                {Object.entries(reportData.byPayment).map(([method, amount]) => (
                  <div key={method} className="flex justify-between text-sm" style={{ color: COLORS.ink }}>
                    <span>{method}</span>
                    <span className="font-semibold">{money(amount)}</span>
                  </div>
                ))}
              </div>
            </div>

            <div>
              <div className="text-xs font-bold uppercase tracking-wide mb-2" style={{ color: COLORS.teal700 }}>Distribution by area</div>
              <div className="overflow-x-auto">
                <table className="w-full text-sm" style={{ minWidth: 380 }}>
                  <thead>
                    <tr style={{ borderBottom: `1px solid ${COLORS.line}` }}>
                      {["Area", "Bottles", "Charged", "Collected"].map((h) => (
                        <th key={h} className="text-left py-1.5 text-[11px] font-bold uppercase" style={{ color: COLORS.muted }}>{h}</th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {Object.entries(reportData.byArea).sort((a, b) => b[1].bottles - a[1].bottles).map(([area, agg]) => (
                      <tr key={area} style={{ borderBottom: `1px solid ${COLORS.paperDeep}` }}>
                        <td className="py-1.5" style={{ color: COLORS.ink }}>{area}</td>
                        <td className="py-1.5" style={{ color: COLORS.ink }}>{agg.bottles}</td>
                        <td className="py-1.5" style={{ color: COLORS.ink }}>{money(agg.charged)}</td>
                        <td className="py-1.5" style={{ color: COLORS.ink }}>{money(agg.paid)}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>

            <div className="flex gap-2 mt-5 no-print">
              <button onClick={printReport} className="flex-1 py-2.5 rounded-full text-sm font-semibold flex items-center justify-center gap-2" style={{ border: `1.5px solid ${COLORS.teal700}`, color: COLORS.teal700, background: "white" }}>
                Print
              </button>
              <button onClick={() => setShowReportModal(false)} className="flex-1 py-2.5 rounded-full text-sm font-semibold text-white" style={{ background: COLORS.teal700 }}>
                Done
              </button>
            </div>
          </div>
        </div>
      )}

      {confirmDeleteCustomer && (
        <div className="fixed inset-0 z-50 flex items-center justify-center px-4" style={{ background: "rgba(12,59,59,0.55)" }}>
          <div className="w-full max-w-xs rounded-2xl p-5" style={{ background: "white" }}>
            <div className="font-semibold text-sm mb-2" style={{ color: COLORS.danger, ...fraunces }}>Delete {confirmDeleteCustomer.name}?</div>
            <p className="text-xs mb-4" style={{ color: COLORS.muted }}>
              This permanently deletes this customer <strong>and every entry in their history</strong>, current and past. There's no undo. Type their name to confirm, or cancel.
            </p>
            <div className="flex gap-2">
              <button onClick={() => setConfirmDeleteCustomer(null)} className="flex-1 py-2 rounded-full text-xs font-semibold" style={{ border: `1.5px solid ${COLORS.line}`, color: COLORS.ink }}>Cancel</button>
              <button
                onClick={() => { removeCustomer(confirmDeleteCustomer.id); setConfirmDeleteCustomer(null); }}
                className="flex-1 py-2 rounded-full text-xs font-semibold text-white"
                style={{ background: COLORS.danger }}
              >
                Delete permanently
              </button>
            </div>
          </div>
        </div>
      )}

      {confirmDeleteTx && (
        <div className="fixed inset-0 z-50 flex items-center justify-center px-4" style={{ background: "rgba(12,59,59,0.55)" }}>
          <div className="w-full max-w-xs rounded-2xl p-5" style={{ background: "white" }}>
            <div className="font-semibold text-sm mb-2" style={{ color: COLORS.danger, ...fraunces }}>Delete this entry?</div>
            <p className="text-xs mb-4" style={{ color: COLORS.muted }}>
              {fmtDate(confirmDeleteTx.date)} · {confirmDeleteTx.bottles} bottles · {money(confirmDeleteTx.paid)} paid. This can't be undone.
            </p>
            <div className="flex gap-2">
              <button onClick={() => setConfirmDeleteTx(null)} className="flex-1 py-2 rounded-full text-xs font-semibold" style={{ border: `1.5px solid ${COLORS.line}`, color: COLORS.ink }}>Cancel</button>
              <button
                onClick={() => { removeTransaction(confirmDeleteTx.id); setConfirmDeleteTx(null); }}
                className="flex-1 py-2 rounded-full text-xs font-semibold text-white"
                style={{ background: COLORS.danger }}
              >
                Delete
              </button>
            </div>
          </div>
        </div>
      )}

      {confirmDeleteExpense && (
        <div className="fixed inset-0 z-50 flex items-center justify-center px-4" style={{ background: "rgba(12,59,59,0.55)" }}>
          <div className="w-full max-w-xs rounded-2xl p-5" style={{ background: "white" }}>
            <div className="font-semibold text-sm mb-2" style={{ color: COLORS.danger, ...fraunces }}>Delete this expense?</div>
            <p className="text-xs mb-4" style={{ color: COLORS.muted }}>
              {fmtDate(confirmDeleteExpense.date)} · {confirmDeleteExpense.category} · {money(confirmDeleteExpense.amount)}. This can't be undone.
            </p>
            <div className="flex gap-2">
              <button onClick={() => setConfirmDeleteExpense(null)} className="flex-1 py-2 rounded-full text-xs font-semibold" style={{ border: `1.5px solid ${COLORS.line}`, color: COLORS.ink }}>Cancel</button>
              <button
                onClick={() => { removeExpense(confirmDeleteExpense.id); setConfirmDeleteExpense(null); }}
                className="flex-1 py-2 rounded-full text-xs font-semibold text-white"
                style={{ background: COLORS.danger }}
              >
                Delete
              </button>
            </div>
          </div>
        </div>
      )}

      {customerDetail && (
        <div className="fixed inset-0 z-50 flex items-center justify-center px-4 py-8 overflow-y-auto" style={{ background: "rgba(12,59,59,0.6)" }}>
          <div className={(customerDetail ? "print-area " : "") + "w-full max-w-lg rounded-2xl p-5 sm:p-6 my-auto"} style={{ background: "white" }}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-base" style={{ color: COLORS.ink, ...fraunces }}>#{customerDetail.serial} · {customerDetail.name}</div>
              <button onClick={() => setCustomerDetail(null)} aria-label="Close" className="no-print"><X size={16} color={COLORS.muted} /></button>
            </div>
            <p className="text-xs mb-3" style={{ color: COLORS.muted }}>
              {customerDetail.area || "No area set"}
              {Number(customerDetail.security_deposit) > 0 && <span> · Deposit held: {money(customerDetail.security_deposit)}</span>}
              {Number(customerDetail.dispenser_count) > 0 && <span> · Dispensers: {customerDetail.dispenser_count}</span>}
            </p>

            <div className="flex flex-wrap gap-1.5 mb-4 no-print">
              <button
                onClick={() => setCustomerDetailPeriod("current")}
                className="px-3 py-1.5 rounded-full text-xs font-semibold"
                style={customerDetailPeriod === "current" ? { background: COLORS.teal700, color: "white" } : { border: `1.5px solid ${COLORS.line}`, color: COLORS.ink }}
              >
                Current (open)
              </button>
              {customerDetailHistory.map((h) => {
                const key = `${h.label}__${h.closedOn}`;
                return (
                  <button
                    key={key}
                    onClick={() => setCustomerDetailPeriod(key)}
                    className="px-3 py-1.5 rounded-full text-xs font-semibold"
                    style={customerDetailPeriod === key ? { background: COLORS.teal700, color: "white" } : { border: `1.5px solid ${COLORS.line}`, color: COLORS.ink }}
                  >
                    {h.label}
                  </button>
                );
              })}
            </div>

            <div className="grid grid-cols-3 gap-2 mb-4">
              <div className="rounded-xl p-3" style={{ background: COLORS.paperDeep }}>
                <div className="text-[10px] uppercase font-bold" style={{ color: COLORS.teal700 }}>Bottles</div>
                <div className="text-lg font-semibold" style={{ ...fraunces, color: COLORS.ink }}>{customerDetailTotals.bottles}</div>
              </div>
              <div className="rounded-xl p-3" style={{ background: COLORS.paperDeep }}>
                <div className="text-[10px] uppercase font-bold" style={{ color: COLORS.teal700 }}>Charged</div>
                <div className="text-lg font-semibold" style={{ ...fraunces, color: COLORS.ink }}>{money(customerDetailTotals.charged)}</div>
              </div>
              <div className="rounded-xl p-3" style={{ background: COLORS.paperDeep }}>
                <div className="text-[10px] uppercase font-bold" style={{ color: COLORS.teal700 }}>Paid</div>
                <div className="text-lg font-semibold" style={{ ...fraunces, color: COLORS.ink }}>{money(customerDetailTotals.paid)}</div>
              </div>
            </div>

            {customerDetailTx.length === 0 ? (
              <div className="text-sm text-center py-6" style={{ color: COLORS.muted }}>No entries in this period.</div>
            ) : (
              <div className="overflow-x-auto mb-4">
                <table className="w-full text-xs" style={{ minWidth: 480 }}>
                  <thead>
                    <tr style={{ borderBottom: `1px solid ${COLORS.line}` }}>
                      {["Date", "Bottles", "Returned", "Rate", "Charged", "Paid", "Method"].map((h) => (
                        <th key={h} className="text-left py-1.5 font-bold uppercase" style={{ color: COLORS.teal700 }}>{h}</th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {[...customerDetailTx].sort((a, b) => a.date.localeCompare(b.date)).map((tx) => (
                      <tr key={tx.id} style={{ borderBottom: `1px solid ${COLORS.paperDeep}` }}>
                        <td className="py-1.5" style={{ color: COLORS.ink }}>{fmtDate(tx.date)}</td>
                        <td className="py-1.5" style={{ color: COLORS.ink }}>{tx.bottles}</td>
                        <td className="py-1.5" style={{ color: COLORS.muted }}>{tx.bottles_returned || 0}</td>
                        <td className="py-1.5" style={{ color: COLORS.muted }}>{money(tx.rate)}</td>
                        <td className="py-1.5" style={{ color: COLORS.ink }}>{money(tx.bottles * tx.rate)}</td>
                        <td className="py-1.5" style={{ color: COLORS.ink }}>{money(tx.paid)}</td>
                        <td className="py-1.5" style={{ color: COLORS.muted }}>{tx.payment_method || "Cash"}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            )}

            <div className="flex gap-2 no-print">
              <button onClick={printCustomerBill} className="flex-1 py-2.5 rounded-full text-sm font-semibold" style={{ border: `1.5px solid ${COLORS.teal700}`, color: COLORS.teal700, background: "white" }}>
                Print
              </button>
              <button onClick={() => setCustomerDetail(null)} className="flex-1 py-2.5 rounded-full text-sm font-semibold text-white" style={{ background: COLORS.teal700 }}>
                Done
              </button>
            </div>
          </div>
        </div>
      )}

      {showManageTeam && (
        <div className="fixed inset-0 z-50 flex items-center justify-center px-4 py-8 overflow-y-auto" style={{ background: "rgba(12,59,59,0.6)" }}>
          <div className="w-full max-w-lg rounded-2xl p-5 sm:p-6 my-auto" style={{ background: "white" }}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-base flex items-center gap-2" style={{ color: COLORS.ink, ...fraunces }}>
                <Users size={16} color={COLORS.teal700} /> Manage team
              </div>
              <button onClick={() => setShowManageTeam(false)} aria-label="Close"><X size={16} color={COLORS.muted} /></button>
            </div>
            <p className="text-xs mb-4" style={{ color: COLORS.muted }}>
              Blocking someone stops them logging in immediately — their password still exists, it just won't work anymore. Good for when someone leaves the job.
            </p>
            <div className="space-y-2">
              {profiles.length === 0 && (
                <div className="text-sm text-center py-6" style={{ color: COLORS.muted }}>No team accounts found.</div>
              )}
              {profiles.map((p) => {
                const isSelf = authState && p.id === authState.userId;
                const isActive = p.active !== false;
                return (
                  <div key={p.id} className="flex items-center justify-between rounded-xl p-3" style={{ background: COLORS.paperDeep }}>
                    <div>
                      <div className="font-semibold text-sm" style={{ color: COLORS.ink }}>{p.name || "Unnamed"}</div>
                      <div className="text-xs" style={{ color: COLORS.muted }}>
                        {p.role === "admin" ? "Admin" : p.role === "owner" ? "Owner" : "Salesperson"}
                        {isSelf && " · you"}
                        {!isActive && " · blocked"}
                      </div>
                    </div>
                    <button
                      onClick={() => toggleProfileActive(p.id, !isActive)}
                      disabled={savingAction || isSelf}
                      className="px-4 py-1.5 rounded-full text-xs font-semibold"
                      style={isActive
                        ? { border: `1.5px solid ${COLORS.danger}`, color: COLORS.danger, background: "white", opacity: isSelf ? 0.4 : 1 }
                        : { background: COLORS.teal700, color: "white" }}
                    >
                      {isActive ? "Block" : "Unblock"}
                    </button>
                  </div>
                );
              })}
            </div>
            <button onClick={() => setShowManageTeam(false)} className="w-full mt-5 py-2.5 rounded-full text-sm font-semibold text-white" style={{ background: COLORS.teal700 }}>
              Done
            </button>
          </div>
        </div>
      )}

      {showTeamModal && (
        <div className="fixed inset-0 z-50 flex items-center justify-center px-4 py-8 overflow-y-auto" style={{ background: "rgba(12,59,59,0.6)" }}>
          <div className={(showTeamModal ? "print-area " : "") + "w-full max-w-lg rounded-2xl p-5 sm:p-6 my-auto"} style={{ background: "white" }}>
            <div className="flex items-center justify-between mb-1">
              <div className="font-semibold text-base flex items-center gap-2" style={{ color: COLORS.ink, ...fraunces }}>
                <TrendingUp size={16} color={COLORS.teal700} /> Team performance
              </div>
              <button onClick={() => setShowTeamModal(false)} aria-label="Close" className="no-print"><X size={16} color={COLORS.muted} /></button>
            </div>
            <p className="text-xs mb-3" style={{ color: COLORS.muted }}>Tap a person to see their individual entries for the selected dates.</p>

            <div className="flex flex-wrap gap-1.5 mb-3">
              {[
                { label: "Today", from: today(), to: today() },
                { label: "Yesterday", from: (() => { const d = new Date(); d.setDate(d.getDate() - 1); return d.toISOString().slice(0, 10); })(), to: (() => { const d = new Date(); d.setDate(d.getDate() - 1); return d.toISOString().slice(0, 10); })() },
                { label: "This month", from: today().slice(0, 8) + "01", to: today() },
                { label: "All time", from: "2000-01-01", to: today() },
              ].map((p) => (
                <button
                  key={p.label}
                  onClick={() => { setTeamDateFrom(p.from); setTeamDateTo(p.to); }}
                  className="px-3 py-1.5 rounded-full text-xs font-semibold"
                  style={teamDateFrom === p.from && teamDateTo === p.to ? { background: COLORS.teal700, color: "white" } : { border: `1.5px solid ${COLORS.line}`, color: COLORS.ink }}
                >
                  {p.label}
                </button>
              ))}
            </div>
            <div className="flex items-center gap-2 mb-4">
              <input type="date" value={teamDateFrom} onChange={(e) => setTeamDateFrom(e.target.value)} className="text-xs rounded-lg px-2 py-1.5 outline-none" style={{ border: `1px solid ${COLORS.line}` }} />
              <span className="text-xs" style={{ color: COLORS.muted }}>to</span>
              <input type="date" value={teamDateTo} onChange={(e) => setTeamDateTo(e.target.value)} className="text-xs rounded-lg px-2 py-1.5 outline-none" style={{ border: `1px solid ${COLORS.line}` }} />
            </div>

            <div className="space-y-3">
              {teamStats.length === 0 && (
                <div className="text-sm text-center py-6" style={{ color: COLORS.muted }}>No entries in this date range.</div>
              )}
              {teamStats.map((s) => {
                const isExpanded = expandedTeamId === s.id;
                return (
                  <div key={s.id} className="rounded-xl overflow-hidden" style={{ background: COLORS.paperDeep }}>
                    <button onClick={() => setExpandedTeamId((cur) => (cur === s.id ? null : s.id))} className="w-full text-left p-4">
                      <div className="flex items-center gap-2 mb-2">
                        {isExpanded ? <ChevronDown size={14} color={COLORS.teal700} /> : <ChevronRight size={14} color={COLORS.teal700} />}
                        <div className="font-semibold text-sm" style={{ color: COLORS.ink }}>{s.name}</div>
                      </div>
                      <div className="grid grid-cols-2 sm:grid-cols-5 gap-2 text-xs">
                        <div><div style={{ color: COLORS.muted }}>Entries</div><div className="font-semibold" style={{ color: COLORS.ink }}>{s.entries}</div></div>
                        <div><div style={{ color: COLORS.muted }}>Bottles</div><div className="font-semibold" style={{ color: COLORS.ink }}>{s.bottles}</div></div>
                        <div><div style={{ color: COLORS.muted }}>Customers</div><div className="font-semibold" style={{ color: COLORS.ink }}>{s.customers}</div></div>
                        <div><div style={{ color: COLORS.muted }}>Collected</div><div className="font-semibold" style={{ color: COLORS.teal700 }}>{money(s.paid)}</div></div>
                        <div><div style={{ color: COLORS.muted }}>Must collect</div><div className="font-semibold" style={{ color: s.outstanding > 0 ? COLORS.danger : COLORS.teal700 }}>{s.outstanding > 0 ? money(s.outstanding) : "Settled"}</div></div>
                      </div>
                    </button>
                    {isExpanded && (
                      <div className="px-4 pb-4 overflow-x-auto">
                        <table className="w-full text-xs" style={{ minWidth: 420 }}>
                          <thead>
                            <tr style={{ borderBottom: `1px solid ${COLORS.line}` }}>
                              {["Date", "Customer", "Bottles", "Charged", "Paid", "Method"].map((h) => (
                                <th key={h} className="text-left py-1.5 font-bold uppercase" style={{ color: COLORS.teal700 }}>{h}</th>
                              ))}
                            </tr>
                          </thead>
                          <tbody>
                            {s.items.map((tx) => (
                              <tr key={tx.id} style={{ borderBottom: `1px solid ${COLORS.line}` }}>
                                <td className="py-1.5" style={{ color: COLORS.ink }}>{fmtDate(tx.date)}</td>
                                <td className="py-1.5" style={{ color: COLORS.ink }}>{(customerById[tx.customer_id] && customerById[tx.customer_id].name) || "—"}</td>
                                <td className="py-1.5" style={{ color: COLORS.ink }}>{tx.bottles}</td>
                                <td className="py-1.5" style={{ color: COLORS.ink }}>{money(tx.bottles * tx.rate)}</td>
                                <td className="py-1.5" style={{ color: COLORS.ink }}>{money(tx.paid)}</td>
                                <td className="py-1.5" style={{ color: COLORS.muted }}>{tx.payment_method || "Cash"}</td>
                              </tr>
                            ))}
                          </tbody>
                        </table>
                      </div>
                    )}
                  </div>
                );
              })}
            </div>
            <div className="flex gap-2 mt-5 no-print">
              <button onClick={printTeamPerformance} className="flex-1 py-2.5 rounded-full text-sm font-semibold" style={{ border: `1.5px solid ${COLORS.teal700}`, color: COLORS.teal700, background: "white" }}>
                Print
              </button>
              <button onClick={() => setShowTeamModal(false)} className="flex-1 py-2.5 rounded-full text-sm font-semibold text-white" style={{ background: COLORS.teal700 }}>
                Done
              </button>
            </div>
          </div>
        </div>
      )}

      <main className="max-w-5xl mx-auto px-5 sm:px-10 py-8 space-y-6">
        {role === "owner" ? (
          <>
            {errorMsg && (
              <div className="rounded-xl px-4 py-3 text-sm flex items-center gap-2" style={{ background: "#FBEAEA", color: COLORS.danger }}>
                <AlertCircle size={15} /> {errorMsg}
              </div>
            )}

            <div className="flex items-center justify-between flex-wrap gap-2">
              <h2 className="text-xs font-bold uppercase tracking-wide" style={{ color: COLORS.teal700 }}>Business overview</h2>
              <div className="flex items-center gap-2">
                <select
                  value={ownerPeriod}
                  onChange={(e) => setOwnerPeriod(e.target.value)}
                  className="text-sm rounded-full px-3 py-1.5 outline-none"
                  style={{ border: `1px solid ${COLORS.line}`, color: COLORS.ink, background: "white" }}
                >
                  <option value="current">Current (not yet closed)</option>
                  {closedPeriodLabels.map((label) => <option key={label} value={label}>{label}</option>)}
                </select>
                <button onClick={printOwnerDashboard} className="no-print px-4 py-1.5 rounded-full text-xs font-semibold" style={{ border: `1.5px solid ${COLORS.teal700}`, color: COLORS.teal700, background: "white" }}>
                  Print
                </button>
              </div>
            </div>

            <div className={(!showTeamModal && !customerDetail && !showManageTeam && !showReportModal ? "print-area " : "") + "space-y-6"}>

            <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
              {[
                { label: "Bottles", value: ownerStats.bottles },
                { label: "Collected", value: money(ownerStats.paid) },
                { label: "Outstanding", value: money(ownerStats.balance), accent: ownerStats.balance > 0 },
                { label: ownerPeriod === "current" ? "Expenses (this month)" : `Expenses (${ownerPeriod})`, value: money(ownerPeriodExpenseTotal) },
              ].map((s) => (
                <div key={s.label} className="rounded-2xl p-4" style={{ background: s.accent ? COLORS.teal900 : "white", border: `1px solid ${COLORS.line}` }}>
                  <div className="text-[11px] uppercase tracking-wide font-bold mb-1" style={{ color: s.accent ? COLORS.aqua300 : COLORS.teal700 }}>{s.label}</div>
                  <div className="text-lg font-semibold" style={{ color: s.accent ? "white" : COLORS.ink, ...fraunces }}>{s.value}</div>
                </div>
              ))}
            </div>

            <div className="flex items-center justify-between text-sm rounded-2xl px-4 py-3" style={{ background: COLORS.teal900 }}>
              <span style={{ color: COLORS.aqua300 }}>Net cash this period (collected − expenses)</span>
              <span className="font-semibold" style={{ color: "white" }}>{money(ownerStats.paid - ownerPeriodExpenseTotal)}</span>
            </div>

            <div className="rounded-2xl p-4 sm:p-5" style={{ background: "white", border: `1px solid ${COLORS.line}` }}>
              <div className="text-xs font-bold uppercase tracking-wide mb-3" style={{ color: COLORS.teal700 }}>Cash flow by type</div>
              {Object.keys(ownerStats.byPayment).length === 0 ? (
                <div className="text-sm" style={{ color: COLORS.muted }}>No entries in this period.</div>
              ) : (
                <div className="space-y-2">
                  {Object.entries(ownerStats.byPayment).map(([method, amount]) => (
                    <div key={method} className="flex justify-between text-sm" style={{ color: COLORS.ink }}>
                      <span>{method}</span>
                      <span className="font-semibold">{money(amount)}</span>
                    </div>
                  ))}
                </div>
              )}
            </div>

            <div className="rounded-2xl p-4 sm:p-5" style={{ background: "white", border: `1px solid ${COLORS.line}` }}>
              <div className="text-xs font-bold uppercase tracking-wide mb-3" style={{ color: COLORS.teal700 }}>Bottles &amp; cash by area</div>
              {Object.keys(ownerStats.byArea).length === 0 ? (
                <div className="text-sm" style={{ color: COLORS.muted }}>No entries in this period.</div>
              ) : (
                <div className="overflow-x-auto">
                  <table className="w-full text-sm" style={{ minWidth: 420 }}>
                    <thead>
                      <tr style={{ borderBottom: `1px solid ${COLORS.line}` }}>
                        {["Area", "Bottles", "Charged", "Collected"].map((h) => (
                          <th key={h} className="text-left py-1.5 text-[11px] font-bold uppercase" style={{ color: COLORS.muted }}>{h}</th>
                        ))}
                      </tr>
                    </thead>
                    <tbody>
                      {Object.entries(ownerStats.byArea).sort((a, b) => b[1].bottles - a[1].bottles).map(([area, agg]) => (
                        <tr key={area} style={{ borderBottom: `1px solid ${COLORS.paperDeep}` }}>
                          <td className="py-1.5" style={{ color: COLORS.ink }}>{area}</td>
                          <td className="py-1.5" style={{ color: COLORS.ink }}>{agg.bottles}</td>
                          <td className="py-1.5" style={{ color: COLORS.ink }}>{money(agg.charged)}</td>
                          <td className="py-1.5" style={{ color: COLORS.ink }}>{money(agg.paid)}</td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </div>

            <div className="flex justify-end gap-2 no-print">
              <button
                onClick={() => setShowManageTeam(true)}
                className="px-5 py-2.5 rounded-full text-sm font-semibold flex items-center gap-2"
                style={{ border: `1.5px solid ${COLORS.teal700}`, color: COLORS.teal700, background: "white" }}
              >
                <Users size={15} /> Manage team
              </button>
              <button
                onClick={() => setShowTeamModal(true)}
                className="px-5 py-2.5 rounded-full text-sm font-semibold flex items-center gap-2"
                style={{ border: `1.5px solid ${COLORS.teal700}`, color: COLORS.teal700, background: "white" }}
              >
                <TrendingUp size={15} /> Team performance
              </button>
            </div>

            <div className="rounded-2xl overflow-hidden" style={{ border: `1px solid ${COLORS.line}` }}>
              <div className="px-4 sm:px-5 py-3 flex items-center justify-between flex-wrap gap-2" style={{ background: COLORS.teal900 }}>
                <div className="text-xs font-bold uppercase tracking-wide" style={{ color: "white" }}>Customers — lifetime overview</div>
                <input
                  value={customerSearch}
                  onChange={(e) => setCustomerSearch(e.target.value)}
                  onKeyDown={(e) => e.key === "Enter" && e.target.blur()}
                  placeholder="Search by name…"
                  className="no-print text-sm rounded-full px-3 py-1.5 outline-none w-40"
                  style={{ border: "none", color: COLORS.ink, background: "white" }}
                />
              </div>
              <div className="overflow-x-auto">
                <table className="w-full text-sm" style={{ minWidth: 480 }}>
                  <thead>
                    <tr style={{ borderBottom: `1px solid ${COLORS.line}` }}>
                      {["Customer", "Area", "Lifetime bottles", "With customer", "Deposit held", "Lifetime collected", "Balance"].map((h) => (
                        <th key={h} className="text-left px-4 py-2 text-[11px] font-bold uppercase" style={{ color: COLORS.teal700 }}>{h}</th>
                      ))}
                    </tr>
                  </thead>
                  <tbody>
                    {customerLifetime.filter((c) => !customerSearch.trim() || c.name.toLowerCase().includes(customerSearch.trim().toLowerCase())).map((c, i) => (
                      <tr key={c.id} style={{ background: i % 2 === 0 ? "white" : COLORS.paperDeep }}>
                        <td className="px-4 py-2 font-semibold">
                          <button onClick={() => { setCustomerDetail(c); setCustomerDetailPeriod("current"); }} style={{ color: COLORS.teal700, textDecoration: "underline" }}>
                            {c.name}
                          </button>
                        </td>
                        <td className="px-4 py-2" style={{ color: COLORS.muted }}>{c.area || "—"}</td>
                        <td className="px-4 py-2" style={{ color: COLORS.ink }}>{c.lifetimeBottles}</td>
                        <td className="px-4 py-2" style={{ color: c.bottlesOutstanding > 0 ? COLORS.danger : COLORS.muted }}>{c.bottlesOutstanding}</td>
                        <td className="px-4 py-2" style={{ color: COLORS.muted }}>{Number(c.security_deposit) > 0 ? money(c.security_deposit) : "—"}</td>
                        <td className="px-4 py-2" style={{ color: COLORS.ink }}>{money(c.lifetimePaid)}</td>
                        <td className="px-4 py-2 font-semibold" style={{ color: c.balance > 0 ? COLORS.danger : COLORS.teal700 }}>{c.balance > 0 ? money(c.balance) : "Settled"}</td>
                      </tr>
                    ))}
                    {customerLifetime.length === 0 && (
                      <tr><td colSpan={7} className="px-4 py-8 text-center" style={{ color: COLORS.muted }}>No customers yet.</td></tr>
                    )}
                  </tbody>
                </table>
              </div>
            </div>
            </div>
          </>
        ) : (
          <>
        {errorMsg && (
          <div className="rounded-xl px-4 py-3 text-sm flex items-center gap-2" style={{ background: "#FBEAEA", color: COLORS.danger }}>
            <AlertCircle size={15} /> {errorMsg}
          </div>
        )}

        <div className="rounded-2xl p-4 sm:p-5 flex flex-col sm:flex-row gap-3 sm:items-end" style={{ background: "white", border: `1px solid ${COLORS.line}` }}>
          <div className="flex-1">
            <label className="text-xs font-medium block mb-1.5" style={{ color: COLORS.muted }}>New customer name</label>
            <input
              value={newName}
              onChange={(e) => setNewName(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && addCustomer()}
              placeholder="e.g. Sara Khan"
              className="w-full text-sm rounded-xl px-3 py-2.5 outline-none"
              style={{ border: `1px solid ${COLORS.line}`, color: COLORS.ink }}
            />
          </div>
          <div>
            <label className="text-xs font-medium block mb-1.5" style={{ color: COLORS.muted }}>Area</label>
            <select value={newArea} onChange={(e) => setNewArea(e.target.value)} className="text-sm rounded-xl px-3 py-2.5 outline-none" style={{ border: `1px solid ${COLORS.line}`, color: COLORS.ink, background: "white" }}>
              {AREAS.map((a) => <option key={a} value={a}>{a}</option>)}
            </select>
          </div>
          <div>
            <label className="text-xs font-medium block mb-1.5" style={{ color: COLORS.muted }}>Security deposit (PKR)</label>
            <input
              type="number"
              value={newDeposit}
              onChange={(e) => setNewDeposit(e.target.value)}
              placeholder="e.g. 1200"
              className="w-28 text-sm rounded-xl px-3 py-2.5 outline-none"
              style={{ border: `1px solid ${COLORS.line}`, color: COLORS.ink }}
            />
          </div>
          <div>
            <label className="text-xs font-medium block mb-1.5" style={{ color: COLORS.muted }}>Bottles already with them</label>
            <input
              type="number"
              value={newOpeningBottles}
              onChange={(e) => setNewOpeningBottles(e.target.value)}
              placeholder="e.g. 3"
              className="w-24 text-sm rounded-xl px-3 py-2.5 outline-none"
              style={{ border: `1px solid ${COLORS.line}`, color: COLORS.ink }}
            />
          </div>
          <div>
            <label className="text-xs font-medium block mb-1.5" style={{ color: COLORS.muted }}>Dispensers</label>
            <input
              type="number"
              min="0"
              value={newDispenserCount}
              onChange={(e) => setNewDispenserCount(e.target.value)}
              placeholder="e.g. 1"
              className="w-20 text-sm rounded-xl px-3 py-2.5 outline-none"
              style={{ border: `1px solid ${COLORS.line}`, color: COLORS.ink }}
            />
          </div>
          <div className="text-xs" style={{ color: COLORS.muted }}>Serial #{nextSerial}</div>
          <button onClick={addCustomer} disabled={savingAction} className="px-5 py-2.5 rounded-full text-sm font-semibold text-white flex items-center justify-center gap-1.5" style={{ background: COLORS.teal700, opacity: savingAction ? 0.6 : 1 }}>
            <Plus size={15} /> Add customer
          </button>
        </div>

        <div className="rounded-2xl p-4 sm:p-5" style={{ background: "white", border: `1px solid ${COLORS.line}` }}>
          <button onClick={() => setShowBulkAdd((s) => !s)} className="text-xs font-semibold" style={{ color: COLORS.teal700 }}>
            {showBulkAdd ? "− Hide" : "+ Add multiple customers at once"}
          </button>
          {showBulkAdd && (
            <div className="mt-3 space-y-3">
              <p className="text-xs" style={{ color: COLORS.muted }}>
                Paste one customer per line, as <strong>Name, Area, Deposit (optional)</strong>. If you leave out the area, the default below is used. Deposit defaults to 0 if left out.
                <br />Example: <em>Sara Khan, Bani Gala, Islamabad</em>
              </p>
              <textarea
                value={bulkText}
                onChange={(e) => setBulkText(e.target.value)}
                rows={6}
                placeholder={"Sara Khan, Bani Gala, Islamabad\nAli Raza, F-8, Islamabad\nUmair Traders"}
                className="w-full text-sm rounded-xl px-3 py-2.5 outline-none"
                style={{ border: `1px solid ${COLORS.line}`, color: COLORS.ink, fontFamily: "monospace" }}
              />
              <div className="flex flex-wrap items-end gap-3">
                <div>
                  <label className="text-xs font-medium block mb-1.5" style={{ color: COLORS.muted }}>Default area (if not given per line)</label>
                  <select value={bulkDefaultArea} onChange={(e) => setBulkDefaultArea(e.target.value)} className="text-sm rounded-xl px-3 py-2.5 outline-none" style={{ border: `1px solid ${COLORS.line}`, color: COLORS.ink, background: "white" }}>
                    {AREAS.map((a) => <option key={a} value={a}>{a}</option>)}
                  </select>
                </div>
                <button onClick={addCustomersBulk} disabled={savingAction || !bulkText.trim()} className="px-5 py-2.5 rounded-full text-sm font-semibold text-white" style={{ background: COLORS.teal700, opacity: savingAction || !bulkText.trim() ? 0.6 : 1 }}>
                  Add all
                </button>
                {bulkResult && <span className="text-xs" style={{ color: COLORS.teal700 }}>{bulkResult}</span>}
              </div>
            </div>
          )}
        </div>

        <div className="grid grid-cols-2 sm:grid-cols-3 gap-3">
          {[
            { label: "Customers", value: customers.length },
            { label: "Bottles this period", value: grandTotals.bottles },
            { label: "Balance outstanding", value: money(grandTotals.balance), accent: grandTotals.balance > 0 },
          ].map((s) => (
            <div key={s.label} className="rounded-2xl p-4" style={{ background: s.accent ? COLORS.teal900 : "white", border: `1px solid ${COLORS.line}` }}>
              <div className="text-[11px] uppercase tracking-wide font-bold mb-1" style={{ color: s.accent ? COLORS.aqua300 : COLORS.teal700 }}>{s.label}</div>
              <div className="text-lg font-semibold" style={{ color: s.accent ? "white" : COLORS.ink, ...fraunces }}>{s.value}</div>
            </div>
          ))}
          {role === "admin" && (
            <div className="rounded-2xl p-4" style={{ background: "white", border: `1px solid ${COLORS.line}` }}>
              <div className="text-[11px] uppercase tracking-wide font-bold mb-1" style={{ color: COLORS.teal700 }}>Total expenses</div>
              <div className="text-lg font-semibold" style={{ color: COLORS.ink, ...fraunces }}>{money(expenseTotals)}</div>
            </div>
          )}
        </div>

        <div className="rounded-2xl p-4 sm:p-5" style={{ background: COLORS.teal900 }}>
          <div className="text-xs font-bold uppercase tracking-wide mb-3" style={{ color: COLORS.aqua300 }}>Today</div>
          <div className="grid grid-cols-2 sm:grid-cols-3 gap-3 mb-3">
            <div>
              <div className="text-[11px]" style={{ color: COLORS.aqua300 }}>Bottles today</div>
              <div className="text-lg font-semibold text-white" style={{ ...fraunces }}>{todaysSummary.bottles}</div>
            </div>
            <div>
              <div className="text-[11px]" style={{ color: COLORS.aqua300 }}>Cash in hand</div>
              <div className="text-lg font-semibold text-white" style={{ ...fraunces }}>{money(todaysSummary.cashCollected)}</div>
            </div>
            <div>
              <div className="text-[11px]" style={{ color: COLORS.aqua300 }}>Easypaisa/Bank</div>
              <div className="text-lg font-semibold text-white" style={{ ...fraunces }}>{money(todaysSummary.otherCollected)}</div>
            </div>
          </div>
          <div className="flex items-center justify-between rounded-xl px-3 py-2 mb-2" style={{ background: "rgba(255,255,255,0.08)" }}>
            <span className="text-xs" style={{ color: COLORS.aqua300 }}>Expenses today</span>
            <span className="text-sm font-semibold text-white">− {money(todaysSummary.expenses)}</span>
          </div>
          <div className="flex items-center justify-between rounded-xl px-3 py-2.5" style={{ background: COLORS.gold500 }}>
            <span className="text-xs font-semibold" style={{ color: COLORS.teal900 }}>Net cash in hand today</span>
            <span className="text-base font-bold" style={{ color: COLORS.teal900, ...fraunces }}>{money(todaysSummary.net)}</span>
          </div>
          <div className="text-[10px] mt-2" style={{ color: COLORS.aqua300, opacity: 0.8 }}>
            Easypaisa/JazzCash and Bank Transfer aren't physical cash, so they're not subtracted here — expenses only come out of actual cash in hand.
          </div>
        </div>

        <div className="rounded-2xl p-4 sm:p-5" style={{ background: "white", border: `1px solid ${COLORS.line}` }}>
          <div className="text-xs font-bold uppercase tracking-wide mb-3" style={{ color: COLORS.teal700 }}>Cash flow by type (this period)</div>
          <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
            {PAYMENT_METHODS.map((m) => (
              <div key={m} className="rounded-xl p-3" style={{ background: COLORS.paperDeep }}>
                <div className="text-[11px] font-semibold mb-1" style={{ color: COLORS.muted }}>{m}</div>
                <div className="text-base font-semibold" style={{ color: m === "Credit" ? COLORS.danger : COLORS.ink, ...fraunces }}>
                  {money(m === "Credit" ? paymentBreakdown[m].charged : paymentBreakdown[m].paid)}
                </div>
                {m === "Credit" && <div className="text-[10px] mt-0.5" style={{ color: COLORS.muted }}>given on credit</div>}
              </div>
            ))}
          </div>
        </div>

        {role === "admin" && (
          <div className="flex justify-end gap-2 flex-wrap">
            <button
              onClick={() => setShowManageTeam(true)}
              className="px-5 py-2.5 rounded-full text-sm font-semibold flex items-center gap-2"
              style={{ border: `1.5px solid ${COLORS.teal700}`, color: COLORS.teal700, background: "white" }}
            >
              <Users size={15} /> Manage team
            </button>
            <button
              onClick={() => setShowTeamModal(true)}
              className="px-5 py-2.5 rounded-full text-sm font-semibold flex items-center gap-2"
              style={{ border: `1.5px solid ${COLORS.teal700}`, color: COLORS.teal700, background: "white" }}
            >
              <TrendingUp size={15} /> Team performance
            </button>
            <button
              onClick={exportBackup}
              className="px-5 py-2.5 rounded-full text-sm font-semibold flex items-center gap-2"
              style={{ border: `1.5px solid ${COLORS.teal700}`, color: COLORS.teal700, background: "white" }}
            >
              Download backup
            </button>
            <button
              onClick={() => setShowCloseMonthConfirm(true)}
              className="px-5 py-2.5 rounded-full text-sm font-semibold flex items-center gap-2"
              style={{ background: COLORS.gold500, color: COLORS.teal900 }}
            >
              <FileBarChart size={15} /> Close month &amp; generate report
            </button>
          </div>
        )}

        {/* Expenses */}
        <div className="rounded-2xl p-4 sm:p-5" style={{ background: "white", border: `1px solid ${COLORS.line}` }}>
          <button onClick={() => setShowExpenseForm((s) => !s)} className="text-xs font-semibold flex items-center gap-1.5" style={{ color: COLORS.teal700 }}>
            <Wallet size={14} /> {showExpenseForm ? "− Hide expense form" : "+ Log an expense (petrol, food, etc.)"}
          </button>
          {showExpenseForm && (
            <div className="mt-3 flex flex-wrap items-end gap-3">
              <div>
                <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Date</label>
                <input type="date" value={expenseDate} onChange={(e) => setExpenseDate(e.target.value)} className="text-sm rounded-lg px-2.5 py-2 outline-none" style={{ border: `1px solid ${COLORS.line}` }} />
              </div>
              <div>
                <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Category</label>
                <select value={expenseCategory} onChange={(e) => setExpenseCategory(e.target.value)} className="text-sm rounded-lg px-2.5 py-2 outline-none" style={{ border: `1px solid ${COLORS.line}`, background: "white" }}>
                  {EXPENSE_CATEGORIES.map((cat) => <option key={cat} value={cat}>{cat}</option>)}
                </select>
              </div>
              <div>
                <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Amount (PKR)</label>
                <input type="number" value={expenseAmount} onChange={(e) => setExpenseAmount(e.target.value)} className="w-28 text-sm rounded-lg px-2.5 py-2 outline-none" style={{ border: `1px solid ${COLORS.line}` }} />
              </div>
              <div className="flex-1 min-w-[140px]">
                <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Note (optional)</label>
                <input value={expenseNote} onChange={(e) => setExpenseNote(e.target.value)} placeholder="e.g. Bahria Enclave route" className="w-full text-sm rounded-lg px-2.5 py-2 outline-none" style={{ border: `1px solid ${COLORS.line}` }} />
              </div>
              <button onClick={addExpense} disabled={savingAction} className="px-4 py-2 rounded-full text-xs font-semibold text-white" style={{ background: COLORS.teal700, opacity: savingAction ? 0.6 : 1 }}>
                Save expense
              </button>
            </div>
          )}

          {role === "admin" && expenses.length > 0 && (
            <div className="overflow-x-auto mt-4">
              <table className="w-full text-sm" style={{ minWidth: 480 }}>
                <thead>
                  <tr style={{ borderBottom: `1px solid ${COLORS.line}` }}>
                    {["Date", "Category", "Amount", "Note", "Added by", ""].map((h) => (
                      <th key={h} className="text-left py-2 text-xs font-bold uppercase tracking-wide" style={{ color: COLORS.teal700 }}>{h}</th>
                    ))}
                  </tr>
                </thead>
                <tbody>
                  {expenses.map((e) => (
                    <tr key={e.id} style={{ borderBottom: `1px solid ${COLORS.paperDeep}` }}>
                      <td className="py-2" style={{ color: COLORS.ink }}>{fmtDate(e.date)}</td>
                      <td className="py-2" style={{ color: COLORS.ink }}>{e.category}</td>
                      <td className="py-2" style={{ color: COLORS.ink }}>{money(e.amount)}</td>
                      <td className="py-2" style={{ color: COLORS.muted }}>{e.note || "—"}</td>
                      <td className="py-2" style={{ color: COLORS.muted }}>{profileNameById[e.created_by] || "—"}</td>
                      <td className="py-2">
                        <button onClick={() => setConfirmDeleteExpense(e)} aria-label="Remove expense"><X size={13} color={COLORS.muted} /></button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>

        <div className="flex items-center justify-between flex-wrap gap-2">
          <h2 className="text-xs font-bold uppercase tracking-wide" style={{ color: COLORS.teal700 }}>Customers</h2>
          <div className="flex items-center gap-2 flex-wrap">
            <input
              value={customerSearch}
              onChange={(e) => setCustomerSearch(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && e.target.blur()}
              placeholder="Search by name…"
              className="text-sm rounded-full px-3 py-1.5 outline-none w-40"
              style={{ border: `1px solid ${COLORS.line}`, color: COLORS.ink, background: "white" }}
            />
            <label className="text-xs font-medium" style={{ color: COLORS.muted }}>Filter by area</label>
            <select value={areaFilter} onChange={(e) => setAreaFilter(e.target.value)} className="text-sm rounded-full px-3 py-1.5 outline-none" style={{ border: `1px solid ${COLORS.line}`, color: COLORS.ink, background: "white" }}>
              <option value="all">All areas</option>
              {usedAreas.map((a) => <option key={a} value={a}>{a}</option>)}
            </select>
          </div>
        </div>
        {customerSearch.trim() && (
          <div className="text-xs -mt-3" style={{ color: COLORS.muted }}>
            {groupedCustomers.reduce((n, g) => n + g.customers.length, 0)} match{groupedCustomers.reduce((n, g) => n + g.customers.length, 0) === 1 ? "" : "es"} for "{customerSearch.trim()}"
          </div>
        )}

        <div className="space-y-3">
          {groupedCustomers.map((group) => (
            <div key={group.area}>
              {areaFilter === "all" && (
                <div className="text-xs font-bold uppercase tracking-wide mb-2 mt-4" style={{ color: COLORS.teal700 }}>
                  {group.area} <span className="font-normal normal-case" style={{ color: COLORS.muted }}>({group.customers.length})</span>
                </div>
              )}
              <div className="space-y-3">
                {group.customers.map((c) => {
                  const openTx = currentTxByCustomer[c.id] || [];
                  const t = periodTotals(openTx);
                  const balance = Number(c.carried_balance) + t.charged - t.paid;
                  const isOpen = expanded === c.id;
                  const isHistoryOpen = historyOpenFor === c.id;
                  const history = historyByCustomer[c.id] || [];
                  const lifetime = lifetimeByCustomer[c.id] || { bottles: 0, paid: 0, returned: 0 };
                  const bottlesOutstanding = Number(c.opening_bottles || 0) + lifetime.bottles - lifetime.returned;

                  return (
                    <div key={c.id} className="rounded-2xl overflow-hidden" style={{ border: `1px solid ${COLORS.line}`, background: "white" }}>
                      <button onClick={() => toggleExpand(c.id)} className="w-full flex items-center justify-between px-4 sm:px-5 py-4 text-left">
                        <div className="flex items-center gap-3">
                          {isOpen ? <ChevronDown size={16} color={COLORS.teal700} /> : <ChevronRight size={16} color={COLORS.teal700} />}
                          <div>
                            <div className="font-semibold text-sm" style={{ color: COLORS.ink }}>#{c.serial} · {c.name}</div>
                            <div className="text-xs" style={{ color: COLORS.muted }}>
                              {c.area && <span>{c.area} · </span>}
                              {t.bottles} bottles this period
                              {Number(c.carried_balance) > 0 && <span> · {money(c.carried_balance)} carried in</span>}
                              {history.length > 0 && <span> · {history.length} past period{history.length > 1 ? "s" : ""}</span>}
                            </div>
                            <div className="text-[11px] mt-0.5 font-medium" style={{ color: COLORS.teal700 }}>
                              Lifetime: {lifetime.bottles} bottles · {money(lifetime.paid)} collected
                            </div>
                            <div className="text-[11px] mt-0.5" style={{ color: bottlesOutstanding > 0 ? COLORS.danger : COLORS.muted }}>
                              {bottlesOutstanding > 0 ? `${bottlesOutstanding} bottles with customer (not returned)` : "All bottles returned"}
                              {Number(c.security_deposit) > 0 && <span> · Deposit held: {money(c.security_deposit)}</span>}
                              {Number(c.dispenser_count) > 0 && <span> · Dispensers: {c.dispenser_count}</span>}
                            </div>
                          </div>
                        </div>
                        <div className="flex items-center gap-4">
                          <div className="text-right">
                            <div className="text-sm font-semibold" style={{ color: balance > 0 ? COLORS.danger : COLORS.teal700 }}>
                              {balance > 0 ? money(balance) : "Settled"}
                            </div>
                            <div className="text-[11px]" style={{ color: COLORS.muted }}>current balance</div>
                          </div>
                          <Printer size={14} color={COLORS.teal700} onClick={(e) => { e.stopPropagation(); setCustomerDetail(c); setCustomerDetailPeriod("current"); }} />
                          {(role === "admin" || (role === "sales" && c.created_by === authState.userId)) && (
                            <Pencil size={14} color={COLORS.teal700} onClick={(e) => { e.stopPropagation(); if (!isOpen) toggleExpand(c.id); startEditCustomer(c); }} />
                          )}
                          {role === "admin" && (
                            <Trash2 size={15} color={COLORS.muted} onClick={(e) => { e.stopPropagation(); setConfirmDeleteCustomer(c); }} />
                          )}
                        </div>
                      </button>

                      {isOpen && role !== "admin" && (
                        <div className="px-4 sm:px-5 pb-2 pt-2 text-xs" style={{ borderTop: `1px solid ${COLORS.line}`, color: COLORS.muted }}>
                          Viewing as Salesperson — you can add new entries, but editing, deleting, and closing periods are admin-only.
                        </div>
                      )}

                      {isOpen && (
                        <div className="px-4 sm:px-5 pb-5" style={{ borderTop: `1px solid ${COLORS.line}` }}>
                          {editingCustomerId === c.id && (
                            <div className="mt-4 mb-4 rounded-xl p-4" style={{ background: COLORS.paperDeep }}>
                              <div className="text-xs font-bold uppercase tracking-wide mb-3" style={{ color: COLORS.teal700 }}>Edit customer</div>
                              <div className="flex flex-wrap items-end gap-3">
                                <div>
                                  <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Name</label>
                                  <input
                                    value={editCustomerDraft.name}
                                    onChange={(e) => setEditCustomerDraft((d) => ({ ...d, name: e.target.value }))}
                                    className="text-sm rounded-lg px-2.5 py-2 outline-none"
                                    style={{ border: `1px solid ${COLORS.line}` }}
                                  />
                                </div>
                                <div>
                                  <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Area</label>
                                  <select
                                    value={editCustomerDraft.area}
                                    onChange={(e) => setEditCustomerDraft((d) => ({ ...d, area: e.target.value }))}
                                    className="text-sm rounded-lg px-2.5 py-2 outline-none"
                                    style={{ border: `1px solid ${COLORS.line}`, background: "white" }}
                                  >
                                    {AREAS.map((a) => <option key={a} value={a}>{a}</option>)}
                                  </select>
                                </div>
                                <div>
                                  <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Security deposit (PKR)</label>
                                  <input
                                    type="number"
                                    value={editCustomerDraft.deposit}
                                    onChange={(e) => setEditCustomerDraft((d) => ({ ...d, deposit: e.target.value }))}
                                    className="w-28 text-sm rounded-lg px-2.5 py-2 outline-none"
                                    style={{ border: `1px solid ${COLORS.line}` }}
                                  />
                                </div>
                                <div>
                                  <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Bottles already with them</label>
                                  <input
                                    type="number"
                                    value={editCustomerDraft.openingBottles}
                                    onChange={(e) => setEditCustomerDraft((d) => ({ ...d, openingBottles: e.target.value }))}
                                    className="w-24 text-sm rounded-lg px-2.5 py-2 outline-none"
                                    style={{ border: `1px solid ${COLORS.line}` }}
                                  />
                                </div>
                                <div>
                                  <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Dispensers</label>
                                  <input
                                    type="number"
                                    min="0"
                                    value={editCustomerDraft.dispenserCount}
                                    onChange={(e) => setEditCustomerDraft((d) => ({ ...d, dispenserCount: e.target.value }))}
                                    className="w-20 text-sm rounded-lg px-2.5 py-2 outline-none"
                                    style={{ border: `1px solid ${COLORS.line}` }}
                                  />
                                </div>
                                <button onClick={() => saveEditCustomer(c.id)} disabled={savingAction} className="px-4 py-2 rounded-full text-xs font-semibold text-white" style={{ background: COLORS.teal700, opacity: savingAction ? 0.6 : 1 }}>
                                  Save
                                </button>
                                <button onClick={cancelEditCustomer} className="px-4 py-2 rounded-full text-xs font-semibold" style={{ border: `1.5px solid ${COLORS.line}`, color: COLORS.ink }}>
                                  Cancel
                                </button>
                              </div>
                            </div>
                          )}
                          {Number(c.carried_balance) > 0 && (
                            <div className="mt-4 mb-3 text-xs rounded-lg px-3 py-2" style={{ background: "#FBF0E4", color: COLORS.danger }}>
                              Opening balance carried from last period: {money(c.carried_balance)}
                            </div>
                          )}

                          {openTx.length > 0 && (
                            <div className="overflow-x-auto mt-2 mb-4">
                              <table className="w-full text-sm" style={{ minWidth: 480 }}>
                                <thead>
                                  <tr style={{ borderBottom: `1px solid ${COLORS.line}` }}>
                                    {["Date", "Bottles", "Returned", "Rate", "Charged", "Paid", "Method", ""].map((h) => (
                                      <th key={h} className="text-left py-2 text-xs font-bold uppercase tracking-wide" style={{ color: COLORS.teal700 }}>{h}</th>
                                    ))}
                                  </tr>
                                </thead>
                                <tbody>
                                  {[...openTx].sort((a, b) => a.date.localeCompare(b.date)).map((tx) => {
                                    const isEditing = editingTxId === tx.id;
                                    if (isEditing) {
                                      return (
                                        <tr key={tx.id} style={{ borderBottom: `1px solid ${COLORS.paperDeep}`, background: COLORS.paperDeep }}>
                                          <td className="py-2 pr-2"><input type="date" value={editDraft.date} onChange={(e) => setEditDraft((d) => ({ ...d, date: e.target.value }))} className="text-xs rounded-lg px-2 py-1.5 outline-none w-full" style={{ border: `1px solid ${COLORS.line}` }} /></td>
                                          <td className="py-2 pr-2"><input type="number" value={editDraft.bottles} onChange={(e) => setEditDraft((d) => ({ ...d, bottles: e.target.value }))} className="text-xs rounded-lg px-2 py-1.5 outline-none w-16" style={{ border: `1px solid ${COLORS.line}` }} /></td>
                                          <td className="py-2 pr-2"><input type="number" value={editDraft.bottlesReturned} onChange={(e) => setEditDraft((d) => ({ ...d, bottlesReturned: e.target.value }))} className="text-xs rounded-lg px-2 py-1.5 outline-none w-16" style={{ border: `1px solid ${COLORS.line}` }} /></td>
                                          <td className="py-2 pr-2"><input type="number" value={editDraft.rate} onChange={(e) => setEditDraft((d) => ({ ...d, rate: e.target.value }))} className="text-xs rounded-lg px-2 py-1.5 outline-none w-16" style={{ border: `1px solid ${COLORS.line}` }} /></td>
                                          <td className="py-2 pr-2 text-xs" style={{ color: COLORS.muted }}>{money((parseFloat(editDraft.bottles) || 0) * (parseFloat(editDraft.rate) || 0))}</td>
                                          <td className="py-2 pr-2"><input type="number" value={editDraft.paid} onChange={(e) => setEditDraft((d) => ({ ...d, paid: e.target.value }))} className="text-xs rounded-lg px-2 py-1.5 outline-none w-20" style={{ border: `1px solid ${COLORS.line}` }} /></td>
                                          <td className="py-2 pr-2">
                                            <select value={editDraft.paymentMethod} onChange={(e) => setEditDraft((d) => ({ ...d, paymentMethod: e.target.value }))} className="text-xs rounded-lg px-2 py-1.5 outline-none" style={{ border: `1px solid ${COLORS.line}`, background: "white" }}>
                                              {PAYMENT_METHODS.map((m) => <option key={m} value={m}>{m}</option>)}
                                            </select>
                                          </td>
                                          <td className="py-2">
                                            <div className="flex items-center gap-2">
                                              <button onClick={() => saveEditTx(tx.id)} aria-label="Save changes"><Check size={15} color={COLORS.teal700} /></button>
                                              <button onClick={cancelEditTx} aria-label="Cancel edit"><X size={13} color={COLORS.muted} /></button>
                                            </div>
                                          </td>
                                        </tr>
                                      );
                                    }
                                    return (
                                      <tr key={tx.id} style={{ borderBottom: `1px solid ${COLORS.paperDeep}` }}>
                                        <td className="py-2" style={{ color: COLORS.ink }}>{fmtDate(tx.date)}</td>
                                        <td className="py-2" style={{ color: COLORS.ink }}>{tx.bottles}</td>
                                        <td className="py-2" style={{ color: COLORS.muted }}>{tx.bottles_returned || 0}</td>
                                        <td className="py-2" style={{ color: COLORS.muted }}>{money(tx.rate)}</td>
                                        <td className="py-2" style={{ color: COLORS.ink }}>{money(tx.bottles * tx.rate)}</td>
                                        <td className="py-2" style={{ color: COLORS.ink }}>{money(tx.paid)}</td>
                                        <td className="py-2 text-xs" style={{ color: COLORS.muted }}>{tx.payment_method || "Cash"}</td>
                                        <td className="py-2">
                                          {role === "admin" ? (
                                            <div className="flex items-center gap-2.5">
                                              <button onClick={() => startEditTx(tx)} aria-label="Edit entry"><Pencil size={13} color={COLORS.teal700} /></button>
                                              <button onClick={() => setConfirmDeleteTx(tx)} aria-label="Remove entry"><X size={13} color={COLORS.muted} /></button>
                                            </div>
                                          ) : (
                                            <span className="text-xs" style={{ color: COLORS.line }}>—</span>
                                          )}
                                        </td>
                                      </tr>
                                    );
                                  })}
                                </tbody>
                              </table>
                            </div>
                          )}

                          <div className="rounded-xl p-4 flex flex-wrap items-end gap-3 mb-3" style={{ background: COLORS.paperDeep }}>
                            <div>
                              <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Date</label>
                              <input type="date" value={entryDate} onChange={(e) => setEntryDate(e.target.value)} className="text-sm rounded-lg px-2.5 py-2 outline-none" style={{ border: `1px solid ${COLORS.line}` }} />
                            </div>
                            <div>
                              <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Bottles given</label>
                              <input type="number" value={entryBottles} onChange={(e) => setEntryBottles(e.target.value)} className="w-24 text-sm rounded-lg px-2.5 py-2 outline-none" style={{ border: `1px solid ${COLORS.line}` }} />
                            </div>
                            <div>
                              <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Empty bottles taken back</label>
                              <input type="number" value={entryBottlesReturned} onChange={(e) => setEntryBottlesReturned(e.target.value)} className="w-24 text-sm rounded-lg px-2.5 py-2 outline-none" style={{ border: `1px solid ${COLORS.line}` }} />
                            </div>
                            <div>
                              <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Rate (PKR)</label>
                              <input type="number" value={entryRate} onChange={(e) => setEntryRate(e.target.value)} className="w-24 text-sm rounded-lg px-2.5 py-2 outline-none" style={{ border: `1px solid ${COLORS.line}` }} />
                            </div>
                            <div>
                              <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Amount received (PKR)</label>
                              <input type="number" value={entryPaid} onChange={(e) => setEntryPaid(e.target.value)} className="w-32 text-sm rounded-lg px-2.5 py-2 outline-none" style={{ border: `1px solid ${COLORS.line}` }} />
                            </div>
                            <div>
                              <label className="text-xs font-medium block mb-1" style={{ color: COLORS.muted }}>Payment method</label>
                              <select value={entryPaymentMethod} onChange={(e) => setEntryPaymentMethod(e.target.value)} className="text-sm rounded-lg px-2.5 py-2 outline-none" style={{ border: `1px solid ${COLORS.line}`, background: "white" }}>
                                {PAYMENT_METHODS.map((m) => <option key={m} value={m}>{m}</option>)}
                              </select>
                            </div>
                            <button onClick={() => addTransaction(c.id)} disabled={savingAction} className="px-4 py-2 rounded-full text-xs font-semibold text-white" style={{ background: COLORS.teal700, opacity: savingAction ? 0.6 : 1 }}>
                              Save entry
                            </button>
                          </div>

                          <div className="flex items-center justify-between flex-wrap gap-2">
                            {role === "admin" && (
                              <button
                                onClick={() => closePeriod(c)}
                                disabled={openTx.length === 0 || savingAction}
                                className="px-4 py-2 rounded-full text-xs font-semibold flex items-center gap-1.5"
                                style={openTx.length === 0 ? { background: COLORS.paperDeep, color: COLORS.muted, cursor: "not-allowed" } : { background: COLORS.gold500, color: COLORS.teal900 }}
                              >
                                <Archive size={13} /> Close this period &amp; start new
                              </button>
                            )}
                            {history.length > 0 && (
                              <button onClick={() => setHistoryOpenFor((cur) => (cur === c.id ? null : c.id))} className="text-xs font-semibold flex items-center gap-1.5" style={{ color: COLORS.teal700 }}>
                                <History size={13} /> {isHistoryOpen ? "Hide" : "View"} past periods ({history.length})
                              </button>
                            )}
                          </div>

                          {isHistoryOpen && (
                            <div className="mt-4 space-y-3">
                              {history.map((h, idx) => {
                                const ht = periodTotals(h.transactions);
                                return (
                                  <div key={idx} className="rounded-xl p-3" style={{ background: COLORS.paperDeep }}>
                                    <div className="flex justify-between items-center mb-2">
                                      <div className="text-xs font-semibold" style={{ color: COLORS.teal700 }}>{h.label} · closed {fmtDate(h.closedOn)}</div>
                                    </div>
                                    <div className="text-xs mb-2" style={{ color: COLORS.muted }}>
                                      Bottles: {ht.bottles} · Charged: {money(ht.charged)} · Paid: {money(ht.paid)}
                                    </div>
                                    <div className="overflow-x-auto">
                                      <table className="w-full text-xs" style={{ minWidth: 420 }}>
                                        <tbody>
                                          {h.transactions.map((tx) => (
                                            <tr key={tx.id} style={{ borderBottom: `1px solid ${COLORS.line}` }}>
                                              <td className="py-1.5" style={{ color: COLORS.ink }}>{fmtDate(tx.date)}</td>
                                              <td className="py-1.5" style={{ color: COLORS.ink }}>{tx.bottles} btl</td>
                                              <td className="py-1.5" style={{ color: COLORS.muted }}>@ {money(tx.rate)}</td>
                                              <td className="py-1.5" style={{ color: COLORS.ink }}>{money(tx.bottles * tx.rate)}</td>
                                              <td className="py-1.5" style={{ color: COLORS.ink }}>paid {money(tx.paid)}</td>
                                            </tr>
                                          ))}
                                        </tbody>
                                      </table>
                                    </div>
                                  </div>
                                );
                              })}
                            </div>
                          )}
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            </div>
          ))}

          {customers.length === 0 && (
            <div className="rounded-2xl p-10 text-center" style={{ background: "white", border: `1px solid ${COLORS.line}`, color: COLORS.muted }}>
              <Users size={20} className="mx-auto mb-2" />
              No customers yet — add one above.
            </div>
          )}
        </div>
          </>
        )}
      </main>

      <footer className="px-5 sm:px-10 py-6 text-center text-xs" style={{ color: COLORS.muted }}>
        Connected to Supabase — data is saved for real. Currently viewing as: {roleLabel}.
      </footer>
    </div>
  );
}

import { createRoot } from "react-dom/client";
createRoot(document.getElementById("root")).render(<BottleLedgerLive />);
