const { useEffect, useRef, useState } = React;

const API_BASE = (window.CITYSOOCHNA_API_BASE || "").replace(/\/$/, "");
const apiUrl = (url) => url.startsWith("http") ? url : `${API_BASE}${url}`;
const assetUrl = (url) => {
  if (!url || String(url).startsWith("data:") || String(url).startsWith("http")) return url || "";
  return String(url).startsWith("/") ? `${API_BASE}${url}` : url;
};

const api = async (url, options = {}) => {
  const response = await fetch(apiUrl(url), {
    credentials: "include",
    headers: { "Content-Type": "application/json", ...(options.headers || {}) },
    ...options
  });
  const data = await response.json().catch(() => ({}));
  if (!response.ok) throw new Error(data.error || "Something went wrong");
  return data;
};

const INDIAN_LOCATIONS = {
  "Andaman and Nicobar Islands": ["Port Blair", "Mayabunder", "Diglipur"],
  "Andhra Pradesh": ["Visakhapatnam", "Vijayawada", "Guntur", "Nellore", "Kurnool", "Tirupati", "Rajahmundry", "Kakinada"],
  "Arunachal Pradesh": ["Itanagar", "Naharlagun", "Pasighat", "Tawang", "Ziro"],
  "Assam": ["Guwahati", "Silchar", "Dibrugarh", "Jorhat", "Tezpur", "Nagaon"],
  "Bihar": ["Patna", "Gaya", "Bhagalpur", "Muzaffarpur", "Darbhanga", "Purnia"],
  "Chandigarh": ["Chandigarh"],
  "Chhattisgarh": ["Raipur", "Bhilai", "Bilaspur", "Korba", "Durg", "Rajnandgaon"],
  "Dadra and Nagar Haveli and Daman and Diu": ["Daman", "Diu", "Silvassa"],
  "Delhi": ["New Delhi", "Dwarka", "Rohini", "Karol Bagh", "Saket", "Lajpat Nagar", "Pitampura", "Janakpuri"],
  "Goa": ["Panaji", "Margao", "Vasco da Gama", "Mapusa", "Ponda"],
  "Gujarat": ["Ahmedabad", "Surat", "Vadodara", "Rajkot", "Bhavnagar", "Jamnagar", "Gandhinagar", "Junagadh", "Anand"],
  "Haryana": ["Gurugram", "Faridabad", "Panipat", "Hisar", "Ambala", "Karnal", "Rohtak", "Sonipat", "Kurukshetra"],
  "Himachal Pradesh": ["Shimla", "Dharamshala", "Mandi", "Solan", "Kullu", "Una"],
  "Jammu and Kashmir": ["Srinagar", "Jammu", "Anantnag", "Baramulla", "Udhampur"],
  "Jharkhand": ["Ranchi", "Jamshedpur", "Dhanbad", "Bokaro", "Deoghar", "Hazaribagh"],
  "Karnataka": ["Bengaluru", "Mysuru", "Mangaluru", "Hubballi", "Belagavi", "Davangere", "Ballari", "Udupi", "Shivamogga"],
  "Kerala": ["Kochi", "Thiruvananthapuram", "Kozhikode", "Thrissur", "Kollam", "Alappuzha", "Kottayam", "Kannur", "Palakkad"],
  "Ladakh": ["Leh", "Kargil"],
  "Lakshadweep": ["Kavaratti", "Agatti", "Amini"],
  "Madhya Pradesh": ["Indore", "Bhopal", "Gwalior", "Jabalpur", "Ujjain", "Sagar", "Rewa", "Satna"],
  "Maharashtra": ["Mumbai", "Pune", "Nagpur", "Nashik", "Thane", "Aurangabad", "Solapur", "Kolhapur", "Amravati"],
  "Manipur": ["Imphal", "Thoubal", "Bishnupur", "Churachandpur"],
  "Meghalaya": ["Shillong", "Tura", "Jowai", "Nongpoh"],
  "Mizoram": ["Aizawl", "Lunglei", "Champhai", "Serchhip"],
  "Nagaland": ["Kohima", "Dimapur", "Mokokchung", "Tuensang"],
  "Odisha": ["Bhubaneswar", "Cuttack", "Rourkela", "Puri", "Sambalpur", "Balasore", "Berhampur"],
  "Puducherry": ["Puducherry", "Karaikal", "Yanam", "Mahe"],
  "Punjab": ["Ludhiana", "Amritsar", "Jalandhar", "Patiala", "Bathinda", "Mohali", "Pathankot"],
  "Rajasthan": ["Jaipur", "Jodhpur", "Udaipur", "Kota", "Ajmer", "Bikaner", "Alwar", "Bhilwara", "Sikar"],
  "Sikkim": ["Gangtok", "Namchi", "Gyalshing", "Mangan"],
  "Tamil Nadu": ["Chennai", "Coimbatore", "Madurai", "Salem", "Tiruchirappalli", "Tiruppur", "Erode", "Vellore", "Thoothukudi"],
  "Telangana": ["Hyderabad", "Warangal", "Nizamabad", "Karimnagar", "Khammam", "Ramagundam", "Mahbubnagar"],
  "Tripura": ["Agartala", "Udaipur", "Dharmanagar", "Kailashahar"],
  "Uttar Pradesh": ["Lucknow", "Kanpur", "Noida", "Ghaziabad", "Varanasi", "Agra", "Meerut", "Prayagraj", "Bareilly", "Gorakhpur"],
  "Uttarakhand": ["Roorkee", "Dehradun", "Haridwar", "Haldwani", "Rishikesh", "Kashipur", "Rudrapur", "Nainital"],
  "West Bengal": ["Kolkata", "Howrah", "Siliguri", "Durgapur", "Asansol", "Darjeeling", "Kharagpur", "Bardhaman"]
};

const stateNames = Object.keys(INDIAN_LOCATIONS).sort();
const locationOptions = stateNames.flatMap((state) => (INDIAN_LOCATIONS[state] || []).map((city) => ({ city, state, label: `${city}, ${state}` })));

const BUSINESS_CATEGORIES = {
  "Agriculture": ["Seeds", "Fertilizers", "Pesticides", "Farm equipment", "Irrigation", "Organic produce", "Dairy farming", "Poultry farming", "Animal feed", "Agro chemicals"],
  "Automobile": ["Car dealers", "Bike dealers", "Spare parts", "Tyres", "Battery", "Repair garage", "Car wash", "Accessories", "Used vehicles", "EV charging"],
  "Baby and Kids": ["Baby products", "Toys", "Kids clothing", "School supplies", "Day care", "Maternity products", "Kids furniture"],
  "Beauty and Wellness": ["Salon", "Spa", "Cosmetics", "Skin care", "Hair care", "Fitness center", "Yoga", "Gym", "Wellness clinic", "Massage"],
  "Books and Stationery": ["Books", "School books", "Office stationery", "Printing stationery", "Art supplies", "Registers", "Packaging stationery"],
  "Business Services": ["CA", "Accounting", "Legal", "HR services", "Recruitment", "Security services", "Housekeeping", "Facility management", "Consulting", "Insurance"],
  "Construction": ["Contractor", "Architect", "Interior designer", "Cement", "Steel", "Bricks", "Tiles", "Paint", "Hardware", "Sanitaryware", "Plumbing", "Electrical contractor"],
  "Education": ["School", "College", "Coaching", "Tuition", "Training institute", "Computer classes", "Language classes", "Skill training", "Online classes", "Library"],
  "Electricals": ["Wires", "Lights", "Switches", "Fans", "Appliances", "Electrical panels", "Inverters", "Solar equipment", "Repair service", "Electrical wholesale"],
  "Electronics": ["Mobile phones", "Mobile accessories", "Computer hardware", "Laptops", "CCTV", "Printers", "Audio video", "Electronics repair", "Gaming", "Smart devices"],
  "Events and Entertainment": ["Event planner", "Wedding planner", "Tent house", "Catering", "Photography", "Videography", "DJ sound", "Decoration", "Makeup artist", "Event venue"],
  "Fashion and Apparel": ["Clothing", "Mens wear", "Womens wear", "Kids wear", "Footwear", "Bags", "Jewellery", "Boutique", "Tailor", "Uniforms", "Textiles"],
  "Finance": ["Loans", "Mutual funds", "Tax planning", "Insurance", "Bookkeeping", "Payment services", "Investment advisor", "Banking services"],
  "Food and Grocery": ["Wholesale grocery", "Retail grocery", "Snacks", "Spices", "Bakery", "Dairy products", "Restaurant supplies", "Cloud kitchen", "Sweets", "Dry fruits", "Beverages"],
  "Furniture and Decor": ["Furniture", "Office furniture", "Home decor", "Mattress", "Curtains", "Modular kitchen", "Lighting decor", "Carpets", "Handicrafts"],
  "Gifts and Handicrafts": ["Corporate gifts", "Handmade gifts", "Handicrafts", "Marble decor", "Religious gifts", "Trophies", "Personalized gifts", "Packaging gifts"],
  "Healthcare": ["Clinic", "Hospital", "Pharmacy", "Diagnostics", "Medical supplies", "Dental clinic", "Eye care", "Physiotherapy", "Ayurveda", "Home nursing", "Ambulance"],
  "Home and Kitchen": ["Homeware", "Kitchenware", "Cleaning products", "Storage", "Water purifier", "Gas stove", "Utensils", "Home utility", "Household wholesale"],
  "Industrial": ["Industrial tools", "Safety equipment", "Machinery", "Bearings", "Fasteners", "Welding", "Hydraulics", "Pneumatics", "Workshop supplies", "Generators"],
  "IT and Software": ["Website development", "App development", "Software services", "Digital marketing", "SEO", "Cloud services", "IT support", "Cyber security", "POS software"],
  "Manufacturing": ["Textiles", "Packaging", "Plastic", "Metal works", "Printing", "Paper products", "Food processing", "Garments", "Chemicals", "Fabrication"],
  "Pet Care": ["Pet food", "Pet grooming", "Veterinary", "Pet accessories", "Pet boarding", "Aquarium"],
  "Printing and Packaging": ["Offset printing", "Digital printing", "Labels", "Boxes", "Corrugated packaging", "Flex printing", "Business cards", "Catalogues", "Bags"],
  "Real Estate": ["Property dealer", "Builders", "Rentals", "Commercial property", "Property management", "Hostel PG", "Warehousing space"],
  "Repair and Maintenance": ["Appliance repair", "Mobile repair", "Computer repair", "AC repair", "RO repair", "Electrician", "Plumber", "Carpenter", "Painter"],
  "Retail": ["General store", "Department store", "Kirana", "Supermarket", "Gift store", "Stationery retail", "Lifestyle store", "Discount store"],
  "Sports and Fitness": ["Sports goods", "Gym equipment", "Fitness trainer", "Sports academy", "Yoga studio", "Nutrition", "Outdoor gear"],
  "Telecom": ["Internet service", "Broadband", "Mobile recharge", "SIM dealer", "Telecom equipment", "Network services"],
  "Transport and Logistics": ["Courier", "Transporter", "Tempo", "Packers movers", "Warehouse", "Freight", "Cold storage", "Last mile delivery", "Travel cab"],
  "Travel and Hospitality": ["Hotel", "Restaurant", "Travel agent", "Tour operator", "Resort", "Guest house", "Cafe", "Banquet hall", "Ticket booking"],
  "Wholesale and Distribution": ["FMCG distributor", "Pharma distributor", "Electronics distributor", "Garment wholesale", "Food wholesale", "Building material wholesale", "Super stockist"]
};

const SUPER_CATEGORIES = [
  { name: "General", icon: "store", categories: ["Retail", "Wholesale and Distribution", "Business Services", "Repair and Maintenance"] },
  { name: "Products", icon: "package-search", categories: ["Food and Grocery", "Fashion and Apparel", "Home and Kitchen", "Books and Stationery", "Baby and Kids", "Gifts and Handicrafts"] },
  { name: "Services", icon: "briefcase-business", categories: ["Business Services", "IT and Software", "Finance", "Education", "Events and Entertainment"] },
  { name: "Home and Building", icon: "building-2", categories: ["Construction", "Furniture and Decor", "Electricals", "Real Estate"] },
  { name: "Health and Lifestyle", icon: "heart-pulse", categories: ["Healthcare", "Beauty and Wellness", "Sports and Fitness", "Pet Care"] },
  { name: "Industrial", icon: "factory", categories: ["Manufacturing", "Industrial", "Printing and Packaging", "Agriculture"] },
  { name: "Mobility", icon: "truck", categories: ["Automobile", "Transport and Logistics", "Travel and Hospitality", "Telecom", "Electronics"] }
];

const categoryNames = Object.keys(BUSINESS_CATEGORIES).sort();
const REPORT_REASONS = ["Fake business", "Wrong details", "Spam post", "Abusive chat", "Duplicate listing", "Fraud or suspicious", "Other"];
const CONSENT_VERSION = "2026-07-04";

const LEGAL_CONTENT = {
  terms: {
    title: "Terms and Conditions",
    updated: "July 4, 2026",
    sections: [
      ["Use of CitySoochna", "CitySoochna helps people discover businesses, view catalogs, send enquiries, chat, save listings, follow businesses, and request quotations. Buying and selling do not happen directly on the platform."],
      ["Account responsibility", "You are responsible for keeping your account details accurate, protecting your login, and using correct phone, email, business, GST, address, catalog, and quotation information."],
      ["Business listings", "Business owners must only list businesses they own or are authorized to represent. Admin may review, approve, block, reject, or remove listings that appear fake, duplicate, misleading, abusive, or spammy."],
      ["Communication", "Users may contact each other through enquiry, chat, phone, WhatsApp, or listed business contact details. Do not send spam, abusive content, fraud messages, or illegal offers."],
      ["No transaction guarantee", "CitySoochna is a discovery and communication platform. We do not guarantee product availability, price, delivery, payment, quality, or any offline agreement between users."],
      ["Changes", "We may update features, moderation rules, consent wording, or these terms as the platform grows. Continued use means you agree to the current terms."]
    ]
  },
  privacy: {
    title: "Privacy Policy",
    updated: "July 4, 2026",
    sections: [
      ["Data we collect", "We collect account details, phone number, email, location preferences, business details, catalog data, enquiries, chat messages, posts, support requests, notification preferences, analytics events, and consent records."],
      ["Business and marketing use", "With your consent, we use your data to run business pages, show relevant businesses and posts, enable enquiries and chat, provide admin support, improve catalog discovery, send service updates, and send marketing communication when you opt in."],
      ["Public visibility", "Business profile details, catalog items, posts, public contact phone, location, category, and website/social links may be visible to other users. Account emails are not shown as public contact details unless used in a business email field."],
      ["Admin and moderation", "Admins can review users, businesses, claims, reports, support tickets, enquiries, and platform activity to protect the platform and resolve issues."],
      ["Storage and security", "Data is stored in the CitySoochna MySQL database and uploaded/generated media storage. We use access controls and login sessions, but users should avoid sharing sensitive personal information in public fields."],
      ["Your choices", "You can update profile details, notification preferences, business information, and marketing preference. Support can be contacted for account or data-related requests."]
    ]
  }
};

function LucideIcon({ name, label }) {
  useEffect(() => {
    if (window.lucide) window.lucide.createIcons();
  });

  return <span className="lucide-holder" data-lucide={name} aria-label={label} />;
}

function formatDetailValue(value) {
  if (value === null || value === undefined || value === "") return "-";
  if (typeof value === "boolean") return value ? "Yes" : "No";
  if (Array.isArray(value)) {
    if (!value.length) return "-";
    return value.map((entry) => {
      if (entry === null || entry === undefined || entry === "") return "";
      if (typeof entry === "boolean") return entry ? "Yes" : "No";
      if (typeof entry === "object") return Object.entries(entry).map(([key, val]) => `${formatDetailLabel(key)}: ${formatDetailValue(val)}`).join(", ");
      return String(entry);
    }).filter(Boolean).join(" | ");
  }
  if (typeof value === "object") {
    if (value.name || value.email || value.phone) {
      return [value.name, value.email, value.phone].filter(Boolean).join(" | ") || value.id || "-";
    }
    if (value.businessName) {
      return [value.businessName, value.category, [value.city, value.state].filter(Boolean).join(", ")].filter(Boolean).join(" | ");
    }
    if (value.title || value.message) {
      return [value.title, value.message].filter(Boolean).join(" | ");
    }
    const entries = Object.entries(value).filter(([, val]) => val !== undefined && val !== null && val !== "");
    if (!entries.length) return "-";
    return entries.map(([key, val]) => `${formatDetailLabel(key)}: ${formatDetailValue(val)}`).join(" | ");
  }
  return String(value);
}

function formatDetailLabel(key) {
  const labels = {
    inApp: "In-app",
    email: "Email",
    whatsapp: "WhatsApp",
    sms: "SMS",
    businessName: "Business name",
    ownerId: "Owner ID",
    requesterId: "Requester ID",
    businessId: "Business ID",
    targetType: "Target type",
    targetId: "Target ID"
  };
  return labels[key] || String(key).replace(/([a-z])([A-Z])/g, "$1 $2").replaceAll("_", " ").replace(/^./, (char) => char.toUpperCase());
}

function fileToDataUrl(file) {
  return new Promise((resolve) => {
    if (!file) return resolve("");
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result);
    reader.readAsDataURL(file);
  });
}

function fileToCroppedDataUrl(file, targetWidth, targetHeight) {
  return new Promise((resolve) => {
    if (!file) return resolve("");
    const reader = new FileReader();
    reader.onload = () => {
      const image = new Image();
      image.onload = () => {
        const sourceRatio = image.width / image.height;
        const targetRatio = targetWidth / targetHeight;
        let sx = 0;
        let sy = 0;
        let sw = image.width;
        let sh = image.height;
        if (sourceRatio > targetRatio) {
          sw = image.height * targetRatio;
          sx = (image.width - sw) / 2;
        } else {
          sh = image.width / targetRatio;
          sy = (image.height - sh) / 2;
        }
        const canvas = document.createElement("canvas");
        canvas.width = targetWidth;
        canvas.height = targetHeight;
        canvas.getContext("2d").drawImage(image, sx, sy, sw, sh, 0, 0, targetWidth, targetHeight);
        resolve(canvas.toDataURL("image/jpeg", 0.88));
      };
      image.src = reader.result;
    };
    reader.readAsDataURL(file);
  });
}

function cropDataUrl(source, targetWidth, targetHeight, zoom = 1, positionX = 50, positionY = 50) {
  return new Promise((resolve) => {
    const image = new Image();
    image.onload = () => {
      const baseScale = Math.max(targetWidth / image.width, targetHeight / image.height);
      const scale = baseScale * zoom;
      const drawWidth = image.width * scale;
      const drawHeight = image.height * scale;
      const offsetX = (targetWidth - drawWidth) * (positionX / 100);
      const offsetY = (targetHeight - drawHeight) * (positionY / 100);
      const canvas = document.createElement("canvas");
      canvas.width = targetWidth;
      canvas.height = targetHeight;
      const context = canvas.getContext("2d");
      context.fillStyle = "#ffffff";
      context.fillRect(0, 0, targetWidth, targetHeight);
      context.drawImage(image, offsetX, offsetY, drawWidth, drawHeight);
      resolve(canvas.toDataURL("image/jpeg", 0.9));
    };
    image.src = source;
  });
}

function pageFromPath() {
  const parts = window.location.pathname.split("/").filter(Boolean);
  if (!parts.length) return "home";
  if (parts[0] === "terms") return "terms";
  if (parts[0] === "privacy") return "privacy";
  if (parts[0] === "admin" && parts[1] && parts[2]) return `adminDetail:${parts[1]}:${parts[2]}`;
  if (parts[0] === "admin") return "admin";
  if (parts[0] === "dashboard") return parts[1] ? `dashboard:${parts[1]}` : "dashboard";
  if (parts[0] === "businesses" && parts[1] && parts[2] === "catalog") return `catalog:${parts[1]}`;
  if (parts[0] === "businesses" && parts[1]) return `business:${parts[1]}`;
  if (parts[0] === "items" && parts[1]) return `item:${parts[1]}`;
  if (parts[0] === "chat" && parts[1]) return `chat:${parts[1]}`;
  if (parts[0] === "enquiries" && parts[1]) return `enquiry:${parts[1]}`;
  if (parts.length >= 4) return `businessSeo:${parts.join("/")}`;
  return "home";
}

function pathForPage(page) {
  if (page === "terms") return "/terms";
  if (page === "privacy") return "/privacy";
  if (page === "admin") return "/admin";
  if (page.startsWith("adminDetail:")) {
    const [, type, id] = page.split(":");
    return `/admin/${type}/${id}`;
  }
  if (page === "dashboard") return "/dashboard";
  if (page.startsWith("dashboard:")) return `/dashboard/${page.split(":")[1]}`;
  if (page.startsWith("catalog:")) return `/businesses/${page.split(":")[1]}/catalog`;
  if (page.startsWith("business:")) return `/businesses/${page.split(":")[1]}`;
  if (page.startsWith("businessSeo:")) return `/${page.replace("businessSeo:", "")}`;
  if (page.startsWith("item:")) return `/items/${page.split(":")[1]}`;
  if (page.startsWith("chat:")) return `/chat/${page.split(":")[1]}`;
  if (page.startsWith("enquiry:")) return `/enquiries/${page.split(":")[1]}`;
  return "/";
}

function App() {
  const [page, setPage] = useState(pageFromPath());
  const [me, setMe] = useState({ user: null, business: null });
  const [authReady, setAuthReady] = useState(false);
  const [toast, setToast] = useState([]);
  const [refreshKey, setRefreshKey] = useState(0);
  const [shareProfileOpen, setShareProfileOpen] = useState(false);

  const navigate = (nextPage) => {
    setPage(nextPage);
    const nextPath = pathForPage(nextPage);
    if (window.location.pathname !== nextPath) window.history.pushState({}, "", nextPath);
  };

  const notify = (title, detail) => {
    const item = { id: Date.now(), title, detail };
    setToast((items) => [...items.slice(-2), item]);
    setTimeout(() => setToast((items) => items.filter((entry) => entry.id !== item.id)), 4200);
  };

  const loadMe = async () => {
    const data = await api("/api/me");
    setMe(data);
    setAuthReady(true);
    return data;
  };

  useEffect(() => {
    loadMe().catch(() => setAuthReady(true));
    const onPop = () => setPage(pageFromPath());
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
  }, []);

  useEffect(() => {
    if (!me.user) return undefined;
    const source = new EventSource(apiUrl("/api/events"), { withCredentials: true });
    source.addEventListener("notification", (event) => {
      const data = JSON.parse(event.data);
      notify(data.title, data.message);
      setRefreshKey((key) => key + 1);
    });
    source.addEventListener("message", () => setRefreshKey((key) => key + 1));
    return () => source.close();
  }, [me.user?.id]);

  const logout = async () => {
    await api("/api/auth/logout", { method: "POST", body: "{}" });
    setMe({ user: null, business: null });
    setPage("home");
  };

  const needsLogin = page === "admin" || page.startsWith("adminDetail:") || page === "dashboard" || page.startsWith("dashboard:") || page.startsWith("chat:") || page.startsWith("enquiry:");
  const protectedContent = needsLogin && !me.user;

  useEffect(() => {
    if (authReady && protectedContent) navigate("login");
  }, [authReady, protectedContent]);

  return (
    <div className="app-shell">
      <header className="topbar">
        <button className="brand" onClick={() => setPage("home")}>
          <span className="brand-mark">c</span>
          <span>citysoochna</span>
        </button>
        {me.user && <HeaderLocation user={me.user} setMe={setMe} notify={notify} />}
        <nav className="nav">
          <button className="ghost" onClick={() => navigate("home")}>Explore</button>
          {me.user?.accountRole === "admin" && <button className="ghost" onClick={() => navigate("admin")}>Admin</button>}
          {me.user && <button className="ghost" onClick={() => navigate("dashboard:feed")}>Dashboard</button>}
          {me.user && <button className="icon-btn chat-nav" onClick={() => navigate("dashboard:messages")} title="Messages" aria-label="Messages"><LucideIcon name="message-circle" label="Messages" />{me.unreadMessages > 0 && <i>{me.unreadMessages}</i>}</button>}
          {me.user && <NotificationBell refreshKey={refreshKey} notify={notify} setPage={navigate} />}
          {me.user ? (
            <AccountMenu me={me} setPage={navigate} onShare={() => setShareProfileOpen(true)} onLogout={logout} />
          ) : (
            <>
              <button className="ghost" onClick={() => navigate("login")}>Login</button>
              <button className="ghost" onClick={() => navigate("register")}>Sign up</button>
              <button className="btn" onClick={() => navigate("onboarding")}>Create business page</button>
            </>
          )}
        </nav>
      </header>

      {protectedContent && !authReady && <main className="page"><div className="panel empty-state">Checking login...</div></main>}
      {protectedContent && authReady && <Login setPage={navigate} setMe={setMe} notify={notify} />}
      {!protectedContent && page === "home" && <Home setPage={navigate} notify={notify} me={me} />}
      {!protectedContent && page === "terms" && <LegalPage type="terms" />}
      {!protectedContent && page === "privacy" && <LegalPage type="privacy" />}
      {page === "login" && <Login setPage={navigate} setMe={setMe} notify={notify} />}
      {page === "register" && <Register setPage={navigate} setMe={setMe} notify={notify} />}
      {!protectedContent && page === "onboarding" && <Onboarding setPage={navigate} setMe={setMe} notify={notify} />}
      {!protectedContent && (page === "dashboard" || page.startsWith("dashboard:")) && <Dashboard me={me} setMe={setMe} refreshKey={refreshKey} notify={notify} setPage={navigate} initialTab={page.split(":")[1]} />}
      {!protectedContent && page === "admin" && <AdminDashboard me={me} notify={notify} setPage={navigate} />}
      {!protectedContent && page.startsWith("adminDetail:") && <AdminDetailPage me={me} notify={notify} setPage={navigate} type={page.split(":")[1]} id={page.split(":")[2]} />}
      {!protectedContent && page.startsWith("business:") && <BusinessDetail id={page.split(":")[1]} me={me} notify={notify} setPage={navigate} />}
      {!protectedContent && page.startsWith("businessSeo:") && <BusinessDetail seoPath={page.replace("businessSeo:", "")} me={me} notify={notify} setPage={navigate} />}
      {!protectedContent && page.startsWith("catalog:") && (me.user ? <DashboardDetailShell me={me} setPage={navigate} active="catalog"><BusinessCatalogPage id={page.split(":")[1]} me={me} notify={notify} setPage={navigate} embedded /></DashboardDetailShell> : <BusinessCatalogPage id={page.split(":")[1]} me={me} notify={notify} setPage={navigate} />)}
      {!protectedContent && page.startsWith("item:") && (me.user ? <DashboardDetailShell me={me} setPage={navigate} active="catalog"><ItemDetail id={page.split(":")[1]} me={me} notify={notify} setPage={navigate} embedded /></DashboardDetailShell> : <ItemDetail id={page.split(":")[1]} me={me} notify={notify} setPage={navigate} />)}
      {!protectedContent && page.startsWith("chat:") && <DashboardDetailShell me={me} setPage={navigate} active="messages"><ChatPage id={page.split(":")[1]} me={me} notify={notify} embedded /></DashboardDetailShell>}
      {!protectedContent && page.startsWith("enquiry:") && <DashboardDetailShell me={me} setPage={navigate} active="enquiries"><EnquiryPage id={page.split(":")[1]} me={me} notify={notify} embedded /></DashboardDetailShell>}

      {shareProfileOpen && me.user && (
        <ShareProfileModal
          title={me.business?.businessName || me.user.name || me.user.username || "CitySoochna profile"}
          url={me.business?.id ? `${window.location.origin}/businesses/${me.business.id}` : `${window.location.origin}/dashboard/about`}
          notify={notify}
          onClose={() => setShareProfileOpen(false)}
        />
      )}

      <Footer me={me} setPage={navigate} />

      <div className="toast-stack">
        {toast.map((entry) => (
          <div className="toast" key={entry.id}>
            <strong>{entry.title}</strong>
            <div>{entry.detail}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

function Login({ setPage, setMe, notify }) {
  const [form, setForm] = useState({ login: "demo@citysoochna.test", password: "citysoochna123" });

  const login = async () => {
    try {
      const data = await api("/api/auth/login", { method: "POST", body: JSON.stringify({ ...form, email: form.login }) });
      setMe({ user: data.user, business: data.business });
      notify("Logged in", `Welcome back, ${data.user.name}.`);
      setPage(data.user.accountRole === "admin" ? "admin" : "dashboard:feed");
    } catch (error) {
      notify("Login failed", error.message);
    }
  };

  return (
    <main className="page form-page">
      <section className="panel login-panel">
        <span className="eyebrow">Welcome back</span>
        <h1>Login to CitySoochna</h1>
        <p className="muted">Use your admin or business account to open dashboard access.</p>
        <div className="form-grid">
          <Field label="Username or email" value={form.login} onChange={(value) => setForm({ ...form, login: value })} />
          <PasswordField label="Password" value={form.password} onChange={(value) => setForm({ ...form, password: value })} />
        </div>
        <p>
          <button className="btn" onClick={login}>Login</button>{" "}
          <button className="ghost" onClick={() => setPage("register")}>Create normal account</button>
        </p>
      </section>
    </main>
  );
}

function LegalPage({ type }) {
  const content = LEGAL_CONTENT[type] || LEGAL_CONTENT.terms;
  return (
    <main className="page legal-page">
      <section className="panel legal-panel">
        <span className="eyebrow">CitySoochna legal</span>
        <h1>{content.title}</h1>
        <p className="muted">Last updated: {content.updated}</p>
        {content.sections.map(([title, body]) => (
          <article className="legal-section" key={title}>
            <h2>{title}</h2>
            <p>{body}</p>
          </article>
        ))}
      </section>
    </main>
  );
}

function LegalModal({ type, onClose }) {
  const content = LEGAL_CONTENT[type] || LEGAL_CONTENT.terms;
  return (
    <div className="modal-backdrop" onMouseDown={onClose}>
      <section className="modal-panel legal-modal" onMouseDown={(event) => event.stopPropagation()}>
        <div className="detail-head">
          <div>
            <h2>{content.title}</h2>
            <p className="muted">Last updated: {content.updated}</p>
          </div>
          <button className="icon-btn" onClick={onClose} aria-label="Close"><LucideIcon name="x" label="Close" /></button>
        </div>
        {content.sections.map(([title, body]) => (
          <article className="legal-section" key={title}>
            <h3>{title}</h3>
            <p>{body}</p>
          </article>
        ))}
      </section>
    </div>
  );
}

function ConsentFields({ value, onChange, openLegal }) {
  return (
    <div className="consent-box">
      <label className="check-row">
        <input
          type="checkbox"
          checked={Boolean(value.termsAccepted)}
          onChange={(event) => onChange({ ...value, termsAccepted: event.target.checked, dataProcessingConsent: event.target.checked })}
        />
        <span>
          I agree to CitySoochna's{" "}
          <button type="button" className="inline-link" onClick={() => openLegal("terms")}>Terms and Conditions</button>
          {" "}and{" "}
          <button type="button" className="inline-link" onClick={() => openLegal("privacy")}>Privacy Policy</button>
          , and consent to use of my data for business page, enquiry, messaging, catalog, support, analytics, and platform operation purposes.
        </span>
      </label>
      <label className="check-row">
        <input
          type="checkbox"
          checked={Boolean(value.marketingConsent)}
          onChange={(event) => onChange({ ...value, marketingConsent: event.target.checked })}
        />
        <span>I agree to receive marketing, product updates, and business growth communication from CitySoochna. This is optional.</span>
      </label>
      <small>Consent version: {CONSENT_VERSION}. We record consent date, IP, and browser details for compliance.</small>
    </div>
  );
}

function Register({ setPage, setMe, notify }) {
  const [form, setForm] = useState({ name: "", username: "", email: "", phone: "", password: "", termsAccepted: false, dataProcessingConsent: false, marketingConsent: false });
  const [legalOpen, setLegalOpen] = useState("");

  const register = async () => {
    if (!form.termsAccepted || !form.dataProcessingConsent) {
      notify("Consent required", "Please read and accept the Terms, Privacy Policy, and data-use consent.");
      return;
    }
    try {
      const data = await api("/api/auth/register", { method: "POST", body: JSON.stringify(form) });
      setMe({ user: data.user, business: null });
      notify("Account created", "You can explore, message users, or create a business page.");
      setPage("dashboard:feed");
    } catch (error) {
      notify("Signup failed", error.message);
    }
  };

  return (
    <main className="page form-page">
      <section className="panel login-panel">
        <span className="eyebrow">Normal account</span>
        <h1>Create account</h1>
        <p className="muted">Explore businesses, communicate with sellers, and create a business page whenever you are ready.</p>
        <div className="form-grid">
          <Field label="Full name" value={form.name} onChange={(value) => setForm({ ...form, name: value })} />
          <Field label="Username" value={form.username} onChange={(value) => setForm({ ...form, username: value })} />
          <Field label="Email" type="email" value={form.email} onChange={(value) => setForm({ ...form, email: value })} />
          <Field label="Phone" value={form.phone} onChange={(value) => setForm({ ...form, phone: value })} />
          <PasswordField label="Password" value={form.password} onChange={(value) => setForm({ ...form, password: value })} />
        </div>
        <ConsentFields value={form} onChange={setForm} openLegal={setLegalOpen} />
        <p><button className="btn" onClick={register}>Create account</button></p>
      </section>
      {legalOpen && <LegalModal type={legalOpen} onClose={() => setLegalOpen("")} />}
    </main>
  );
}

function NotificationBell({ refreshKey, notify, setPage }) {
  const [open, setOpen] = useState(false);
  const [data, setData] = useState({ notifications: [], unread: 0 });
  const menuRef = useRef(null);

  const load = async () => {
    const response = await api("/api/notifications");
    setData(response);
  };

  useEffect(() => {
    load().catch(() => {});
  }, [refreshKey]);

  useEffect(() => {
    const close = (event) => {
      if (menuRef.current && !menuRef.current.contains(event.target)) setOpen(false);
    };
    document.addEventListener("mousedown", close);
    return () => document.removeEventListener("mousedown", close);
  }, []);

  const markRead = async (id = "") => {
    await api("/api/notifications/read", { method: "POST", body: JSON.stringify({ id }) });
    await load();
  };

  const openNotification = async (note) => {
    await markRead(note.id);
    setOpen(false);
    if (note.target?.type === "chat" && note.target.id) return setPage(`chat:${note.target.id}`);
    if (note.target?.type === "enquiry" && note.target.id) return setPage(`enquiry:${note.target.id}`);
    if (note.target?.type === "business" && note.target.id) return setPage(`business:${note.target.id}`);
    if (note.target?.type === "admin") {
      if (note.target.section) sessionStorage.setItem("adminSection", note.target.section);
      return setPage("admin");
    }
    const text = `${note.title || ""} ${note.message || ""}`.toLowerCase();
    if (text.includes("support")) setPage("admin");
    else if (text.includes("chat")) setPage("dashboard:messages");
    else if (text.includes("enquiry") || text.includes("message")) setPage("dashboard:enquiries");
    else setPage("dashboard:notifications");
  };

  return (
    <div className="notification-wrap" ref={menuRef}>
      <button className="icon-btn" onClick={() => {
        setOpen(!open);
        load().catch((error) => notify("Notifications", error.message));
      }} title="Notifications">
        <LucideIcon name="bell" label="Notifications" />
        {data.unread > 0 && <i>{data.unread}</i>}
      </button>
      {open && (
        <div className="notification-menu">
          <div className="notification-head">
            <strong>Notifications</strong>
            <div>
              <button className="ghost" onClick={load}>Refresh</button>
              <button className="ghost" onClick={() => markRead()}>Mark all read</button>
              <button className="ghost" onClick={() => {
                setOpen(false);
                setPage("dashboard:notifications");
              }}>View all</button>
            </div>
          </div>
          {data.notifications.map((note) => (
            <button className={`notification-item ${note.read || note.is_read ? "read" : ""}`} key={note.id} onClick={() => openNotification(note)}>
              <strong>{note.title}</strong>
              <span>{note.message}</span>
            </button>
          ))}
          {!data.notifications.length && <p className="muted">No notifications yet.</p>}
        </div>
      )}
    </div>
  );
}

function AccountMenu({ me, setPage, onShare, onLogout }) {
  const [open, setOpen] = useState(false);
  const menuRef = useRef(null);
  const username = me.user?.username || me.user?.name || "Account";

  useEffect(() => {
    const close = (event) => {
      if (menuRef.current && !menuRef.current.contains(event.target)) setOpen(false);
    };
    document.addEventListener("mousedown", close);
    return () => document.removeEventListener("mousedown", close);
  }, []);

  const go = (nextPage) => {
    setOpen(false);
    setPage(nextPage);
  };

  const share = () => {
    setOpen(false);
    onShare();
  };

  return (
    <div className="account-wrap" ref={menuRef}>
      <button className="account-trigger" onClick={() => setOpen(!open)} title="Account menu">
        <LucideIcon name="circle-user-round" label="Account" />
        <span>{username}</span>
        <LucideIcon name="chevron-down" label="Open menu" />
      </button>
      {open && (
        <div className="account-menu">
          <button onClick={() => go("dashboard:feed")}>
            <LucideIcon name="layout-dashboard" label="Dashboard" />
            <span>Dashboard</span>
          </button>
          <button onClick={() => go("dashboard:settings")}>
            <LucideIcon name="user-pen" label="Edit profile" />
            <span>Edit profile</span>
          </button>
          <button onClick={() => go("dashboard:settings")}>
            <LucideIcon name="settings" label="Account settings" />
            <span>Account settings</span>
          </button>
          <button onClick={share}>
            <LucideIcon name="share-2" label="Share profile" />
            <span>Share profile</span>
          </button>
          <button className="danger-link" onClick={onLogout}>
            <LucideIcon name="log-out" label="Logout" />
            <span>Logout</span>
          </button>
        </div>
      )}
    </div>
  );
}

function HeaderLocation({ user, setMe, notify }) {
  const savedLabel = [user.preferredCity, user.preferredState].filter(Boolean).join(", ");
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState(savedLabel || "");
  const [picked, setPicked] = useState(user.preferredCity && user.preferredState ? { city: user.preferredCity, state: user.preferredState, label: savedLabel } : null);
  const boxRef = useRef(null);

  useEffect(() => {
    setQuery(savedLabel || "");
    setPicked(user.preferredCity && user.preferredState ? { city: user.preferredCity, state: user.preferredState, label: savedLabel } : null);
  }, [user.preferredCity, user.preferredState]);

  useEffect(() => {
    const close = (event) => {
      if (boxRef.current && !boxRef.current.contains(event.target)) setOpen(false);
    };
    document.addEventListener("mousedown", close);
    return () => document.removeEventListener("mousedown", close);
  }, []);

  const matches = query.trim()
    ? locationOptions.filter((option) => option.label.toLowerCase().includes(query.toLowerCase())).slice(0, 8)
    : locationOptions.slice(0, 6);

  const save = async () => {
    if (!picked) return notify("Choose location", "Please select a location from the suggestions.");
    const data = await api("/api/profile/location", { method: "POST", body: JSON.stringify({ state: picked.state, city: picked.city }) });
    setMe((current) => ({ ...current, user: data.user }));
    setOpen(false);
    notify("Location saved", `Showing nearby results for ${picked.label}.`);
  };

  const clearLocation = async (event) => {
    event.stopPropagation();
    const data = await api("/api/profile/location", { method: "POST", body: JSON.stringify({ state: "", city: "" }) });
    setMe((current) => ({ ...current, user: data.user }));
    setQuery("");
    setPicked(null);
    setOpen(true);
    notify("Location cleared", "Choose another location or leave it unset.");
  };

  return (
    <div className="header-location" ref={boxRef}>
      <button className="location-trigger" onClick={() => setOpen(!open)} title="Set location">
        <LucideIcon name="map-pin" label="Location" />
        <span>{savedLabel || "Set location"}</span>
        {savedLabel && (
          <span className="location-clear" onClick={clearLocation} role="button" tabIndex="0" title="Clear location">
            <LucideIcon name="x" label="Clear location" />
          </span>
        )}
      </button>
      {open && (
        <div className="location-popover">
          <label>Location</label>
          <input value={query} placeholder="Type city or state" onChange={(event) => {
            setQuery(event.target.value);
            setPicked(null);
          }} autoFocus />
          <div className="location-suggestions">
            {matches.map((option) => (
              <button key={option.label} onClick={() => {
                setPicked(option);
                setQuery(option.label);
              }}>
                <LucideIcon name="map-pin" label="Location" />
                <span>{option.label}</span>
              </button>
            ))}
            {!matches.length && <p className="muted">No matching location found.</p>}
          </div>
          <button className="btn location-save" onClick={save}>Save location</button>
        </div>
      )}
    </div>
  );
}

function ShareProfileModal({ title, url, notify, onClose }) {
  const [copied, setCopied] = useState(false);
  const shareText = `${title} - ${url}`;
  const encodedText = encodeURIComponent(shareText);
  const encodedUrl = encodeURIComponent(url);

  const copyUrl = async () => {
    try {
      await navigator.clipboard.writeText(url);
      setCopied(true);
      notify("Profile link copied", "You can share it anywhere now.");
    } catch (error) {
      notify("Copy failed", error.message);
    }
  };

  const shareNative = async () => {
    try {
      if (navigator.share) await navigator.share({ title, text: title, url });
      else await copyUrl();
    } catch {}
  };

  return (
    <div className="modal-backdrop" onMouseDown={onClose}>
      <section className="share-profile-modal" onMouseDown={(event) => event.stopPropagation()}>
        <div className="share-modal-head">
          <div>
            <span className="eyebrow">Share profile</span>
            <h2>{title}</h2>
          </div>
          <button className="icon-btn" onClick={onClose} aria-label="Close share profile">
            <LucideIcon name="x" label="Close" />
          </button>
        </div>
        <div className="share-url-box">
          <input value={url} readOnly />
          <button className="btn" onClick={copyUrl}>{copied ? "Copied" : "Copy URL"}</button>
        </div>
        <div className="share-options">
          <button className="ghost" onClick={shareNative}>
            <LucideIcon name="send" label="Share" />
            <span>Share</span>
          </button>
          <a className="ghost" href={`https://wa.me/?text=${encodedText}`} target="_blank" rel="noreferrer">
            <LucideIcon name="message-circle" label="WhatsApp" />
            <span>WhatsApp</span>
          </a>
          <a className="ghost" href={`mailto:?subject=${encodeURIComponent(title)}&body=${encodedUrl}`}>
            <LucideIcon name="mail" label="Email" />
            <span>Email</span>
          </a>
          <a className="ghost" href={url} target="_blank" rel="noreferrer">
            <LucideIcon name="external-link" label="Open" />
            <span>Open profile</span>
          </a>
        </div>
      </section>
    </div>
  );
}

function Home({ setPage, notify, me }) {
  const [businesses, setBusinesses] = useState([]);
  const [stats, setStats] = useState({ topSellers: [], highlightedItems: [] });
  const [filters, setFilters] = useState({ q: "", category: "", subCategory: "" });
  const [slide, setSlide] = useState(0);
  const [categorySlide, setCategorySlide] = useState(0);
  const [activeSuper, setActiveSuper] = useState(SUPER_CATEGORIES[0]);
  const latestBusinesses = businesses
    .slice()
    .slice(0, 5);
  const visibleBusinesses = latestBusinesses.slice(slide, slide + 3);
  const visibleSuperCategories = SUPER_CATEGORIES.slice(categorySlide, categorySlide + 4);

  const load = async () => {
    const params = new URLSearchParams(Object.entries(filters).filter(([, value]) => value));
    const data = await api(`/api/businesses?${params}`);
    setBusinesses(data.businesses);
    setStats(data.stats || { topSellers: [], highlightedItems: [] });
  };

  useEffect(() => {
    load().catch((error) => notify("Could not load businesses", error.message));
  }, [filters.q, me.user?.preferredState, me.user?.preferredCity]);

  const nextSlide = () => setSlide((current) => Math.min(current + 1, Math.max(0, latestBusinesses.length - 3)));
  const previousSlide = () => setSlide((current) => Math.max(0, current - 1));
  const nextCategorySlide = () => setCategorySlide((current) => Math.min(current + 1, Math.max(0, SUPER_CATEGORIES.length - 4)));
  const previousCategorySlide = () => setCategorySlide((current) => Math.max(0, current - 1));
  const pickCategory = (category) => {
    setFilters({ q: "", category, subCategory: "" });
    setSlide(0);
  };
  const pickSubCategory = (category, subCategory) => {
    setFilters({ q: subCategory, category: "", subCategory: "" });
    setSlide(0);
  };
  const clearCategory = () => {
    setFilters({ q: "", category: "", subCategory: "" });
    setSlide(0);
  };

  return (
    <main className="page home-page">
      <section className="clean-search">
        <span className="eyebrow">CitySoochna</span>
        <h1>Find businesses near you.</h1>
        <p>{me.user?.preferredCity ? `Prioritizing ${me.user.preferredCity}, ${me.user.preferredState}.` : "Set your location in the header to see nearby businesses first."}</p>

        <div className="search-grid single-search-grid">
          <div className="field search-field">
            <label>Search business</label>
            <input placeholder="Search business, catalog, service" value={filters.q} onChange={(event) => {
              setFilters({ ...filters, q: event.target.value, category: "", subCategory: "" });
              setSlide(0);
            }} />
          </div>
        </div>
        <button className="btn" onClick={() => setPage(me.user ? "dashboard" : "onboarding")}>List your business</button>
      </section>

      <section className="category-browser">
        <div className="slider-head">
          <div>
            <h2>Browse categories</h2>
            <p>Choose a broad area, then dive into business types and products.</p>
          </div>
          <div className="slider-controls">
            <button className="ghost" onClick={previousCategorySlide} disabled={categorySlide === 0}>Prev</button>
            <button className="ghost" onClick={nextCategorySlide} disabled={categorySlide >= Math.max(0, SUPER_CATEGORIES.length - 4)}>Next</button>
          </div>
        </div>
        <div className="super-category-slider">
          {visibleSuperCategories.map((group) => (
            <button className={`super-category-card ${activeSuper.name === group.name ? "active" : ""}`} key={group.name} onClick={() => setActiveSuper(group)}>
              <LucideIcon name={group.icon} label={group.name} />
              <span>{group.name}</span>
              <small>{group.categories.length} categories</small>
            </button>
          ))}
        </div>
        <div className="category-dive">
          <div className="category-dive-head">
            <strong>{activeSuper.name}</strong>
            {(filters.category || filters.subCategory || filters.q) && <button className="ghost compact-btn" onClick={clearCategory}>Clear</button>}
          </div>
          {activeSuper.categories.map((category) => (
            <div className="category-cluster" key={category}>
              <button className={`category-pill ${filters.category === category && !filters.subCategory ? "active" : ""}`} onClick={() => pickCategory(category)}>{category}</button>
              <div>
                {(BUSINESS_CATEGORIES[category] || []).slice(0, 10).map((item) => (
                  <button className={`sub-category-chip ${filters.q === item ? "active" : ""}`} key={item} onClick={() => pickSubCategory(category, item)}>{item}</button>
                ))}
              </div>
            </div>
          ))}
        </div>
      </section>

      <section className="slider-section">
        <div className="slider-head">
          <div>
            <h2>{filters.category || filters.q ? `${filters.subCategory || filters.category || filters.q} businesses` : "Latest businesses"}</h2>
            <p>{filters.category || filters.q ? "Showing matches from your selected category or search." : "Showing 3 of latest 5 listings."}</p>
          </div>
          <div className="slider-controls">
            <button className="ghost" onClick={previousSlide} disabled={slide === 0}>Prev</button>
            <button className="ghost" onClick={nextSlide} disabled={slide >= Math.max(0, latestBusinesses.length - 3)}>Next</button>
          </div>
        </div>
        <div className="business-slider">
          {visibleBusinesses.map((business) => <BusinessCard key={business.id} business={business} setPage={setPage} me={me} notify={notify} />)}
          {!latestBusinesses.length && <div className="panel">No businesses found for this location.</div>}
        </div>
      </section>

      <section className="home-highlights">
        <div className="slider-head">
          <div>
            <h2>Highlighted products</h2>
            <p>Useful catalog items from businesses on CitySoochna.</p>
          </div>
        </div>
        <div className="highlight-product-grid">
          {(stats.highlightedItems || []).slice(0, 4).map((item) => (
            <article className="highlight-product-card" key={item.id}>
              {item.image ? <button className="highlight-product-image" onClick={() => setPage(`item:${item.id}`)}><img src={assetUrl(item.image)} alt="" /></button> : <button className="highlight-product-image empty" onClick={() => setPage(`item:${item.id}`)}><LucideIcon name="package" label="Product" /></button>}
              <div>
                <span className="tag">{item.category || "Product"}</span>
                <h3>{item.name}</h3>
                <p className="muted">{item.business?.businessName || "Business"}{item.business?.city ? ` · ${item.business.city}` : ""}</p>
                <div className="card-actions">
                  <button className="ghost compact-btn" onClick={() => setPage(`item:${item.id}`)}>View item</button>
                  <ShareButton url={`${window.location.origin}/items/${item.id}`} title={item.name} />
                </div>
              </div>
            </article>
          ))}
        </div>
      </section>

      <section className="home-highlights">
        <div className="slider-head">
          <div>
            <h2>Most active sellers</h2>
            <p>Businesses with strong catalog and enquiry activity.</p>
          </div>
        </div>
        <div className="seller-strip">
          {(stats.topSellers || []).slice(0, 4).map((seller) => (
            <button className="seller-chip-card" key={seller.id} onClick={() => setPage(`business:${seller.id}`)}>
              <span>{seller.businessName}</span>
              <small>{seller.itemCount || 0} items · {seller.enquiryCount || 0} enquiries</small>
            </button>
          ))}
        </div>
      </section>
    </main>
  );
}

function BusinessCard({ business, setPage, me = {}, notify = () => {} }) {
  const [saved, setSaved] = useState(Boolean(business.savedByMe));
  const [saveCount, setSaveCount] = useState(business.savedCount || 0);
  const url = `${window.location.origin}${business.seoPath || `/businesses/${business.id}`}`;
  const toggleSave = async () => {
    if (!me.user) return notify("Login required", "Please login to save this business.");
    try {
      const data = await api(`/api/businesses/${business.id}/save`, { method: saved ? "DELETE" : "POST" });
      setSaved(Boolean(data.business.savedByMe));
      setSaveCount(data.business.savedCount || 0);
      notify(data.business.savedByMe ? "Business saved" : "Removed from saved", data.business.savedByMe ? "You can find it in Saved Businesses." : "Business removed from your saved list.");
    } catch (error) {
      notify("Save failed", error.message);
    }
  };
  return (
    <article className="business-card">
      <div className="business-banner" style={{ backgroundImage: (business.bannerImages?.[0] || business.bannerImage) ? `url(${assetUrl(business.bannerImages?.[0] || business.bannerImage)})` : undefined }} />
      <div className="business-content">
        {business.profileImage && <img className="avatar" src={assetUrl(business.profileImage)} alt="" />}
        <p><span className="tag">{business.category}</span></p>
        <h3>{business.businessName}</h3>
        <p className="muted">{business.city}, {business.state}</p>
        <p>{business.description || business.tagline}</p>
        <p className="muted">{business.followerCount || 0} follower{business.followerCount === 1 ? "" : "s"} · {saveCount} saved</p>
        <div className="card-actions">
          <button className="btn" onClick={() => setPage(business.seoPath ? `businessSeo:${business.seoPath.slice(1)}` : `business:${business.id}`)}>View business</button>
          <button className={saved ? "btn compact-btn" : "ghost compact-btn"} onClick={toggleSave}>{saved ? "Saved" : "Save"}</button>
          <ShareButton url={url} title={business.businessName} />
        </div>
      </div>
    </article>
  );
}

function BannerSlider({ images = [] }) {
  const [index, setIndex] = useState(0);
  const realImages = images.filter(Boolean);
  if (!realImages.length) return <div className="business-banner detail-banner" />;
  return (
    <div className="business-banner detail-banner" style={{ backgroundImage: `url(${assetUrl(realImages[index])})` }}>
      {realImages.length > 1 && (
        <div className="banner-controls">
          <button className="ghost" onClick={() => setIndex((index - 1 + realImages.length) % realImages.length)}>Prev</button>
          <button className="ghost" onClick={() => setIndex((index + 1) % realImages.length)}>Next</button>
        </div>
      )}
    </div>
  );
}

function Onboarding({ setPage, setMe, notify }) {
  const [step, setStep] = useState(1);
  const [user, setUser] = useState({ name: "", username: "", email: "", phone: "", password: "", termsAccepted: false, dataProcessingConsent: false, marketingConsent: false });
  const [legalOpen, setLegalOpen] = useState("");
  const [business, setBusiness] = useState({
    businessName: "", tagline: "", category: "", description: "", website: "",
    subCategory: "", instagram: "", facebook: "", linkedin: "", whatsapp: "",
    businessPhone: "", businessEmail: "", businessAddress: "", gstNumber: "", businessIdNumber: "",
    city: "", state: "", address: "", pincode: "", latitude: "", longitude: "",
    profileImage: "", bannerImage: ""
  });
  const [personal, setPersonal] = useState({ name: "", phone: "", role: "Owner", personalAddress: "" });

  const register = async (provider = "email") => {
    if (!user.termsAccepted || !user.dataProcessingConsent) {
      notify("Consent required", "Please read and accept the Terms, Privacy Policy, and data-use consent.");
      return;
    }
    const data = await api("/api/auth/register", { method: "POST", body: JSON.stringify({ ...user, provider }) });
    setMe({ user: data.user, business: null });
    setPersonal({ name: data.user.name, phone: data.user.phone || "", role: "Owner" });
    setStep(2);
  };

  const saveBusiness = async () => {
    const data = await api("/api/onboarding/business", {
      method: "POST",
      body: JSON.stringify({
        ...business,
        socials: {
          instagram: business.instagram,
          facebook: business.facebook,
          linkedin: business.linkedin,
          whatsapp: business.whatsapp
        }
      })
    });
    setMe((current) => ({ ...current, business: data.business }));
    setStep(3);
  };

  const savePersonal = async () => {
    const data = await api("/api/profile/personal", { method: "POST", body: JSON.stringify(personal) });
    const me = await api("/api/me");
    setMe({ ...me, user: data.user });
    notify("Business page ready", "You can now add catalog items and receive enquiries.");
    setPage("dashboard:feed");
  };

  const pickImage = async (event, key) => {
    const dataUrl = await fileToDataUrl(event.target.files?.[0]);
    setBusiness((current) => ({ ...current, [key]: dataUrl }));
  };

  const businessCities = business.state ? INDIAN_LOCATIONS[business.state] || [] : [];

  return (
    <main className="page form-page">
      <div className="steps">
        <div className={`step ${step === 1 ? "active" : ""}`}>Registration</div>
        <div className={`step ${step === 2 ? "active" : ""}`}>Business details</div>
        <div className={`step ${step === 3 ? "active" : ""}`}>Personal details</div>
      </div>

      {step === 1 && (
        <section className="panel">
          <h2>Create your account</h2>
          <div className="form-grid">
            <Field label="Full name" value={user.name} onChange={(value) => setUser({ ...user, name: value })} />
            <Field label="Username" value={user.username} onChange={(value) => setUser({ ...user, username: value })} />
            <Field label="Gmail / email" type="email" value={user.email} onChange={(value) => setUser({ ...user, email: value })} />
            <Field label="Mobile number" value={user.phone} onChange={(value) => setUser({ ...user, phone: value })} />
            <PasswordField label="Password" value={user.password} onChange={(value) => setUser({ ...user, password: value })} />
          </div>
          <ConsentFields value={user} onChange={setUser} openLegal={setLegalOpen} />
          <p>
            <button className="btn" onClick={() => register("email")}>Continue</button>{" "}
            <button className="ghost" onClick={() => register("google")}>Continue with Gmail</button>
          </p>
        </section>
      )}

      {step === 2 && (
        <section className="panel">
          <h2>Business details</h2>
          <div className="form-grid">
            <Field label="Business name" value={business.businessName} onChange={(value) => setBusiness({ ...business, businessName: value })} />
            <div className="field">
              <label>Category</label>
              <select value={business.category} onChange={(event) => setBusiness({ ...business, category: event.target.value, subCategory: "" })}>
                <option value="">Select category</option>
                {categoryNames.map((category) => <option key={category}>{category}</option>)}
              </select>
            </div>
            <div className="field">
              <label>Sub category</label>
              <select value={business.subCategory} disabled={!business.category} onChange={(event) => setBusiness({ ...business, subCategory: event.target.value })}>
                <option value="">{business.category ? "Select sub category" : "Select category first"}</option>
                {(BUSINESS_CATEGORIES[business.category] || []).map((item) => <option key={item}>{item}</option>)}
              </select>
            </div>
            <Field label="Short tagline" value={business.tagline} onChange={(value) => setBusiness({ ...business, tagline: value })} />
            <Field label="Website" value={business.website} onChange={(value) => setBusiness({ ...business, website: value })} />
            <TextField label="Business description" value={business.description} onChange={(value) => setBusiness({ ...business, description: value })} />
            <Field label="Instagram" value={business.instagram} onChange={(value) => setBusiness({ ...business, instagram: value })} />
            <Field label="Facebook" value={business.facebook} onChange={(value) => setBusiness({ ...business, facebook: value })} />
            <Field label="LinkedIn" value={business.linkedin} onChange={(value) => setBusiness({ ...business, linkedin: value })} />
            <Field label="WhatsApp" value={business.whatsapp} onChange={(value) => setBusiness({ ...business, whatsapp: value })} />
            <Field label="Business phone optional" value={business.businessPhone} onChange={(value) => setBusiness({ ...business, businessPhone: value })} />
            <Field label="Business email optional" type="email" value={business.businessEmail} onChange={(value) => setBusiness({ ...business, businessEmail: value })} />
            <Field label="GST number optional" value={business.gstNumber} onChange={(value) => setBusiness({ ...business, gstNumber: value })} />
            <Field label="Business ID number optional" value={business.businessIdNumber} onChange={(value) => setBusiness({ ...business, businessIdNumber: value })} />
            <div className="field">
              <label>State</label>
              <select value={business.state} onChange={(event) => setBusiness({ ...business, state: event.target.value, city: "" })}>
                <option value="">Select state</option>
                {stateNames.map((state) => <option key={state}>{state}</option>)}
              </select>
            </div>
            <div className="field">
              <label>City</label>
              <select value={business.city} disabled={!business.state} onChange={(event) => setBusiness({ ...business, city: event.target.value })}>
                <option value="">{business.state ? "Select city" : "Select state first"}</option>
                {businessCities.map((city) => <option key={city}>{city}</option>)}
              </select>
            </div>
            <Field label="Pincode" value={business.pincode} onChange={(value) => setBusiness({ ...business, pincode: value })} />
            <Field label="Full address" value={business.address} onChange={(value) => setBusiness({ ...business, address: value })} full />
            <Field label="Business address if different" value={business.businessAddress} onChange={(value) => setBusiness({ ...business, businessAddress: value })} full />
            <Field label="Latitude" value={business.latitude} onChange={(value) => setBusiness({ ...business, latitude: value })} />
            <Field label="Longitude" value={business.longitude} onChange={(value) => setBusiness({ ...business, longitude: value })} />
            <UploadControl label="Profile picture" hint="Upload logo or owner photo." onChange={(event) => pickImage(event, "profileImage")} />
            <UploadControl label="Profile banner" hint="Upload a wide cover image." onChange={(event) => pickImage(event, "bannerImage")} />
          </div>
          <p><button className="btn" onClick={saveBusiness}>Continue</button></p>
        </section>
      )}

      {step === 3 && (
        <section className="panel">
          <h2>Personal details</h2>
          <div className="form-grid">
            <Field label="Your name" value={personal.name} onChange={(value) => setPersonal({ ...personal, name: value })} />
            <Field label="Your phone" value={personal.phone} onChange={(value) => setPersonal({ ...personal, phone: value })} />
            <Field label="Role in business" value={personal.role} onChange={(value) => setPersonal({ ...personal, role: value })} />
            <Field label="Personal address" value={personal.personalAddress} onChange={(value) => setPersonal({ ...personal, personalAddress: value })} full />
          </div>
          <p><button className="btn" onClick={savePersonal}>Open dashboard</button></p>
        </section>
      )}
      {legalOpen && <LegalModal type={legalOpen} onClose={() => setLegalOpen("")} />}
    </main>
  );
}

function Dashboard({ me, setMe, refreshKey, notify, setPage, initialTab }) {
  const firstTab = initialTab === "profile" ? "about" : initialTab;
  const [tab, setTab] = useState(firstTab || "feed");
  const [data, setData] = useState({ business: null, items: [], enquiries: [], notifications: [] });
  const [item, setItem] = useState({ name: "", description: "", category: "", subCategory: "", price: "", minQty: "", stock: "", unit: "", status: "Available", image: "" });
  const [itemFilter, setItemFilter] = useState({ category: "", subCategory: "" });
  const [cropModal, setCropModal] = useState(null);

  const load = async () => {
    const response = await api("/api/dashboard");
    setData(response);
  };

  useEffect(() => {
    load().catch(() => {});
  }, [refreshKey]);

  useEffect(() => {
    if (initialTab) setTab(initialTab === "profile" ? "about" : initialTab);
  }, [initialTab]);

  const chooseTab = (nextTab) => {
    setTab(nextTab);
    setPage(nextTab === "catalog" ? "dashboard" : `dashboard:${nextTab}`);
  };

  const createItem = async () => {
    const response = await api("/api/items", { method: "POST", body: JSON.stringify(item) });
    setData((current) => ({ ...current, items: [response.item, ...current.items] }));
    setItem({ name: "", description: "", category: "", subCategory: "", price: "", minQty: "", stock: "", unit: "", status: "Available", image: "" });
    notify("Item added", "Your catalog is updated.");
    chooseTab("catalog");
  };

  const deleteItem = async (id) => {
    await api(`/api/items/${id}`, { method: "DELETE" });
    setData((current) => ({ ...current, items: current.items.filter((entry) => entry.id !== id) }));
  };
  const suggestions = getProfileSuggestions(data.business || me.business, data.items);
  const business = data.business || me.business;
  const filteredItems = data.items.filter((entry) => (!itemFilter.category || entry.category === itemFilter.category) && (!itemFilter.subCategory || entry.subCategory === itemFilter.subCategory));

  const saveBusinessMedia = async (patch) => {
    const response = await api("/api/onboarding/business", { method: "POST", body: JSON.stringify({ ...business, ...patch }) });
    setData((current) => ({ ...current, business: response.business }));
    setMe((current) => ({ ...current, business: response.business }));
    return response.business;
  };

  const uploadProfilePicture = async (event) => {
    const source = await fileToDataUrl(event.target.files?.[0]);
    event.target.value = "";
    if (!source) return;
    setCropModal({ kind: "profile", title: "Adjust profile picture", source, targetWidth: 512, targetHeight: 512 });
  };

  const uploadDashboardBanner = async (event) => {
    const source = await fileToDataUrl(event.target.files?.[0]);
    event.target.value = "";
    if (!source) return;
    setCropModal({ kind: "banner", title: "Adjust profile banner", source, targetWidth: 1600, targetHeight: 520 });
  };

  const saveCrop = async ({ kind, image }) => {
    if (kind === "profile") {
      await saveBusinessMedia({ profileImage: image });
      notify("Profile picture updated", "Your cropped photo was saved.");
    } else {
      const next = [image, ...(business.bannerImages || []).filter(Boolean)].slice(0, 5);
      await saveBusinessMedia({ bannerImage: image, bannerImages: next });
      notify("Banner updated", "Your adjusted banner was saved.");
    }
    setCropModal(null);
  };

  const openDashboardNotification = (note) => {
    if (note.target?.type === "chat" && note.target.id) return setPage(`chat:${note.target.id}`);
    if (note.target?.type === "enquiry" && note.target.id) return setPage(`enquiry:${note.target.id}`);
    if (note.target?.type === "business" && note.target.id) return setPage(`business:${note.target.id}`);
    if (note.target?.type === "admin") {
      if (note.target.section) sessionStorage.setItem("adminSection", note.target.section);
      return setPage("admin");
    }
  };

  if (!me.user) return <main className="page"><div className="panel">Please create an account first.</div></main>;
  if (!data.business && !me.business) return <ProfileHub user={me.user} setPage={setPage} initialTab={initialTab} />;

  return (
    <main className="page dashboard-grid">
      <UserSidebar user={me.user} business={business} active={tab} chooseTab={chooseTab} onProfileUpload={uploadProfilePicture} />

      <section className="panel">
        <DashboardBannerControl business={business} onBannerUpload={uploadDashboardBanner} />
        <ApprovalNotice business={business} />
        {tab === "about" && <AboutProfile user={me.user} business={business} setMe={setMe} notify={notify} reload={load} onEdit={() => chooseTab("settings")} />}
        {tab === "settings" && <EditProfile me={me} business={business} setMe={setMe} notify={notify} reload={load} onClose={() => chooseTab("about")} />}
        {tab === "feed" && <BusinessFeed me={me} notify={notify} />}
        {tab === "saved" && <SavedBusinesses me={me} notify={notify} setPage={setPage} />}
        {tab === "analytics" && <AnalyticsPanel analytics={data.analytics} />}
        {tab === "catalog" && (
          <>
            <ProfileSuggestions suggestions={suggestions} />
            <div className="detail-head">
              <div>
                <h2>Catalog products</h2>
                <p className="muted">View, filter, share, or remove your listed products and services.</p>
              </div>
              <div className="card-actions">
                <button className="btn compact-btn" onClick={() => chooseTab("add-item")}>Add item</button>
                <button className="ghost compact-btn" onClick={() => setPage(`catalog:${business.id}`)}>View catalog page</button>
                <button className="btn compact-btn" onClick={() => chooseTab("quotation")}>Create quotation</button>
              </div>
            </div>
            <div className="form-grid compact-form">
              <CategorySelect value={itemFilter.category} subValue={itemFilter.subCategory} onChange={(category, subCategory) => setItemFilter({ category, subCategory })} />
            </div>
            <div className="item-list">
              {filteredItems.map((entry) => (
                <article className="item-card" key={entry.id}>
                  {entry.image && <img src={assetUrl(entry.image)} alt="" />}
                  <h3>{entry.name}</h3>
                  <p className="muted">{entry.category} · {entry.status}</p>
                  <p>{entry.description}</p>
                  <p><strong>{entry.price || "Price on enquiry"}</strong></p>
                  <p className="muted">MOQ: {entry.minQty || "Not set"} · Stock: {entry.stock || "Not set"} {entry.unit}</p>
                  <div className="card-actions">
                    <button className="ghost" onClick={() => setPage(`item:${entry.id}`)}>View item</button>
                    <ShareButton url={`${window.location.origin}/items/${entry.id}`} title={entry.name} />
                    <button className="danger" onClick={() => deleteItem(entry.id)}>Delete</button>
                  </div>
                </article>
              ))}
              {!filteredItems.length && <div className="panel">No catalog products found. Add your first item to start building the catalog.</div>}
            </div>
          </>
        )}

        {tab === "add-item" && (
          <>
            <div className="detail-head">
              <div>
                <h2>Add catalog item</h2>
                <p className="muted">Create a new product or service for your catalog.</p>
              </div>
              <button className="ghost compact-btn" onClick={() => chooseTab("catalog")}>Back to catalog</button>
            </div>
            <div className="form-grid">
              <Field label="Item name" value={item.name} onChange={(value) => setItem({ ...item, name: value })} />
              <CategorySelect value={item.category} subValue={item.subCategory} onChange={(category, subCategory) => setItem({ ...item, category, subCategory })} />
              <TextField label="Description" value={item.description} onChange={(value) => setItem({ ...item, description: value })} />
              <Field label="Pricing optional" value={item.price} onChange={(value) => setItem({ ...item, price: value })} placeholder="₹500, Negotiable, On enquiry" />
              <Field label="Minimum qty to order" value={item.minQty} onChange={(value) => setItem({ ...item, minQty: value })} />
              <Field label="Total stock" value={item.stock} onChange={(value) => setItem({ ...item, stock: value })} />
              <Field label="Unit" value={item.unit} onChange={(value) => setItem({ ...item, unit: value })} placeholder="piece, kg, box" />
              <div className="field">
                <label>Status</label>
                <select value={item.status} onChange={(event) => setItem({ ...item, status: event.target.value })}>
                  <option>Available</option>
                  <option>Limited stock</option>
                  <option>Made to order</option>
                  <option>Out of stock</option>
                </select>
              </div>
              <UploadControl label="Item image" hint="Add one clear product image." onChange={async (event) => setItem({ ...item, image: await fileToDataUrl(event.target.files?.[0]) })} />
            </div>
            <p><button className="btn" onClick={createItem}>Add item</button></p>
          </>
        )}

        {tab === "enquiries" && <Enquiries enquiries={data.enquiries} setPage={setPage} notify={notify} reload={load} canManage={Boolean(business)} />}
        {tab === "quotation" && <QuotationBuilder items={data.items} notify={notify} reload={load} openDownloads={() => chooseTab("downloads")} />}
        {tab === "downloads" && <DownloadsPage quotations={data.quotations || []} notify={notify} reload={load} />}
        {tab === "messages" && <Messages notify={notify} me={me} setPage={setPage} />}
        {tab === "support" && <SupportForm notify={notify} />}
        {tab === "notifications" && (
          <>
            <h2>Notifications</h2>
            {data.notifications.map((note) => <button className="notification-row" key={note.id} onClick={() => openDashboardNotification(note)}><strong>{note.title}</strong><br /><span className="muted">{note.message}</span></button>)}
            {!data.notifications.length && <p className="muted">No notifications yet.</p>}
          </>
        )}
      </section>
      {cropModal && <CropModal config={cropModal} onClose={() => setCropModal(null)} onSave={saveCrop} />}
    </main>
  );
}

function CropModal({ config, onClose, onSave }) {
  const [zoom, setZoom] = useState(1);
  const [positionX, setPositionX] = useState(50);
  const [positionY, setPositionY] = useState(50);
  const [saving, setSaving] = useState(false);
  const frameRef = useRef(null);
  const dragRef = useRef(null);
  const isBanner = config.kind === "banner";

  const clamp = (value) => Math.max(0, Math.min(100, value));
  const changeZoom = (amount) => setZoom((current) => Math.max(1, Math.min(2.4, Number((current + amount).toFixed(2)))));

  const startDrag = (event) => {
    event.preventDefault();
    dragRef.current = { x: event.clientX, y: event.clientY, positionX, positionY };
    window.addEventListener("pointermove", moveDrag);
    window.addEventListener("pointerup", stopDrag);
  };

  const moveDrag = (event) => {
    if (!dragRef.current || !frameRef.current) return;
    event.preventDefault();
    const rect = frameRef.current.getBoundingClientRect();
    const deltaX = event.clientX - dragRef.current.x;
    const deltaY = event.clientY - dragRef.current.y;
    setPositionX(clamp(dragRef.current.positionX - (deltaX / rect.width) * 100));
    setPositionY(clamp(dragRef.current.positionY - (deltaY / rect.height) * 100));
  };

  const stopDrag = () => {
    dragRef.current = null;
    window.removeEventListener("pointermove", moveDrag);
    window.removeEventListener("pointerup", stopDrag);
  };

  const save = async () => {
    setSaving(true);
    const image = await cropDataUrl(config.source, config.targetWidth, config.targetHeight, zoom, positionX, positionY);
    await onSave({ kind: config.kind, image });
    setSaving(false);
  };

  return (
    <div className="modal-backdrop" role="dialog" aria-modal="true">
      <div className="crop-modal">
        <div className="detail-head">
          <div>
            <h2>{config.title}</h2>
            <p className="muted">{isBanner ? "Drag the banner to position it, then use + or - to zoom." : "Drag the photo to position it, then use + or - to zoom."}</p>
          </div>
          <button className="ghost compact-btn" onClick={onClose}>Close</button>
        </div>

        <div className={`crop-frame ${isBanner ? "banner-crop" : "profile-crop"}`} ref={frameRef} onPointerDown={startDrag}>
          <img src={config.source} alt="" style={{ objectPosition: `${positionX}% ${positionY}%`, transform: `scale(${zoom})`, transformOrigin: `${positionX}% ${positionY}%` }} />
          <div className="crop-zoom-actions" onPointerDown={(event) => event.stopPropagation()}>
            <button type="button" onClick={() => changeZoom(-0.12)} aria-label="Zoom out">-</button>
            <span>{Math.round(zoom * 100)}%</span>
            <button type="button" onClick={() => changeZoom(0.12)} aria-label="Zoom in">+</button>
          </div>
        </div>

        <div className="card-actions crop-actions">
          <button className="btn" onClick={save} disabled={saving}>{saving ? "Saving..." : "Save crop"}</button>
          <button className="ghost" onClick={() => {
            setZoom(1);
            setPositionX(50);
            setPositionY(50);
          }}>Reset</button>
          <button className="ghost" onClick={onClose}>Cancel</button>
        </div>
      </div>
    </div>
  );
}

function UserSidebar({ user, business, active, chooseTab, onProfileUpload }) {
  return (
    <aside className="panel side-nav">
      <div className="dashboard-profile">
        <div className="dashboard-cover" style={{ backgroundImage: `url(${assetUrl(business?.bannerImages?.[0] || business?.bannerImage || user?.bannerImage || "")})` }} />
        <div className="dashboard-avatar-wrap">
          {(business?.profileImage || user?.profileImage) ? <img src={assetUrl(business?.profileImage || user?.profileImage)} alt="" /> : <div className="dashboard-avatar-placeholder">{(business?.businessName || user?.name || "A").slice(0, 1)}</div>}
          {onProfileUpload && (
            <label className="mini-upload">
              <input type="file" accept="image/*" onChange={onProfileUpload} />
              Update photo
            </label>
          )}
        </div>
        <h3>{business?.businessName || user?.name || "Account"}</h3>
        {!business && <p className="muted">Normal account</p>}
      </div>
        <button className={active === "about" || active === "settings" ? "active" : ""} onClick={() => chooseTab("about")}>About</button>
      <button className={active === "feed" ? "active" : ""} onClick={() => chooseTab("feed")}>Business feed</button>
      <button className={active === "saved" ? "active" : ""} onClick={() => chooseTab("saved")}>Saved businesses</button>
      {business && <button className={active === "catalog" || active === "quotation" ? "active" : ""} onClick={() => chooseTab("catalog")}>Catalog</button>}
      {business && <button className={active === "analytics" ? "active" : ""} onClick={() => chooseTab("analytics")}>Analytics</button>}
      {business && <button className={active === "downloads" ? "active" : ""} onClick={() => chooseTab("downloads")}>Downloads</button>}
      <button className={active === "enquiries" ? "active" : ""} onClick={() => chooseTab("enquiries")}>Enquiries & chat</button>
      <button className={active === "messages" ? "active" : ""} onClick={() => chooseTab("messages")}>Messages</button>
      <button className={active === "support" ? "active" : ""} onClick={() => chooseTab("support")}>Support</button>
    </aside>
  );
}

function DashboardBannerControl({ business, onBannerUpload }) {
  if (!business) return null;
  return (
    <div className="dashboard-banner-control">
      <div className="dashboard-banner-preview" style={{ backgroundImage: `url(${assetUrl(business.bannerImages?.[0] || business.bannerImage || "")})` }} />
      <div>
        <span className="muted">Profile banner</span>
        <label className="mini-upload banner-upload">
          <input type="file" accept="image/*" onChange={onBannerUpload} />
          Update banner
        </label>
      </div>
    </div>
  );
}

function ApprovalNotice({ business }) {
  if (!business || !business.approvalStatus || business.approvalStatus === "approved") return null;
  return (
    <div className={`approval-notice ${business.approvalStatus}`}>
      <strong>{business.approvalStatus === "pending" ? "Waiting for admin approval" : "Business not approved yet"}</strong>
      <span>{business.approvalNote || "Admin will review your business details before it appears publicly."}</span>
    </div>
  );
}

function DashboardDetailShell({ me, setPage, active, children }) {
  const [data, setData] = useState({ business: me.business || null });

  useEffect(() => {
    api("/api/dashboard").then(setData).catch(() => {});
  }, [me.user?.id]);

  const chooseTab = (nextTab) => {
    setPage(nextTab === "catalog" ? "dashboard" : `dashboard:${nextTab}`);
  };

  return (
    <main className="page dashboard-grid">
      <UserSidebar user={me.user} business={data.business || me.business} active={active} chooseTab={chooseTab} />
      <section className="panel dashboard-detail-panel">
        {children}
      </section>
    </main>
  );
}

function getProfileSuggestions(business, items = []) {
  if (!business) return [];
  const checks = [
    ["Add profile picture", !business.profileImage],
    ["Add banner image", !business.bannerImage],
    ["Add business description", !business.description],
    ["Add WhatsApp number", !business.whatsapp && !business.socials?.whatsapp],
    ["Add business email", !business.businessEmail],
    ["Add GST or business ID", !business.gstNumber && !business.businessIdNumber],
    ["Add website or social link", !business.website && !business.socials?.instagram && !business.socials?.facebook],
    ["Add first catalog item", !items.length]
  ];
  return checks.filter(([, missing]) => missing).map(([label]) => label);
}

function ProfileSuggestions({ suggestions }) {
  return (
    <div className="suggestion-box">
      <h3>Tips to make your profile strong</h3>
      {suggestions.length ? (
        <div className="suggestion-list">
          {suggestions.map((item) => <span key={item}>{item}</span>)}
        </div>
      ) : <p className="muted">Your business profile looks complete.</p>}
    </div>
  );
}

function AnalyticsPanel({ analytics }) {
  const metrics = [
    ["Profile views", analytics?.profileViews || 0],
    ["Catalog views", analytics?.catalogViews || 0],
    ["Item views", analytics?.itemViews || 0],
    ["Enquiries", analytics?.enquiries || 0],
    ["Followers", analytics?.followers || 0],
    ["WhatsApp clicks", analytics?.whatsappClicks || 0],
    ["Post reach", analytics?.postReach || 0]
  ];
  return (
    <div className="analytics-panel">
      <div className="detail-head">
        <div>
          <h2>Business analytics</h2>
          <p className="muted">Track discovery, enquiries, followers, and contact intent.</p>
        </div>
      </div>
      <div className="stats-grid compact">
        {metrics.map(([label, value]) => <div className="stat" key={label}><span>{label}</span><strong>{value}</strong></div>)}
      </div>
      <div className="quote-box">
        <h3>Recent activity</h3>
        {(analytics?.recent || []).map((event) => (
          <p key={event.id}><strong>{event.eventType.replaceAll("_", " ")}</strong><br /><span className="muted">{event.createdAt ? new Date(event.createdAt).toLocaleString() : "-"}</span></p>
        ))}
        {!(analytics?.recent || []).length && <p className="muted">No analytics events yet.</p>}
      </div>
    </div>
  );
}

function SavedBusinesses({ me, notify, setPage }) {
  const [businesses, setBusinesses] = useState([]);
  const load = async () => {
    const data = await api("/api/saved-businesses");
    setBusinesses(data.businesses || []);
  };
  useEffect(() => {
    load().catch((error) => notify("Saved unavailable", error.message));
  }, []);
  const remove = async (business) => {
    try {
      await api(`/api/businesses/${business.id}/save`, { method: "DELETE" });
      setBusinesses((current) => current.filter((entry) => entry.id !== business.id));
      notify("Removed from saved", `${business.businessName} was removed.`);
    } catch (error) {
      notify("Remove failed", error.message);
    }
  };
  return (
    <div className="saved-businesses">
      <div className="detail-head">
        <div>
          <h2>Saved businesses</h2>
          <p className="muted">Businesses you want to revisit without following their feed.</p>
        </div>
      </div>
      <div className="business-slider saved-business-grid">
        {businesses.map((business) => (
          <article className="business-card" key={business.id}>
            <div className="business-banner" style={{ backgroundImage: (business.bannerImages?.[0] || business.bannerImage) ? `url(${assetUrl(business.bannerImages?.[0] || business.bannerImage)})` : undefined }} />
            <div className="business-content">
              {business.profileImage && <img className="avatar" src={assetUrl(business.profileImage)} alt="" />}
              <p><span className="tag">{business.category}</span></p>
              <h3>{business.businessName}</h3>
              <p className="muted">{business.city}, {business.state}</p>
              <p>{business.description || business.tagline}</p>
              <div className="card-actions">
                <button className="btn compact-btn" onClick={() => setPage(business.seoPath ? `businessSeo:${business.seoPath.slice(1)}` : `business:${business.id}`)}>View</button>
                <button className="ghost compact-btn" onClick={() => remove(business)}>Remove</button>
                <ShareButton url={`${window.location.origin}${business.seoPath || `/businesses/${business.id}`}`} title={business.businessName} />
              </div>
            </div>
          </article>
        ))}
        {!businesses.length && <div className="quote-box"><h3>No saved businesses yet</h3><p className="muted">Open any business page and click Save to keep it here.</p></div>}
      </div>
    </div>
  );
}

function CategorySelect({ value, subValue, onChange }) {
  return (
    <>
      <div className="field">
        <label>Category</label>
        <select value={value} onChange={(event) => onChange(event.target.value, "")}>
          <option value="">All / select category</option>
          {categoryNames.map((category) => <option key={category}>{category}</option>)}
        </select>
      </div>
      <div className="field">
        <label>Sub category</label>
        <select value={subValue} disabled={!value} onChange={(event) => onChange(value, event.target.value)}>
          <option value="">{value ? "All / select sub category" : "Select category first"}</option>
          {(BUSINESS_CATEGORIES[value] || []).map((item) => <option key={item}>{item}</option>)}
        </select>
      </div>
    </>
  );
}

function AboutProfile({ user, business, setMe, notify, reload, onEdit }) {
  const show = (value) => value || "Not added";
  const socials = business?.socials || {};
  const businessRows = business ? [
    ["Business name", business.businessName],
    ["Category", [business.category, business.subCategory].filter(Boolean).join(" / ")],
    ["Tagline", business.tagline],
    ["Description", business.description],
    ["Website", business.website],
    ["GST number", business.gstNumber],
    ["Business ID", business.businessIdNumber]
  ] : [];
  const contactRows = business ? [
    ["WhatsApp", business.whatsapp || socials.whatsapp],
    ["Business phone", business.businessPhone],
    ["Business email", business.businessEmail],
    ["Instagram", business.instagram || socials.instagram],
    ["Facebook", business.facebook || socials.facebook],
    ["LinkedIn", business.linkedin || socials.linkedin]
  ] : [];
  const addressRows = business ? [
    ["Business address", business.businessAddress || business.address],
    ["City", business.city],
    ["State", business.state],
    ["Pincode", business.pincode],
    ["Latitude", business.latitude],
    ["Longitude", business.longitude]
  ] : [];

  return (
    <div className="about-profile">
      <div className="detail-head">
        <div>
          <h2>About</h2>
          <p className="muted">Saved information visible for this account and business.</p>
        </div>
        <button className="icon-btn pencil-action" onClick={onEdit} title="Profile settings" aria-label="Profile settings">
          <LucideIcon name="pencil" label="Edit" />
        </button>
      </div>

      <div className="about-grid">
        <InfoCard title="Account" rows={[
          ["Name", user?.name],
          ["Username", user?.username],
          ["Email", user?.email],
          ["Phone", user?.phone],
          ["Preferred location", [user?.preferredCity, user?.preferredState].filter(Boolean).join(", ")],
          ["Personal address", user?.personalAddress]
        ]} show={show} />
        {business && <InfoCard title="Business" rows={businessRows} show={show} />}
        {business && <InfoCard title="Contact & social" rows={contactRows} show={show} />}
        {business && <InfoCard title="Location" rows={addressRows} show={show} />}
      </div>
      <EmailVerificationPanel user={user} business={business} setMe={setMe} notify={notify} reload={reload} />
    </div>
  );
}

function EmailVerificationPanel({ user, business, setMe, notify, reload }) {
  const [otp, setOtp] = useState({ user: "", business: "" });
  const [open, setOpen] = useState({ user: false, business: false });
  const [devOtp, setDevOtp] = useState({ user: "", business: "" });

  const requestOtp = async (target) => {
    try {
      const data = await api("/api/email-verification/request", { method: "POST", body: JSON.stringify({ target }) });
      setOpen((current) => ({ ...current, [target]: true }));
      setDevOtp((current) => ({ ...current, [target]: data.devOtp || "" }));
      notify("OTP sent", `Verification email prepared for ${data.email}.`);
    } catch (error) {
      notify("OTP failed", error.message);
    }
  };

  const verifyOtp = async (target) => {
    try {
      const data = await api("/api/email-verification/verify", { method: "POST", body: JSON.stringify({ target, otp: otp[target] }) });
      if (setMe) setMe((current) => ({ ...current, user: data.user, business: data.business || current.business }));
      if (reload) await reload();
      setOpen((current) => ({ ...current, [target]: false }));
      setOtp((current) => ({ ...current, [target]: "" }));
      notify("Email verified", target === "business" ? "Business email is verified." : "Account email is verified.");
    } catch (error) {
      notify("Verification failed", error.message);
    }
  };

  const rows = [
    { target: "user", label: "Account email", email: user?.email, verified: user?.emailVerified },
    { target: "business", label: "Business email", email: business?.businessEmail, verified: business?.businessEmailVerified }
  ].filter((entry) => entry.email);

  if (!rows.length) return null;

  return (
    <section className="email-verify-card">
      <div className="detail-head">
        <div>
          <h3>Email verification</h3>
          <p className="muted">Verify each email with an OTP before using it for official communication.</p>
        </div>
      </div>
      <div className="email-verify-list">
        {rows.map((entry) => (
          <div className="email-verify-row" key={entry.target}>
            <div>
              <strong>{entry.label}</strong>
              <span>{entry.email}</span>
              {entry.verified ? <em>Verified</em> : <em className="pending">Not verified</em>}
            </div>
            {!entry.verified && <button className="ghost compact-btn" onClick={() => requestOtp(entry.target)}>Verify</button>}
            {open[entry.target] && !entry.verified && (
              <div className="otp-box">
                <input value={otp[entry.target]} onChange={(event) => setOtp({ ...otp, [entry.target]: event.target.value })} placeholder="Enter OTP" />
                <button className="btn compact-btn" onClick={() => verifyOtp(entry.target)}>Submit OTP</button>
                {devOtp[entry.target] && <small>Demo OTP: {devOtp[entry.target]}</small>}
              </div>
            )}
          </div>
        ))}
      </div>
    </section>
  );
}

function InfoCard({ title, rows, show }) {
  return (
    <section className="info-card">
      <h3>{title}</h3>
      <div className="info-list">
        {rows.map(([label, value]) => (
          <div className="info-row" key={label}>
            <span>{label}</span>
            <strong>{show(value)}</strong>
          </div>
        ))}
      </div>
    </section>
  );
}

function EditProfile({ me, business, setMe, notify, reload, onClose }) {
  const [userForm, setUserForm] = useState({
    name: me.user.name || "",
    username: me.user.username || "",
    phone: me.user.phone || "",
    preferredCity: me.user.preferredCity || "",
    preferredState: me.user.preferredState || "",
    personalAddress: me.user.personalAddress || "",
    notificationPreferences: me.user.notificationPreferences || { inApp: true, email: true, whatsapp: false, sms: false }
  });
  const [password, setPassword] = useState({ currentPassword: "", newPassword: "" });

  const saveUser = async () => {
    const data = await api("/api/profile/update", { method: "POST", body: JSON.stringify(userForm) });
    setMe((current) => ({ ...current, user: data.user }));
    notify("Profile updated", "Your profile details were saved.");
  };

  const changePassword = async () => {
    await api("/api/profile/password", { method: "POST", body: JSON.stringify(password) });
    setPassword({ currentPassword: "", newPassword: "" });
    notify("Password changed", "Your password has been updated.");
  };

  return (
    <div>
      <div className="detail-head">
        <h2>Profile settings</h2>
        {onClose && <button className="ghost compact-btn" onClick={onClose}>Back to About</button>}
      </div>
      <div className="form-grid">
        <Field label="Name" value={userForm.name} onChange={(value) => setUserForm({ ...userForm, name: value })} />
        <Field label="Username" value={userForm.username} onChange={(value) => setUserForm({ ...userForm, username: value })} />
        <Field label="Phone" value={userForm.phone} onChange={(value) => setUserForm({ ...userForm, phone: value })} />
        <Field label="Preferred city" value={userForm.preferredCity} onChange={(value) => setUserForm({ ...userForm, preferredCity: value })} />
        <Field label="Preferred state" value={userForm.preferredState} onChange={(value) => setUserForm({ ...userForm, preferredState: value })} />
        <Field label="Personal address" value={userForm.personalAddress} onChange={(value) => setUserForm({ ...userForm, personalAddress: value })} />
      </div>
      <p><button className="btn" onClick={saveUser}>Save profile</button></p>
      <h3>Notification preferences</h3>
      <div className="preference-grid">
        {[
          ["inApp", "In-app notifications"],
          ["email", "Email notifications"],
          ["whatsapp", "WhatsApp later"],
          ["sms", "SMS later"]
        ].map(([key, label]) => (
          <label className="check-row" key={key}>
            <input type="checkbox" checked={Boolean(userForm.notificationPreferences?.[key])} onChange={(event) => setUserForm({
              ...userForm,
              notificationPreferences: { ...(userForm.notificationPreferences || {}), [key]: event.target.checked }
            })} />
            <span>{label}</span>
          </label>
        ))}
      </div>
      <h3>Change password</h3>
      <div className="form-grid">
        <PasswordField label="Current password" value={password.currentPassword} onChange={(value) => setPassword({ ...password, currentPassword: value })} />
        <PasswordField label="New password" value={password.newPassword} onChange={(value) => setPassword({ ...password, newPassword: value })} />
      </div>
      <p><button className="ghost" onClick={changePassword}>Change password</button></p>
    </div>
  );
}

function SupportForm({ notify }) {
  const [form, setForm] = useState({ issue: "", message: "" });
  const issues = ["Login issue", "Business verification", "Profile update", "Catalog issue", "Chat or enquiry issue", "Payment or plan", "Report a user", "Other"];
  const submit = async () => {
    await api("/api/support", { method: "POST", body: JSON.stringify(form) });
    setForm({ issue: "", message: "" });
    notify("Support request sent", "Admin has been notified.");
  };
  return (
    <div>
      <h2>Support</h2>
      <div className="form-grid">
        <div className="field"><label>Issue</label><select value={form.issue} onChange={(event) => setForm({ ...form, issue: event.target.value })}><option value="">Select issue</option>{issues.map((issue) => <option key={issue}>{issue}</option>)}</select></div>
        <TextField label="Message" value={form.message} onChange={(value) => setForm({ ...form, message: value })} />
      </div>
      <p><button className="btn" onClick={submit}>Contact admin</button></p>
    </div>
  );
}

function BusinessFeed({ me, notify }) {
  const [posts, setPosts] = useState([]);
  const [form, setForm] = useState({ text: "", image: "" });
  const [comments, setComments] = useState({});
  const [view, setView] = useState("all");
  const [previewImage, setPreviewImage] = useState("");

  const load = async () => {
    const data = await api("/api/posts");
    setPosts(data.posts);
  };

  useEffect(() => {
    load().catch((error) => notify("Feed unavailable", error.message));
  }, []);

  const createPost = async () => {
    try {
      const data = await api("/api/posts", { method: "POST", body: JSON.stringify(form) });
      setPosts((current) => [data.post, ...current]);
      setForm({ text: "", image: "" });
      notify("Post published", "Your business post is live.");
    } catch (error) {
      notify("Post not published", error.message);
    }
  };

  const likePost = async (postId) => {
    const data = await api(`/api/posts/${postId}/like`, { method: "POST", body: "{}" });
    setPosts((current) => current.map((post) => post.id === postId ? data.post : post));
  };

  const addComment = async (postId) => {
    const text = comments[postId] || "";
    if (!text.trim()) return;
    const data = await api(`/api/posts/${postId}/comments`, { method: "POST", body: JSON.stringify({ text }) });
    setPosts((current) => current.map((post) => post.id === postId ? data.post : post));
    setComments((current) => ({ ...current, [postId]: "" }));
  };

  const ownPosts = posts.filter((post) => post.business?.ownerId === me.user?.id);
  const otherPosts = posts.filter((post) => post.business?.ownerId !== me.user?.id);
  const visiblePosts = view === "mine" ? ownPosts : otherPosts;

  return (
    <div className="feed-wrap">
      <div className="section-head tight">
        <div>
          <h2>Business feed</h2>
          <p>See posts from businesses you follow, or review posts created by you.</p>
        </div>
      </div>

      {me.business && (
        <div className="feed-composer">
          <div className="feed-limit-note">Daily limit: 10 posts per business account.</div>
          <textarea value={form.text} onChange={(event) => setForm({ ...form, text: event.target.value })} placeholder="Share a business update, offer, arrival, or announcement" />
          {form.image && <img className="feed-preview" src={assetUrl(form.image)} alt="" />}
          <div className="card-actions">
            <label className="mini-upload">
              <input type="file" accept="image/*" onChange={async (event) => setForm({ ...form, image: await fileToDataUrl(event.target.files?.[0]) })} />
              Add image
            </label>
            <button className="mini-upload mini-action" onClick={createPost}>Post update</button>
          </div>
        </div>
      )}

      <div className="feed-tabs">
        <button className={view === "all" ? "active" : ""} onClick={() => setView("all")}>Following</button>
        <button className={view === "mine" ? "active" : ""} onClick={() => setView("mine")}>My posts</button>
      </div>

      <div className="feed-list">
        {visiblePosts.map((post) => (
          <article className="feed-post" key={post.id}>
            <div className="feed-author">
              {(post.business?.profileImage || post.author?.profileImage) && <img src={assetUrl(post.business?.profileImage || post.author?.profileImage)} alt="" />}
              <div>
                <strong>{post.business?.businessName || post.author?.name || "Business"}</strong>
                <span>{post.business?.city || ""}{post.business?.state ? `, ${post.business.state}` : ""} · {new Date(post.createdAt).toLocaleString()}</span>
              </div>
            </div>
            {post.text && <p>{post.text}</p>}
            {post.image && <button className="feed-image-button" onClick={() => setPreviewImage(post.image)}><img className="feed-image" src={assetUrl(post.image)} alt="" /></button>}
            <div className="feed-actions">
              <button className={post.likedByMe ? "btn compact-btn" : "ghost compact-btn"} onClick={() => likePost(post.id)}>{post.likedByMe ? "Liked" : "Like"} · {post.likeCount}</button>
              <span>{post.commentCount} comment{post.commentCount === 1 ? "" : "s"}</span>
              <ReportButton targetType="post" targetId={post.id} notify={notify} />
            </div>
            <div className="comment-list">
              {(post.comments || []).slice(-3).map((comment) => (
                <p key={comment.id}><strong>{comment.user?.name || "User"}</strong> {comment.text}<br /><span className="muted">{new Date(comment.createdAt).toLocaleString()}</span></p>
              ))}
            </div>
            <div className="comment-box">
              <input value={comments[post.id] || ""} onChange={(event) => setComments({ ...comments, [post.id]: event.target.value })} placeholder="Write a comment" />
              <button className="ghost compact-btn" onClick={() => addComment(post.id)}>Comment</button>
            </div>
          </article>
        ))}
        {!visiblePosts.length && <p className="muted">{view === "mine" ? "You have not created any posts yet." : "Follow businesses to see their posts here."}</p>}
      </div>
      {previewImage && (
        <div className="modal-backdrop image-overlay" onMouseDown={() => setPreviewImage("")}>
          <div className="image-overlay-panel" onMouseDown={(event) => event.stopPropagation()}>
            <button className="icon-btn" onClick={() => setPreviewImage("")} aria-label="Close image">
              <LucideIcon name="x" label="Close" />
            </button>
            <img src={assetUrl(previewImage)} alt="" />
          </div>
        </div>
      )}
    </div>
  );
}

function QuotationBuilder({ items = [], notify, reload, openDownloads }) {
  const [query, setQuery] = useState("");
  const [selected, setSelected] = useState([]);
  const [form, setForm] = useState({ clientName: "", clientEmail: "", comments: "", validityDate: "", discount: "", tax: "", terms: "", signature: "", stamp: "" });
  const [latest, setLatest] = useState(null);
  const [mailEmail, setMailEmail] = useState("");
  const selectedItems = items.filter((item) => selected.includes(item.id));
  const results = items.filter((item) => {
    const text = `${item.name} ${item.description} ${item.category} ${item.subCategory}`.toLowerCase();
    return query ? text.includes(query.toLowerCase()) : true;
  }).slice(0, 8);

  const toggleItem = (itemId) => {
    setSelected((current) => current.includes(itemId) ? current.filter((id) => id !== itemId) : [...current, itemId]);
  };

  const generate = async () => {
    try {
      const data = await api("/api/quotations", { method: "POST", body: JSON.stringify({ ...form, itemIds: selected }) });
      setLatest(data.quotation);
      setMailEmail(data.quotation.clientEmail || "");
      await reload();
      notify("Quotation generated", "PDF is saved in Downloads.");
    } catch (error) {
      notify("Quotation failed", error.message);
    }
  };

  const mailQuotation = async (quotation = latest) => {
    if (!quotation) return;
    try {
      const data = await api(`/api/quotations/${quotation.id}/mail`, { method: "POST", body: JSON.stringify({ email: mailEmail || quotation.clientEmail }) });
      setLatest(data.quotation);
      await reload();
      notify("Quotation mailed", "Email is queued with the PDF link.");
    } catch (error) {
      notify("Mail failed", error.message);
    }
  };

  return (
    <div className="quotation-page">
      <div className="detail-head">
        <div>
          <h2>Create quotation</h2>
          <p className="muted">Search catalog products, select items, add comments, and generate a PDF.</p>
        </div>
      </div>

      <div className="quotation-grid">
        <section className="quote-box">
          <h3>Find products</h3>
          <input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Search product or service" />
          <div className="quote-results">
            {results.map((item) => (
              <label className="quote-result" key={item.id}>
                <input type="checkbox" checked={selected.includes(item.id)} onChange={() => toggleItem(item.id)} />
                <span>
                  <strong>{item.name}</strong>
                  <small>{item.category}{item.subCategory ? ` / ${item.subCategory}` : ""} · {item.price || "Price on enquiry"}</small>
                </span>
              </label>
            ))}
            {!results.length && <p className="muted">No products found.</p>}
          </div>
        </section>

        <section className="quote-box">
          <h3>Selected items</h3>
          <div className="quote-selected">
            {selectedItems.map((item) => (
              <button className="quote-selected-item" key={item.id} onClick={() => toggleItem(item.id)}>
                <span>{item.name}</span>
                <small>Remove</small>
              </button>
            ))}
            {!selectedItems.length && <p className="muted">Select catalog products to build a quotation.</p>}
          </div>
        </section>
      </div>

      <section className="quote-box">
        <h3>Client and comments</h3>
        <div className="form-grid">
          <Field label="Client name optional" value={form.clientName} onChange={(value) => setForm({ ...form, clientName: value })} />
          <Field label="Client email optional" value={form.clientEmail} onChange={(value) => setForm({ ...form, clientEmail: value })} />
          <Field label="Validity date" type="date" value={form.validityDate} onChange={(value) => setForm({ ...form, validityDate: value })} />
          <Field label="Discount optional" value={form.discount} onChange={(value) => setForm({ ...form, discount: value })} placeholder="5%, ₹500, or not applicable" />
          <Field label="Tax optional" value={form.tax} onChange={(value) => setForm({ ...form, tax: value })} placeholder="GST extra, included, 18%" />
          <TextField label="Comments" value={form.comments} onChange={(value) => setForm({ ...form, comments: value })} />
          <TextField label="Terms" value={form.terms} onChange={(value) => setForm({ ...form, terms: value })} placeholder="Payment, delivery, validity, warranty, or discussion terms" />
          <UploadControl label="Signature optional" hint="Upload signature image." onChange={async (event) => setForm({ ...form, signature: await fileToDataUrl(event.target.files?.[0]) })} />
          <UploadControl label="Company stamp optional" hint="Upload company stamp image." onChange={async (event) => setForm({ ...form, stamp: await fileToDataUrl(event.target.files?.[0]) })} />
        </div>
        <p><button className="btn" onClick={generate}>Generate quotation PDF</button></p>
      </section>

      {latest && (
        <section className="quote-box quote-output">
          <div>
            <h3>{latest.number}</h3>
            <p className="muted">PDF generated and saved in Downloads.</p>
          </div>
          <div className="card-actions">
            <a className="btn compact-btn" href={assetUrl(latest.pdfUrl)} target="_blank" rel="noreferrer">Download</a>
            <input value={mailEmail} onChange={(event) => setMailEmail(event.target.value)} placeholder="Client email" />
            <button className="ghost compact-btn" onClick={() => mailQuotation(latest)}>Send email</button>
            <button className="ghost compact-btn" onClick={openDownloads}>Open Downloads</button>
          </div>
        </section>
      )}
    </div>
  );
}

function DownloadsPage({ quotations = [], notify, reload }) {
  const [mailEmails, setMailEmails] = useState({});

  const sendQuotation = async (quote) => {
    try {
      await api(`/api/quotations/${quote.id}/mail`, { method: "POST", body: JSON.stringify({ email: mailEmails[quote.id] || quote.clientEmail }) });
      await reload();
      notify("Email queued", "Quotation email is ready to send from the mail queue.");
    } catch (error) {
      notify("Email failed", error.message);
    }
  };

  const deleteQuotation = async (quote) => {
    if (!window.confirm(`Delete ${quote.number} PDF?`)) return;
    try {
      await api(`/api/quotations/${quote.id}`, { method: "DELETE" });
      await reload();
      notify("PDF deleted", "Quotation PDF was removed from Downloads.");
    } catch (error) {
      notify("Delete failed", error.message);
    }
  };

  return (
    <div className="downloads-page">
      <div className="detail-head">
        <div>
          <h2>Downloads</h2>
          <p className="muted">Download, email, or delete generated quotation PDFs.</p>
        </div>
      </div>

      <div className="download-list">
        {quotations.map((quote) => (
          <article className="download-row" key={quote.id}>
            <div>
              <strong>{quote.number}</strong>
              <span>{new Date(quote.createdAt).toLocaleString()} · {quote.items?.length || 0} item{quote.items?.length === 1 ? "" : "s"}</span>
              {quote.clientName && <span>Client: {quote.clientName}</span>}
            </div>
            <div className="download-actions">
              <a className="btn compact-btn" href={assetUrl(quote.pdfUrl)} target="_blank" rel="noreferrer">Download</a>
              <input value={mailEmails[quote.id] ?? quote.clientEmail ?? ""} onChange={(event) => setMailEmails({ ...mailEmails, [quote.id]: event.target.value })} placeholder="Client email" />
              <button className="ghost compact-btn" onClick={() => sendQuotation(quote)}>Send email</button>
              <button className="danger compact-btn" onClick={() => deleteQuotation(quote)}>Delete PDF</button>
            </div>
          </article>
        ))}
        {!quotations.length && (
          <div className="quote-box">
            <h3>No PDFs yet</h3>
            <p className="muted">Create a quotation from Catalog to generate your first downloadable PDF.</p>
          </div>
        )}
      </div>
    </div>
  );
}

function ProfileHub({ user, setPage, initialTab }) {
  const [localUser, setLocalUser] = useState(user);
  const [tab, setTab] = useState(initialTab === "profile" ? "about" : initialTab || "about");
  const [cropModal, setCropModal] = useState(null);
  const editing = tab === "settings";

  useEffect(() => {
    if (initialTab) setTab(initialTab === "profile" ? "about" : initialTab);
  }, [initialTab]);

  const updateLocalUser = (nextUser) => {
    if (nextUser) setLocalUser(nextUser);
  };

  const uploadNormalPhoto = async (event) => {
    const source = await fileToDataUrl(event.target.files?.[0]);
    event.target.value = "";
    if (!source) return;
    setCropModal({ kind: "profile", title: "Adjust profile picture", source, targetWidth: 512, targetHeight: 512 });
  };

  const uploadNormalBanner = async (event) => {
    const source = await fileToDataUrl(event.target.files?.[0]);
    event.target.value = "";
    if (!source) return;
    setCropModal({ kind: "banner", title: "Adjust profile banner", source, targetWidth: 1600, targetHeight: 520 });
  };

  const saveNormalCrop = async ({ kind, image }) => {
    const payload = {
      name: localUser.name || "",
      username: localUser.username || "",
      phone: localUser.phone || "",
      personalAddress: localUser.personalAddress || "",
      preferredCity: localUser.preferredCity || "",
      preferredState: localUser.preferredState || "",
      profileImage: kind === "profile" ? image : localUser.profileImage || "",
      bannerImage: kind === "banner" ? image : localUser.bannerImage || ""
    };
    const data = await api("/api/profile/update", { method: "POST", body: JSON.stringify(payload) });
    updateLocalUser(data.user);
    setCropModal(null);
  };

  return (
    <main className="page dashboard-grid">
      <UserSidebar user={localUser} business={null} active={tab} chooseTab={setTab} onProfileUpload={uploadNormalPhoto} />
      <section className="panel">
        <DashboardBannerControl business={{ bannerImage: localUser.bannerImage || "" }} onBannerUpload={uploadNormalBanner} />
        {tab === "about" && (
          <>
            <div className="detail-head">
              <div>
                <h2>About</h2>
                <p className="muted">Use your account to explore businesses, message sellers, or create your own business page.</p>
              </div>
              <button className="btn compact-btn" onClick={() => setPage("onboarding")}>Create business page</button>
            </div>
            <AboutProfile user={localUser} business={null} setMe={(updater) => {
              const next = typeof updater === "function" ? updater({ user: localUser, business: null }) : updater;
              if (next.user) setLocalUser(next.user);
            }} notify={() => {}} reload={async () => {}} onEdit={() => setTab("settings")} />
          </>
        )}
        {editing && (
          <EditProfile me={{ user: localUser }} business={null} setMe={(updater) => {
            const next = typeof updater === "function" ? updater({ user: localUser }) : updater;
            if (next.user) setLocalUser(next.user);
          }} notify={() => {}} reload={async () => {}} onClose={() => setTab("about")} />
        )}
        {tab === "feed" && <BusinessFeed me={{ user: localUser }} notify={() => {}} />}
        {tab === "saved" && <SavedBusinesses me={{ user: localUser }} notify={() => {}} setPage={setPage} />}
        {tab === "messages" && <Messages me={{ user: localUser }} setPage={setPage} />}
        {tab === "support" && <SupportForm notify={() => {}} />}
        {tab === "enquiries" && <Enquiries enquiries={[]} setPage={setPage} />}
      </section>
      {cropModal && <CropModal config={cropModal} onClose={() => setCropModal(null)} onSave={saveNormalCrop} />}
    </main>
  );
}

function Messages({ notify = () => {}, me, setPage }) {
  const [conversations, setConversations] = useState([]);
  const [users, setUsers] = useState([]);

  const loadConversations = async () => {
    const data = await api("/api/conversations");
    setConversations(data.conversations);
  };

  useEffect(() => {
    loadConversations().catch(() => {});
    api("/api/users").then((data) => setUsers(data.users.slice(0, 8))).catch(() => {});
  }, []);

  const startConversation = async (recipientId) => {
    const data = await api("/api/conversations", { method: "POST", body: JSON.stringify({ recipientId }) });
    await loadConversations();
    setUsers([]);
    setPage(`chat:${data.conversation.id}`);
  };

  return (
    <div>
      <h2>Messages</h2>
      <div className="thread-list">
        {conversations.map((conversation) => (
          <div className="thread-item" key={conversation.id}>
            <button onClick={() => setPage(`chat:${conversation.id}`)}>
              <span>
                <strong>{conversation.business?.businessName || conversation.other?.name || "Conversation"}</strong>
                <small>{conversation.lastMessage?.text || "No messages yet"} · {new Date(conversation.updatedAt || conversation.createdAt).toLocaleString()}</small>
              </span>
              <b title="Open chat">Chat</b>
            </button>
          </div>
        ))}
        {users.map((user) => (
          <div className="thread-item" key={user.id}>
            <button onClick={() => startConversation(user.id)}>
              <span>
                <strong>{user.name}</strong>
                <small>{user.phone || "Phone not shared"}</small>
              </span>
              <b title="Open chat">Chat</b>
            </button>
          </div>
        ))}
        {!conversations.length && !users.length && <p className="muted">No chats yet.</p>}
      </div>
    </div>
  );
}

function ChatPage({ id, me, notify, embedded = false }) {
  const [thread, setThread] = useState({ conversation: null, messages: [] });
  const [conversations, setConversations] = useState([]);
  const [text, setText] = useState("");

  const load = async () => {
    const [messagesData, conversationsData] = await Promise.all([
      api(`/api/conversations/${id}/messages`),
      api("/api/conversations")
    ]);
    setThread(messagesData);
    setConversations(conversationsData.conversations);
  };

  useEffect(() => {
    load().catch((error) => notify("Chat unavailable", error.message));
  }, [id]);

  const conversation = conversations.find((entry) => entry.id === id) || thread.conversation;
  const send = async () => {
    if (!text.trim()) return;
    await api(`/api/conversations/${id}/messages`, { method: "POST", body: JSON.stringify({ text }) });
    setText("");
    await load();
    notify("Message sent", "Your chat message was delivered.");
  };

  const content = (
    <>
        <div className="detail-head">
          <div>
            <h1>{conversation?.business?.businessName || conversation?.other?.name || "Chat"}</h1>
            <p className="muted">Thread updated {conversation?.updatedAt ? new Date(conversation.updatedAt).toLocaleString() : "-"}</p>
          </div>
          <div className="card-actions">
            <ShareButton url={`${window.location.origin}/chat/${id}`} title="Chat thread" />
            <ReportButton targetType="conversation" targetId={id} notify={notify} />
          </div>
        </div>
        <div className="chat-box page-chat-box">
          {thread.messages.map((message) => {
            const mine = message.senderId === me?.user?.id;
            const seen = mine && Array.isArray(message.seenBy) && message.seenBy.length > 1;
            return <div className={`message ${mine ? "mine" : ""}`} key={message.id}>{message.text}<br /><span className="muted">{new Date(message.createdAt).toLocaleString()} · {mine ? (seen ? "Seen" : "Not seen") : "Received"}</span></div>;
          })}
          {!thread.messages.length && <p className="muted">No messages yet.</p>}
        </div>
        <p><textarea value={text} onChange={(event) => setText(event.target.value)} placeholder="Write a message" /></p>
        <button className="btn" onClick={send}>Send message</button>
    </>
  );

  if (embedded) return <div className="embedded-detail">{content}</div>;

  return (
    <main className="page chat-page">
      <section className="panel">
        {content}
      </section>
    </main>
  );
}

function Enquiries({ enquiries, setPage, notify = () => {}, reload = async () => {}, canManage = false }) {
  const statuses = ["New", "Contacted", "Important", "Closed", "Spam"];
  const updateStatus = async (id, status) => {
    try {
      await api(`/api/enquiries/${id}/status`, { method: "POST", body: JSON.stringify({ status }) });
      await reload();
      notify("Lead updated", `Marked as ${status}.`);
    } catch (error) {
      notify("Lead not updated", error.message);
    }
  };
  return (
    <>
      <h2>Enquiries & chat</h2>
      <div className="thread-list">
        {enquiries.map((enquiry) => (
          <div className="thread-item" key={enquiry.id}>
            <button onClick={() => setPage(`enquiry:${enquiry.id}`)}>
              <span>
                <strong>{enquiry.customer?.name || enquiry.businessName || "Enquiry"}</strong>
                <small>{enquiry.subject} · {enquiry.status || "New"} · {new Date(enquiry.createdAt).toLocaleString()}</small>
              </span>
              <b title="Open chat">Chat</b>
            </button>
            {canManage && (
              <div className="lead-actions">
                {statuses.map((status) => <button className={enquiry.status === status ? "btn compact-btn" : "ghost compact-btn"} key={status} onClick={() => updateStatus(enquiry.id, status)}>{status}</button>)}
              </div>
            )}
          </div>
        ))}
        {!enquiries.length && <p className="muted">No enquiries yet.</p>}
      </div>
    </>
  );
}

function EnquiryPage({ id, me, notify, embedded = false }) {
  const [thread, setThread] = useState({ enquiry: null, messages: [] });
  const [text, setText] = useState("");

  const load = async () => {
    setThread(await api(`/api/enquiries/${id}/messages`));
  };

  useEffect(() => {
    load().catch((error) => notify("Enquiry unavailable", error.message));
  }, [id]);

  const send = async () => {
    if (!text.trim()) return;
    await api(`/api/enquiries/${id}/messages`, { method: "POST", body: JSON.stringify({ text }) });
    setText("");
    await load();
  };

  const content = (
    <>
        <div className="detail-head">
          <div>
            <h1>{thread.enquiry?.subject || "Enquiry"}</h1>
            <p className="muted">Created {thread.enquiry?.createdAt ? new Date(thread.enquiry.createdAt).toLocaleString() : "-"}</p>
          </div>
          <ShareButton url={`${window.location.origin}/enquiries/${id}`} title="Enquiry thread" />
        </div>
        <div className="chat-box page-chat-box">
          {thread.messages.map((message) => {
            const mine = message.senderId === me?.user?.id;
            return <div className={`message ${mine ? "mine" : ""}`} key={message.id}>{message.text}<br /><span className="muted">{new Date(message.createdAt).toLocaleString()} · {mine ? "Sent" : "Received"}</span></div>;
          })}
        </div>
        <p><textarea value={text} onChange={(event) => setText(event.target.value)} placeholder="Write a reply" /></p>
        <button className="btn" onClick={send}>Send message</button>
    </>
  );

  if (embedded) return <div className="embedded-detail">{content}</div>;

  return (
    <main className="page chat-page">
      <section className="panel">
        {content}
      </section>
    </main>
  );
}

function AdminDashboard({ me, notify, setPage }) {
  const [data, setData] = useState(null);
  const [query, setQuery] = useState("");
  const [section, setSection] = useState(sessionStorage.getItem("adminSection") || "overview");

  useEffect(() => {
    api("/api/admin")
      .then(setData)
      .catch((error) => notify("Admin unavailable", error.message));
  }, []);

  if (!me.user) {
    return <main className="page"><div className="panel empty-state">Login first, then open Admin.</div></main>;
  }

  if (me.user.accountRole !== "admin") {
    return <main className="page"><div className="panel empty-state">This account does not have admin access.</div></main>;
  }

  if (!data) {
    return <main className="page"><div className="panel empty-state">Loading admin dashboard...</div></main>;
  }

  const needle = query.trim().toLowerCase();
  const matches = (value) => JSON.stringify(value).toLowerCase().includes(needle);
  const filteredUsers = needle ? data.users.filter(matches) : data.users;
  const filteredBusinesses = needle ? data.businesses.filter(matches) : data.businesses;
  const filteredEnquiries = needle ? data.enquiries.filter(matches) : data.enquiries;
  const filteredSupport = needle ? (data.supportTickets || []).filter(matches) : (data.supportTickets || []);
  const approvals = (data.businesses || []).filter((business) => business.approvalStatus === "pending");
  const filteredApprovals = needle ? approvals.filter(matches) : approvals;
  const filteredClaims = needle ? (data.claimRequests || []).filter(matches) : (data.claimRequests || []);
  const filteredReports = needle ? (data.reports || []).filter(matches) : (data.reports || []);
  const refreshAdmin = async () => setData(await api("/api/admin"));
  const viewData = (type, id) => setPage(`adminDetail:${type}:${id}`);
  const chooseSection = (nextSection) => {
    sessionStorage.setItem("adminSection", nextSection);
    setSection(nextSection);
  };
  const blockUser = async (userId) => {
    await api("/api/admin/user-action", { method: "POST", body: JSON.stringify({ userId, action: "block" }) });
    await refreshAdmin();
  };
  const resetPassword = async (userId) => {
    const password = prompt("Enter new password");
    if (!password) return;
    await api("/api/admin/user-action", { method: "POST", body: JSON.stringify({ userId, action: "password", password }) });
    notify("Password changed", "User password was updated.");
  };
  const blockBusiness = async (businessId) => {
    await api("/api/admin/business-action", { method: "POST", body: JSON.stringify({ businessId, action: "block" }) });
    await refreshAdmin();
  };
  const businessModeration = async (businessId, action) => {
    const note = action === "reject" ? prompt("Reason for rejection") || "" : "";
    await api("/api/admin/business-action", { method: "POST", body: JSON.stringify({ businessId, action, note }) });
    await refreshAdmin();
  };
  const claimModeration = async (claimId, action) => {
    const note = action === "reject" ? prompt("Reason") || "" : "";
    await api("/api/admin/claim-action", { method: "POST", body: JSON.stringify({ claimId, action, note }) });
    await refreshAdmin();
  };
  const reportModeration = async (reportId, action) => {
    const note = action !== "open" ? prompt("Admin note optional") || "" : "";
    await api("/api/admin/report-action", { method: "POST", body: JSON.stringify({ reportId, action, note }) });
    await refreshAdmin();
  };

  return (
    <main className="page admin-layout">
      <AdminSidebar active={section} onSelect={chooseSection} />

      <section className="admin-content">
        <div className="classic-admin-head">
          <div>
            <h1>{section[0].toUpperCase() + section.slice(1)}</h1>
            <p>Search and review one section at a time.</p>
          </div>
          <input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Search anything in admin" />
        </div>

        {section === "overview" && (
          <div className="stats-grid compact">
            <div className="stat"><span>Users</span><strong>{data.totals.users}</strong></div>
            <div className="stat"><span>Businesses</span><strong>{data.totals.businesses}</strong></div>
            <div className="stat"><span>Approvals</span><strong>{data.totals.approvals || 0}</strong></div>
            <div className="stat"><span>Catalog items</span><strong>{data.totals.items}</strong></div>
            <div className="stat"><span>Enquiries</span><strong>{data.totals.enquiries}</strong></div>
            <div className="stat"><span>Claims</span><strong>{data.totals.claims || 0}</strong></div>
            <div className="stat"><span>Reports</span><strong>{data.totals.reports || 0}</strong></div>
            <div className="stat"><span>Support</span><strong>{data.totals.support || 0}</strong></div>
          </div>
        )}

        {section === "approvals" && (
          <div className="panel admin-table-panel">
            <div className="section-head tight"><div><h2>Business approval queue</h2><p>{filteredApprovals.length} pending</p></div></div>
            <table>
              <thead><tr><th>Business</th><th>Owner</th><th>Category</th><th>Location</th><th>Created</th><th>Actions</th></tr></thead>
              <tbody>
                {filteredApprovals.map((business) => (
                  <tr key={business.id}>
                    <td>{business.businessName}</td>
                    <td>{business.owner?.name || "-"}</td>
                    <td>{business.category}</td>
                    <td>{business.city}, {business.state}</td>
                    <td>{business.createdAt ? new Date(business.createdAt).toLocaleDateString() : "-"}</td>
                    <td className="table-actions">
                      <button className="ghost compact-btn" onClick={() => viewData("businesses", business.id)}>View</button>
                      <button className="btn compact-btn" onClick={() => businessModeration(business.id, "approve")}>Approve</button>
                      <button className="ghost compact-btn" onClick={() => businessModeration(business.id, "reject")}>Reject</button>
                    </td>
                  </tr>
                ))}
                {!filteredApprovals.length && <tr><td colSpan="6">No pending businesses.</td></tr>}
              </tbody>
            </table>
          </div>
        )}

        {section === "users" && (
          <div className="panel admin-table-panel">
          <div className="section-head tight">
            <div>
              <h2>All users</h2>
              <p>{filteredUsers.length} record{filteredUsers.length === 1 ? "" : "s"}</p>
            </div>
          </div>
          <table>
            <thead>
              <tr><th>Name</th><th>Email</th><th>Phone</th><th>Role</th><th>Joined</th><th>Actions</th></tr>
            </thead>
            <tbody>
              {filteredUsers.map((user) => (
                <tr key={user.id}>
                  <td>{user.name}</td>
                  <td>{user.email}</td>
                  <td>{user.phone || "-"}</td>
                  <td>{user.accountRole}</td>
                  <td>{user.createdAt ? new Date(user.createdAt).toLocaleDateString() : "-"}</td>
                  <td className="table-actions">
                    <button className="ghost compact-btn" onClick={() => viewData("users", user.id)}>View</button>
                    <button className="ghost compact-btn" onClick={() => blockUser(user.id)}>{user.blocked ? "Unblock" : "Block"}</button>
                    <button className="ghost compact-btn" onClick={() => resetPassword(user.id)}>Password</button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          </div>
        )}

        {section === "businesses" && (
          <div className="panel admin-table-panel">
          <div className="section-head tight">
            <div>
              <h2>All businesses</h2>
              <p>{filteredBusinesses.length} record{filteredBusinesses.length === 1 ? "" : "s"}</p>
            </div>
          </div>
          <table>
            <thead>
              <tr><th>Business</th><th>Owner</th><th>Category</th><th>Location</th><th>Items</th><th>Enquiries</th><th>Actions</th></tr>
            </thead>
            <tbody>
              {filteredBusinesses.map((business) => (
                <tr key={business.id}>
                  <td>{business.businessName}</td>
                  <td>{business.owner?.name || "-"}</td>
                  <td>{business.category}</td>
                  <td>{business.city}, {business.state}</td>
                  <td>{business.itemCount}</td>
                  <td>{business.enquiryCount}</td>
                  <td className="table-actions">
                    <button className="ghost compact-btn" onClick={() => viewData("businesses", business.id)}>View</button>
                    {business.approvalStatus !== "approved" && <button className="btn compact-btn" onClick={() => businessModeration(business.id, "approve")}>Approve</button>}
                    {business.approvalStatus === "approved" && <button className="ghost compact-btn" onClick={() => businessModeration(business.id, "pending")}>Review</button>}
                    <button className="ghost compact-btn" onClick={() => blockBusiness(business.id)}>{business.blocked ? "Unblock" : "Block"}</button>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
          </div>
        )}

        {section === "enquiries" && (
          <div className="panel admin-table-panel">
          <div className="section-head tight">
            <div>
              <h2>Enquiries</h2>
              <p>{filteredEnquiries.length} record{filteredEnquiries.length === 1 ? "" : "s"}</p>
            </div>
          </div>
          <table>
            <thead>
              <tr><th>Subject</th><th>Customer</th><th>Business</th><th>Status</th><th>Date</th><th>Actions</th></tr>
            </thead>
            <tbody>
              {filteredEnquiries.map((enquiry) => (
                <tr key={enquiry.id}>
                  <td>{enquiry.subject}</td>
                  <td>{enquiry.customer?.name || "Guest"}</td>
                  <td>{enquiry.businessName}</td>
                  <td>{enquiry.status}</td>
                  <td>{new Date(enquiry.createdAt).toLocaleDateString()}</td>
                  <td><button className="ghost compact-btn" onClick={() => viewData("enquiries", enquiry.id)}>View</button></td>
                </tr>
              ))}
            </tbody>
          </table>
          </div>
        )}
        {section === "claims" && (
          <div className="panel admin-table-panel">
            <div className="section-head tight"><div><h2>Business claims</h2><p>{filteredClaims.length} record{filteredClaims.length === 1 ? "" : "s"}</p></div></div>
            <table>
              <thead><tr><th>Business</th><th>Requester</th><th>Reason</th><th>Status</th><th>Date</th><th>Actions</th></tr></thead>
              <tbody>
                {filteredClaims.map((claim) => (
                  <tr key={claim.id}>
                    <td>{claim.business?.businessName || claim.businessId}</td>
                    <td>{claim.requester?.name || "-"}</td>
                    <td>{claim.reason}</td>
                    <td>{claim.status}</td>
                    <td>{claim.createdAt ? new Date(claim.createdAt).toLocaleDateString() : "-"}</td>
                    <td className="table-actions">
                      <button className="ghost compact-btn" onClick={() => viewData("claims", claim.id)}>View</button>
                      {claim.status === "pending" && <button className="btn compact-btn" onClick={() => claimModeration(claim.id, "approve")}>Approve</button>}
                      {claim.status === "pending" && <button className="ghost compact-btn" onClick={() => claimModeration(claim.id, "reject")}>Reject</button>}
                    </td>
                  </tr>
                ))}
                {!filteredClaims.length && <tr><td colSpan="6">No claim requests.</td></tr>}
              </tbody>
            </table>
          </div>
        )}
        {section === "reports" && (
          <div className="panel admin-table-panel">
            <div className="section-head tight"><div><h2>Reports</h2><p>{filteredReports.length} record{filteredReports.length === 1 ? "" : "s"}</p></div></div>
            <table>
              <thead><tr><th>Target</th><th>Reason</th><th>Reporter</th><th>Status</th><th>Date</th><th>Actions</th></tr></thead>
              <tbody>
                {filteredReports.map((report) => (
                  <tr key={report.id}>
                    <td>{report.targetType}: {report.targetLabel}</td>
                    <td>{report.reason}</td>
                    <td>{report.reporter?.name || "-"}</td>
                    <td>{report.status}</td>
                    <td>{report.createdAt ? new Date(report.createdAt).toLocaleDateString() : "-"}</td>
                    <td className="table-actions">
                      <button className="ghost compact-btn" onClick={() => viewData("reports", report.id)}>View</button>
                      {report.status === "open" && <button className="btn compact-btn" onClick={() => reportModeration(report.id, "resolved")}>Resolve</button>}
                      {report.status === "open" && <button className="ghost compact-btn" onClick={() => reportModeration(report.id, "dismissed")}>Dismiss</button>}
                    </td>
                  </tr>
                ))}
                {!filteredReports.length && <tr><td colSpan="6">No reports.</td></tr>}
              </tbody>
            </table>
          </div>
        )}
        {section === "support" && (
          <div className="panel admin-table-panel">
            <div className="section-head tight"><div><h2>Support requests</h2><p>{filteredSupport.length} record{filteredSupport.length === 1 ? "" : "s"}</p></div></div>
            <table>
              <thead><tr><th>Issue</th><th>User</th><th>Message</th><th>Date</th><th>Actions</th></tr></thead>
              <tbody>
                {filteredSupport.map((ticket) => (
                  <tr key={ticket.id}>
                    <td>{ticket.issue}</td>
                    <td>{ticket.user?.name || "-"}</td>
                    <td>{ticket.message}</td>
                    <td>{new Date(ticket.createdAt).toLocaleDateString()}</td>
                    <td><button className="ghost compact-btn" onClick={() => viewData("support", ticket.id)}>View</button></td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </section>
    </main>
  );
}

function AdminSidebar({ active, onSelect }) {
  return (
    <aside className="panel admin-sidebar">
      <h2>Admin</h2>
      <button className={active === "overview" ? "active" : ""} onClick={() => onSelect("overview")}>Overview</button>
      <button className={active === "approvals" ? "active" : ""} onClick={() => onSelect("approvals")}>Approvals</button>
      <button className={active === "users" ? "active" : ""} onClick={() => onSelect("users")}>Users</button>
      <button className={active === "businesses" ? "active" : ""} onClick={() => onSelect("businesses")}>Businesses</button>
      <button className={active === "enquiries" ? "active" : ""} onClick={() => onSelect("enquiries")}>Enquiries</button>
      <button className={active === "claims" ? "active" : ""} onClick={() => onSelect("claims")}>Claims</button>
      <button className={active === "reports" ? "active" : ""} onClick={() => onSelect("reports")}>Reports</button>
      <button className={active === "support" ? "active" : ""} onClick={() => onSelect("support")}>Support</button>
    </aside>
  );
}

function AdminDetailPage({ me, notify, setPage, type, id }) {
  const [data, setData] = useState(null);

  useEffect(() => {
    api("/api/admin")
      .then(setData)
      .catch((error) => notify("Admin detail unavailable", error.message));
  }, [type, id]);

  if (!me.user) {
    return <main className="page"><div className="panel empty-state">Login first, then open Admin.</div></main>;
  }

  if (me.user.accountRole !== "admin") {
    return <main className="page"><div className="panel empty-state">This account does not have admin access.</div></main>;
  }

  if (!data) {
    return <main className="page"><div className="panel empty-state">Loading detail...</div></main>;
  }

  const collections = {
    users: { label: "User", items: data.users || [] },
    businesses: { label: "Business", items: data.businesses || [] },
    enquiries: { label: "Enquiry", items: data.enquiries || [] },
    claims: { label: "Business claim", items: data.claimRequests || [] },
    reports: { label: "Report", items: data.reports || [] },
    support: { label: "Support request", items: data.supportTickets || [] }
  };
  const current = collections[type] || collections.users;
  const record = current.items.find((entry) => entry.id === id);
  const activeSection = collections[type] ? type : "users";
  const openSection = (section) => {
    sessionStorage.setItem("adminSection", section);
    setPage("admin");
  };

  if (!record) {
    return (
      <main className="page admin-layout">
        <AdminSidebar active={activeSection} onSelect={openSection} />
        <section className="admin-content">
        <div className="panel empty-state">
          <div>
            <p>Record not found.</p>
            <button className="ghost" onClick={() => setPage("admin")}>Back to admin</button>
          </div>
        </div>
        </section>
      </main>
    );
  }

  return (
    <main className="page admin-layout">
      <AdminSidebar active={activeSection} onSelect={openSection} />
      <section className="admin-content admin-detail-page">
      <div className="panel detail-panel">
        <div className="detail-head">
          <div>
            <span className="eyebrow">Admin detail</span>
            <h1>{record.businessName || record.name || record.subject || record.issue || current.label}</h1>
            <p className="muted">{current.label} ID: {record.id}</p>
          </div>
          <div className="card-actions">
            {type === "businesses" && <button className="ghost compact-btn" onClick={() => setPage(`business:${record.id}`)}>Public page</button>}
            {type === "enquiries" && <button className="ghost compact-btn" onClick={() => setPage(`enquiry:${record.id}`)}>Open thread</button>}
            <button className="ghost compact-btn" onClick={() => setPage("admin")}>Back</button>
          </div>
        </div>
        <div className="detail-grid">
          {Object.entries(record || {}).map(([key, value]) => (
            <p key={key}><strong>{key}</strong><span>{formatDetailValue(value)}</span></p>
          ))}
        </div>
      </div>
      </section>
    </main>
  );
}

function BusinessDetail({ id, seoPath = "", me, notify, setPage }) {
  const [business, setBusiness] = useState(null);
  const [enquiryOpen, setEnquiryOpen] = useState(false);

  useEffect(() => {
    const endpoint = seoPath ? `/api/seo/business/${seoPath}?view=profile` : `/api/businesses/${id}?view=profile`;
    api(endpoint).then((data) => setBusiness(data.business)).catch((error) => notify("Business unavailable", error.message));
  }, [id, seoPath]);

  const startBusinessChat = async () => {
    if (!me.user) return notify("Login required", "Please login to message this business.");
    const data = await api("/api/conversations", { method: "POST", body: JSON.stringify({ businessId: business.id, text: `Hi, I want to discuss ${business.businessName}.` }) });
    setPage(`chat:${data.conversation.id}`);
  };

  const toggleFollow = async () => {
    if (!me.user) return notify("Login required", "Please login to follow this business.");
    const data = await api(`/api/businesses/${business.id}/follow`, { method: business.followedByMe ? "DELETE" : "POST" });
    setBusiness(data.business);
    notify(data.business.followedByMe ? "Business followed" : "Business unfollowed", data.business.followedByMe ? "Their posts will appear in your feed." : "Their posts will no longer appear in your feed.");
  };

  if (!business) return <main className="page"><div className="panel">Loading business...</div></main>;

  return (
    <main className="page">
      <article className="business-card">
        <BannerSlider images={business.bannerImages || [business.bannerImage]} />
        <div className="business-content">
          {business.profileImage && <img className="avatar" src={assetUrl(business.profileImage)} alt="" />}
          <p><span className="tag">{business.category}</span></p>
          <h1>{business.businessName}</h1>
          <p className="muted">{business.address}, {business.city}, {business.state} {business.pincode}</p>
          <p className="muted">Phone: {business.businessPhone || business.whatsapp || business.owner?.phone || "Not shared"}</p>
          <p>{business.description}</p>
          <p>
            {business.website && <a className="btn" href={business.website} target="_blank">Website</a>}{" "}
            <WhatsAppButton business={business} text={`Hi, I found ${business.businessName} on CitySoochna.`} />
            {" "}
            {me.user && <SaveBusinessButton business={business} onChange={setBusiness} notify={notify} />}
            {" "}
            {me.user?.id !== business.ownerId && <button className={business.followedByMe ? "btn" : "ghost"} onClick={toggleFollow}>{business.followedByMe ? "Following" : "Follow"}</button>}
            {" "}
            {me.user?.id !== business.ownerId && <button className="ghost" onClick={startBusinessChat}>Message business</button>}
            {" "}<button className="btn" onClick={() => setEnquiryOpen(true)}>Make enquiry</button>
            {" "}<button className="ghost" onClick={() => setPage(`catalog:${business.id}`)}>View catalog</button>
            {" "}<ShareButton url={`${window.location.origin}${business.seoPath || `/businesses/${business.id}`}`} title={business.businessName} />
            {" "}{me.user?.id !== business.ownerId && <ClaimBusinessButton business={business} notify={notify} />}
            {" "}<ReportButton targetType="business" targetId={business.id} notify={notify} compact={false} />
          </p>
          <p className="muted">{business.followerCount || 0} follower{business.followerCount === 1 ? "" : "s"} · {business.savedCount || 0} saved</p>
        </div>
      </article>

      <section className="panel catalog-entry-panel">
        <div>
          <h2>Catalog</h2>
          <p className="muted">{business.items.length} products listed by {business.businessName}.</p>
        </div>
        <button className="btn" onClick={() => setPage(`catalog:${business.id}`)}>Open catalog</button>
      </section>
      {enquiryOpen && <EnquiryModal business={business} me={me} notify={notify} onClose={() => setEnquiryOpen(false)} />}
    </main>
  );
}

function BusinessCatalogPage({ id, me, notify, setPage, embedded = false }) {
  const [business, setBusiness] = useState(null);
  const [filter, setFilter] = useState({ category: "", subCategory: "" });
  const [enquiryItem, setEnquiryItem] = useState(null);

  useEffect(() => {
    api(`/api/businesses/${id}?view=catalog`).then((data) => setBusiness(data.business)).catch((error) => notify("Catalog unavailable", error.message));
  }, [id]);

  if (!business) {
    return embedded ? <div>Loading catalog...</div> : <main className="page"><div className="panel">Loading catalog...</div></main>;
  }

  const items = (business.items || []).filter((item) => (!filter.category || item.category === filter.category) && (!filter.subCategory || item.subCategory === filter.subCategory));
  const content = (
    <>
      <section className="catalog-page-head">
        <div>
          <button className="ghost compact-btn" onClick={() => setPage(`business:${business.id}`)}>Back to profile</button>
          <h1>{business.businessName} catalog</h1>
          <p className="muted">{business.city}, {business.state} · {business.items.length} products</p>
        </div>
        <ShareButton url={`${window.location.origin}/businesses/${business.id}/catalog`} title={`${business.businessName} catalog`} />
      </section>

      <div className="form-grid compact-form">
        <CategorySelect value={filter.category} subValue={filter.subCategory} onChange={(category, subCategory) => setFilter({ category, subCategory })} />
      </div>

      <div className="item-list catalog-products">
        {items.map((item) => (
          <article className="item-card" key={item.id}>
            {item.image && <img src={assetUrl(item.image)} alt="" />}
            <h3>{item.name}</h3>
            <p className="muted">{item.category}{item.subCategory ? ` · ${item.subCategory}` : ""} · {item.status}</p>
            <p>{item.description}</p>
            <p><strong>{item.price || "Price on enquiry"}</strong></p>
            <p className="muted">MOQ: {item.minQty || "Not set"} · Stock: {item.stock || "Not set"} {item.unit}</p>
            <div className="card-actions">
              <button className="ghost" onClick={() => setPage(`item:${item.id}`)}>View product</button>
              {me.user?.id !== business.ownerId && <button className="ghost" onClick={() => setEnquiryItem(item)}>Enquire</button>}
              <ShareButton url={`${window.location.origin}/items/${item.id}`} title={item.name} />
            </div>
          </article>
        ))}
        {!items.length && <div className="panel">No catalog products match this filter.</div>}
      </div>
      {enquiryItem && <EnquiryModal business={business} item={enquiryItem} me={me} notify={notify} onClose={() => setEnquiryItem(null)} />}
    </>
  );

  if (embedded) return <div className="embedded-detail">{content}</div>;

  return (
    <main className="page catalog-display-page">
      {content}
    </main>
  );
}

function ItemDetail({ id, me, notify, setPage, embedded = false }) {
  const [item, setItem] = useState(null);
  const [enquiryOpen, setEnquiryOpen] = useState(false);

  useEffect(() => {
    api(`/api/items/${id}`).then((data) => {
      setItem(data.item);
    }).catch((error) => notify("Item unavailable", error.message));
  }, [id]);

  const startChat = async () => {
    if (!me.user) return notify("Login required", "Please login to message this seller.");
    const data = await api("/api/conversations", { method: "POST", body: JSON.stringify({ businessId: item.business.id, text: `Hi, I want to discuss ${item.name}.` }) });
    setPage(`chat:${data.conversation.id}`);
  };

  if (!item) return embedded ? <div>Loading item...</div> : <main className="page"><div className="panel">Loading item...</div></main>;

  const content = (
    <>
      <article className={`item-detail ${embedded ? "embedded-item-detail" : "panel"}`}>
        {item.image && <img className="detail-image" src={assetUrl(item.image)} alt="" />}
        <div>
          <p><span className="tag">{item.category || item.business.category}</span></p>
          <h1>{item.name}</h1>
          <p className="muted">{item.business.businessName} · {item.business.city}, {item.business.state}</p>
          <p className="muted">Phone: {item.business.businessPhone || item.business.whatsapp || item.business.owner?.phone || "Not shared"}</p>
          <p>{item.description}</p>
          <p><strong>{item.price || "Price on enquiry"}</strong></p>
          <p className="muted">MOQ: {item.minQty || "Not set"} · Stock: {item.stock || "Not set"} {item.unit}</p>
          <div className="card-actions">
            <button className="ghost" onClick={() => setPage(`business:${item.business.id}`)}>View business</button>
            {me.user?.id !== item.business.ownerId && <button className="ghost" onClick={startChat}>Chat</button>}
            {me.user?.id !== item.business.ownerId && <button className="btn" onClick={() => setEnquiryOpen(true)}>Enquire</button>}
            <WhatsAppButton business={item.business} text={`Hi, I want to discuss ${item.name}.`} targetType="item" targetId={item.id} />
            <ShareButton url={`${window.location.origin}/items/${item.id}`} title={item.name} />
            <ReportButton targetType="item" targetId={item.id} notify={notify} />
          </div>
        </div>
      </article>

      {enquiryOpen && <EnquiryModal business={item.business} item={item} me={me} notify={notify} onClose={() => setEnquiryOpen(false)} />}
    </>
  );

  if (embedded) return <div className="embedded-detail">{content}</div>;

  return (
    <main className="page item-detail-page">
      {content}
    </main>
  );
}

function UploadControl({ label, hint, onChange, multiple = false, full = false }) {
  return (
    <div className={`field ${full ? "full" : ""}`}>
      <label>{label}</label>
      <label className="upload-option">
        <input type="file" accept="image/*" multiple={multiple} onChange={onChange} />
        <span>Upload image</span>
        {hint && <small>{hint}</small>}
      </label>
    </div>
  );
}

function ShareButton({ url, title = "CitySoochna" }) {
  const share = async () => {
    try {
      if (navigator.share) {
        await navigator.share({ title, url });
      } else {
        await navigator.clipboard.writeText(url);
        alert("Share link copied");
      }
    } catch {}
  };
  return <button type="button" className="ghost share-btn" onClick={share}>Share</button>;
}

function whatsappNumber(value) {
  return String(value || "").replace(/\D/g, "");
}

function WhatsAppButton({ business, text, targetType = "business", targetId = "" }) {
  const number = whatsappNumber(business?.whatsapp || business?.socials?.whatsapp || business?.businessPhone);
  if (!number) return null;
  const href = `https://wa.me/${number.length === 10 ? `91${number}` : number}?text=${encodeURIComponent(text || `Hi, I want to discuss ${business.businessName}.`)}`;
  const track = () => {
    api("/api/analytics/whatsapp", { method: "POST", body: JSON.stringify({ businessId: business.id, targetType, targetId: targetId || business.id }) }).catch(() => {});
  };
  return <a className="btn" href={href} target="_blank" rel="noreferrer" onClick={track}>WhatsApp</a>;
}

function SaveBusinessButton({ business, onChange = () => {}, notify, compact = false }) {
  const [saved, setSaved] = useState(Boolean(business?.savedByMe));
  useEffect(() => setSaved(Boolean(business?.savedByMe)), [business?.id, business?.savedByMe]);
  const toggleSave = async () => {
    try {
      const data = await api(`/api/businesses/${business.id}/save`, { method: saved ? "DELETE" : "POST" });
      setSaved(Boolean(data.business.savedByMe));
      onChange(data.business);
      notify(data.business.savedByMe ? "Business saved" : "Removed from saved", data.business.savedByMe ? "You can find it in Saved Businesses." : "Business removed from your saved list.");
    } catch (error) {
      notify("Save failed", error.message);
    }
  };
  return <button className={saved ? `btn ${compact ? "compact-btn" : ""}` : `ghost ${compact ? "compact-btn" : ""}`} onClick={toggleSave}>{saved ? "Saved" : "Save"}</button>;
}

function EnquiryModal({ business, item = null, me, notify, onClose }) {
  const [form, setForm] = useState({
    name: me.user?.name || "",
    email: me.user?.email || "",
    phone: me.user?.phone || "",
    subject: item ? `Enquiry for ${item.name}` : "",
    message: item ? `I want to discuss ${item.name}.` : ""
  });
  const send = async () => {
    try {
      await api("/api/enquiries", {
        method: "POST",
        body: JSON.stringify({
          ...form,
          itemId: item?.id || "",
          businessId: business.id,
          subject: form.subject || (item ? `Enquiry for ${item.name}` : "Business enquiry"),
          message: form.message || (item ? `I want to discuss ${item.name}.` : `I want to discuss ${business.businessName}.`)
        })
      });
      notify("Enquiry sent", "The business owner can reply from their dashboard.");
      onClose();
    } catch (error) {
      notify("Enquiry failed", error.message);
    }
  };
  return (
    <div className="modal-backdrop" onMouseDown={onClose}>
      <section className="modal-panel compact-modal" onMouseDown={(event) => event.stopPropagation()}>
        <div className="detail-head">
          <div>
            <h2>Send enquiry</h2>
            <p className="muted">{item ? item.name : business.businessName}</p>
          </div>
          <button className="icon-btn" onClick={onClose} aria-label="Close"><LucideIcon name="x" label="Close" /></button>
        </div>
        <div className="form-grid compact-form">
          {!me.user && <Field label="Your name" value={form.name} onChange={(value) => setForm({ ...form, name: value })} />}
          {!me.user && <Field label="Your email" type="email" value={form.email} onChange={(value) => setForm({ ...form, email: value })} />}
          <Field label="Phone number" value={form.phone} onChange={(value) => setForm({ ...form, phone: value })} />
          <Field label="Subject" value={form.subject} onChange={(value) => setForm({ ...form, subject: value })} />
          <TextField label="Message" value={form.message} onChange={(value) => setForm({ ...form, message: value })} />
        </div>
        <div className="card-actions">
          <button className="btn" onClick={send}>Send enquiry</button>
          <button className="ghost" onClick={onClose}>Cancel</button>
        </div>
      </section>
    </div>
  );
}

function ReportButton({ targetType, targetId, notify, compact = true }) {
  const [open, setOpen] = useState(false);
  return (
    <>
      <button type="button" className={`ghost ${compact ? "compact-btn" : ""}`} onClick={() => setOpen(true)}>Report</button>
      {open && <ReportModal targetType={targetType} targetId={targetId} notify={notify} onClose={() => setOpen(false)} />}
    </>
  );
}

function ReportModal({ targetType, targetId, notify, onClose }) {
  const [form, setForm] = useState({ reason: REPORT_REASONS[0], message: "" });
  const submit = async () => {
    try {
      await api("/api/reports", { method: "POST", body: JSON.stringify({ ...form, targetType, targetId }) });
      notify("Report submitted", "Admin will review it.");
      onClose();
    } catch (error) {
      notify("Report not submitted", error.message);
    }
  };
  return (
    <div className="modal-backdrop" onMouseDown={onClose}>
      <section className="modal-panel compact-modal" onMouseDown={(event) => event.stopPropagation()}>
        <div className="detail-head">
          <div>
            <h2>Report</h2>
            <p className="muted">Help admin review suspicious or incorrect content.</p>
          </div>
          <button className="icon-btn" onClick={onClose} aria-label="Close"><LucideIcon name="x" label="Close" /></button>
        </div>
        <div className="form-grid compact-form">
          <div className="field">
            <label>Reason</label>
            <select value={form.reason} onChange={(event) => setForm({ ...form, reason: event.target.value })}>
              {REPORT_REASONS.map((reason) => <option key={reason}>{reason}</option>)}
            </select>
          </div>
          <TextField label="Details optional" value={form.message} onChange={(value) => setForm({ ...form, message: value })} />
        </div>
        <div className="card-actions">
          <button className="btn" onClick={submit}>Submit report</button>
          <button className="ghost" onClick={onClose}>Cancel</button>
        </div>
      </section>
    </div>
  );
}

function ClaimBusinessButton({ business, notify }) {
  const [open, setOpen] = useState(false);
  return (
    <>
      <button type="button" className="ghost" onClick={() => setOpen(true)}>Claim business</button>
      {open && <ClaimBusinessModal business={business} notify={notify} onClose={() => setOpen(false)} />}
    </>
  );
}

function ClaimBusinessModal({ business, notify, onClose }) {
  const [form, setForm] = useState({ reason: "", proof: "" });
  const submit = async () => {
    try {
      await api(`/api/businesses/${business.id}/claim`, { method: "POST", body: JSON.stringify(form) });
      notify("Claim submitted", "Admin will review your ownership request.");
      onClose();
    } catch (error) {
      notify("Claim not submitted", error.message);
    }
  };
  return (
    <div className="modal-backdrop" onMouseDown={onClose}>
      <section className="modal-panel compact-modal" onMouseDown={(event) => event.stopPropagation()}>
        <div className="detail-head">
          <div>
            <h2>Claim business</h2>
            <p className="muted">{business.businessName}</p>
          </div>
          <button className="icon-btn" onClick={onClose} aria-label="Close"><LucideIcon name="x" label="Close" /></button>
        </div>
        <div className="form-grid compact-form">
          <TextField label="Why should this business belong to you?" value={form.reason} onChange={(value) => setForm({ ...form, reason: value })} />
          <TextField label="Proof optional" value={form.proof} onChange={(value) => setForm({ ...form, proof: value })} placeholder="GST, phone, website, address proof, or any note admin can verify" />
        </div>
        <div className="card-actions">
          <button className="btn" onClick={submit}>Submit claim</button>
          <button className="ghost" onClick={onClose}>Cancel</button>
        </div>
      </section>
    </div>
  );
}

function Field({ label, value, onChange, type = "text", placeholder = "", full = false }) {
  return (
    <div className={`field ${full ? "full" : ""}`}>
      <label>{label}</label>
      <input type={type} value={value} placeholder={placeholder} onChange={(event) => onChange(event.target.value)} />
    </div>
  );
}

function PasswordField({ label, value, onChange }) {
  const [visible, setVisible] = useState(false);
  return (
    <div className="field password-field">
      <label>{label}</label>
      <div>
        <input type={visible ? "text" : "password"} value={value} onChange={(event) => onChange(event.target.value)} />
        <button type="button" className="ghost" onClick={() => setVisible(!visible)}>{visible ? "Hide" : "View"}</button>
      </div>
    </div>
  );
}

function TextField({ label, value, onChange, placeholder = "" }) {
  return (
    <div className="field full">
      <label>{label}</label>
      <textarea value={value} placeholder={placeholder} onChange={(event) => onChange(event.target.value)} />
    </div>
  );
}

function Footer({ me, setPage }) {
  return (
    <footer className="site-footer">
      <strong>citysoochna</strong>
      <span>Business discovery, enquiries, and local conversations.</span>
      <button className="footer-link" onClick={() => setPage(me.user ? "dashboard:support" : "login")}>Support</button>
      <button className="footer-link" onClick={() => setPage("terms")}>Terms</button>
      <button className="footer-link" onClick={() => setPage("privacy")}>Privacy</button>
      <span>hello@citysoochna.test</span>
    </footer>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
