// ====================================================================
// Tasker24 — Shared components, hooks, i18n helpers, route store
// ====================================================================

const { useState, useEffect, useRef, useMemo, useCallback } = React;

// -------- Tiny route store (hash based) --------
const T24_ROUTES = {
  home:      '#/',
  categories:'#/categories',
  services:  '#/services',
  catDetail: '#/category/',     // + id
  svcDetail: '#/service/',      // + id
  about:     '#/about',
  process:   '#/process',
  registration:'#/registration',
  login:     '#/login',
  contact:   '#/contact',
  faq:       '#/faq',
  terms:     '#/terms',
  privacy:   '#/privacy',
  refund:    '#/refund',
  cookie:    '#/cookie',
  safety:    '#/safety',
  opinion:   '#/opinion',
};

function useRoute() {
  const [hash, setHash] = useState(window.location.hash || '#/');
  useEffect(() => {
    const onHash = () => setHash(window.location.hash || '#/');
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, []);
  // Parse: returns { path, param }
  const path = hash.replace(/^#\//, '').split('/').filter(Boolean);
  return {
    hash,
    page: path[0] || 'home',
    param: path[1] || null,
    go: (h) => { window.location.hash = h; window.scrollTo({top:0, behavior:'smooth'}); },
  };
}

// -------- i18n micro helper --------
const T24_DICT = {
  en: {
    'nav.categories': 'Categories',
    'nav.services':   'Services',
    'nav.process':    'Process',
    'nav.about':      'About',
    'nav.contact':    'Contact',
    'nav.faq':        'FAQ',
    'nav.login':      'Login / Register',
    'nav.dashboard':  'Dashboard',
    'hero.eyebrow':   'Smart service marketplace · Bangladesh',
    'hero.title':     'Tasker24 — Smart Service Marketplace',
    'hero.subtitle':  'Connect with verified providers across 94+ services. Take a service, offer a service, or do both — all on one platform.',
    'hero.search':    'Search category or service',
    'hero.cta1':      'Find a service',
    'hero.cta2':      'Become a provider',
    'common.viewAll': 'View all',
    'common.search':  'Search',
    'common.filter':  'Filter',
    'common.request': 'Request service',
    'common.becomeProvider': 'Become a provider',
    'common.serviceCount': 'services',
    'common.proceed': 'Proceed',
    'role.taker':     'Service Taker',
    'role.provider':  'Service Provider / Freelancer',
    'role.both':      'Service Taker & Provider',
    'safety.title':   'Never share Password / PIN / OTP',
    'safety.text':    'Tasker24 will never ask for your password, banking PIN, or any one-time password (OTP). Anyone who does is a scammer.',
  },
  bn: {
    'nav.categories': 'ক্যাটাগরি',
    'nav.services':   'সেবাসমূহ',
    'nav.process':    'প্রক্রিয়া',
    'nav.about':      'আমাদের সম্পর্কে',
    'nav.contact':    'যোগাযোগ',
    'nav.faq':        'প্রশ্নোত্তর',
    'nav.login':      'লগইন / রেজিস্ট্রেশন',
    'nav.dashboard':  'ড্যাশবোর্ড',
    'hero.eyebrow':   'স্মার্ট সার্ভিস মার্কেটপ্লেস · বাংলাদেশ',
    'hero.title':     'সেবা নিন, সেবা দিন, আয় করুন — সব এক প্ল্যাটফর্মে',
    'hero.subtitle':  '৯৪+ সেবা ও ১১টি ক্যাটাগরির ভেতরে যাচাইকৃত প্রোভাইডারের সাথে সরাসরি যুক্ত হোন। সেবা নিন, সেবা দিন বা দুটোই — এক প্রোফাইলে সব।',
    'hero.search':    'ক্যাটাগরি বা সেবা খুঁজুন',
    'hero.cta1':      'সেবা খুঁজুন',
    'hero.cta2':      'প্রোভাইডার হোন',
    'common.viewAll': 'সব দেখুন',
    'common.search':  'অনুসন্ধান',
    'common.filter':  'ফিল্টার',
    'common.request': 'সেবা চাই',
    'common.becomeProvider': 'প্রোভাইডার হোন',
    'common.serviceCount': 'টি সেবা',
    'common.proceed': 'এগিয়ে যান',
    'role.taker':     'সেবা গ্রহণকারী',
    'role.provider':  'সেবা প্রদানকারী / ফ্রিল্যান্সার',
    'role.both':      'সেবা গ্রহণকারী ও প্রদানকারী',
    'safety.title':   'কখনোই Password / PIN / OTP শেয়ার করবেন না',
    'safety.text':    'Tasker24 কখনোই আপনার পাসওয়ার্ড, ব্যাংকিং PIN বা OTP চাইবে না। কেউ চাইলে সে প্রতারক — সাথে সাথে রিপোর্ট করুন।',
  }
};
function t(lang, key) {
  return (T24_DICT[lang] && T24_DICT[lang][key]) || (T24_DICT.en[key] || key);
}

// -------- Brand logo (uses copied SVG) --------
function BrandMark({ size = 36, withText = true }) {
  return (
    <a href="#/" className="t24-brand">
      <span className="brand-logo">
        <img src="assets/logo/tasker-logo.svg" alt="Tasker24"
             style={{ width: '70%', height: '70%' }} />
      </span>
      {withText && (
        <span className="brand-text">Tasker <small>24</small></span>
      )}
    </a>
  );
}

// -------- Dropdown helper --------
function Dropdown({ trigger, items, align = 'left' }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('click', onDoc);
    return () => document.removeEventListener('click', onDoc);
  }, []);
  return (
    <div className="t24-dd" ref={ref}>
      <button type="button" className="t24-dd-trigger" onClick={()=>setOpen(o=>!o)}>
        {trigger} <i className="bi bi-chevron-down" style={{fontSize:12}}></i>
      </button>
      {open && (
        <div className="t24-dd-menu" style={align==='right'?{left:'auto', right:0}:null}>
          {items.map((it, i) => {
            if (it.sep) return <div key={i} className="sep"></div>;
            return (
              <a key={i} href={it.href || '#/'}
                 onClick={(e)=>{ if(it.onClick){ e.preventDefault(); it.onClick(); } setOpen(false); }}>
                {it.icon && <i className={"bi "+it.icon} style={{color:'var(--t24-blue)'}}></i>}
                <span>{it.label}</span>
                {it.right && <span className="ms-auto small text-muted">{it.right}</span>}
              </a>
            );
          })}
        </div>
      )}
    </div>
  );
}

// -------- Integrated category + keyword search bar --------
function MegaSearch({ lang, defaultCat = 'all', defaultQuery = '', placeholder }) {
  const { cats } = window.T24;
  const [cat, setCat] = useState(defaultCat);
  const [q, setQ] = useState(defaultQuery);
  const onSubmit = (e) => {
    e.preventDefault();
    const params = new URLSearchParams();
    if (q) params.set('q', q);
    if (cat !== 'all') params.set('cat', cat);
    window.location.hash = '#/services' + (params.toString() ? ('?'+params.toString()) : '');
  };
  return (
    <form className="t24-megasearch" onSubmit={onSubmit}>
      <select className="ms-cat" value={cat} onChange={e=>setCat(e.target.value)} aria-label="Category">
        <option value="all">{lang==='bn'?'সব ক্যাটাগরি':'All Categories'}</option>
        {cats.map(c=>(<option key={c.id} value={c.id}>{c.name}</option>))}
      </select>
      <input className="ms-input" value={q} onChange={e=>setQ(e.target.value)}
             placeholder={placeholder || (lang==='bn'?'২০,০০০+ সেবা থেকে খুঁজুন…':'Search for more than 20,000 services…')} />
      <button className="ms-btn" type="submit">
        <i className="bi bi-search"></i>
        <span className="d-none d-md-inline">Search</span>
      </button>
    </form>
  );
}

// -------- Top navbar with utility bar --------
function TopNav({ route, lang, setLang, theme, setTheme, loggedIn, setLoggedIn, onOpenMobileMenu }) {
  const sloganBN = 'সেবা গ্রহণকারী এবং প্রদানকারীর সেতুবন্ধন';
  const sloganEN = 'Bridge of Service Taker & Provider';
  const { cats } = window.T24;

  const servicesMenu = cats.slice(0, 8).map(c => ({
    label: c.name, icon: 'bi-arrow-right-short', href: '#/category/'+c.id,
  })).concat([
    { sep: true },
    { label: lang==='bn'?'সব ক্যাটাগরি দেখুন':'View all categories', icon:'bi-grid-3x3-gap', href:'#/categories' },
    { label: lang==='bn'?'সব সেবা দেখুন':'View all services', icon:'bi-list', href:'#/services' },
  ]);

  const companyMenu = [
    { label: lang==='bn'?'আমাদের সম্পর্কে':'About Us', icon: 'bi-info-circle', href: '#/about' },
    { label: lang==='bn'?'প্রক্রিয়া':'How it works', icon: 'bi-diagram-3', href: '#/process' },
    { label: lang==='bn'?'যোগাযোগ':'Contact', icon: 'bi-envelope', href: '#/contact' },
    { label: 'FAQ', icon: 'bi-question-circle', href: '#/faq' },
    { sep: true },
    { label: lang==='bn'?'নিরাপত্তা':'Safety & Security', icon: 'bi-shield-check', href: '#/safety' },
    { label: lang==='bn'?'অভিমত':'Opinion & Feedback', icon: 'bi-chat-square-text', href: '#/opinion' },
  ];

  return (
    <>
      {/* Dark utility bar */}
      <div className="t24-utility-bar">
        <div className="container py-2 d-flex align-items-center justify-content-between flex-wrap gap-2">
          <div className="d-flex align-items-center gap-3 flex-wrap">
            <a href="#/contact" className="d-inline-flex align-items-center gap-1"><i className="bi bi-geo-alt"></i> {lang==='bn'?'লোকেশন খুঁজুন':'Find a location'}</a>
            <span className="opacity-50 d-none d-md-inline">·</span>
            <a href="mailto:info@tasker24.net" className="d-inline-flex align-items-center gap-1"><i className="bi bi-envelope"></i> info@tasker24.net</a>
            <span className="opacity-50 d-none d-md-inline">·</span>
            <span className="d-none d-md-inline" style={{color:'#9FB3D9'}}>{lang==='bn'?sloganBN:sloganEN}</span>
          </div>
          <div className="d-flex align-items-center gap-3">
            <div className="d-none d-md-inline-flex align-items-center gap-2">
              <a href="#/" aria-label="Facebook" style={{width:24, height:24, borderRadius:'50%', background:'rgba(255,255,255,.08)', display:'grid', placeItems:'center', fontSize:12, color:'#fff'}}><i className="bi bi-facebook"></i></a>
              <a href="#/" aria-label="X/Twitter" style={{width:24, height:24, borderRadius:'50%', background:'rgba(255,255,255,.08)', display:'grid', placeItems:'center', fontSize:12, color:'#fff'}}><i className="bi bi-twitter-x"></i></a>
              <a href="#/" aria-label="Instagram" style={{width:24, height:24, borderRadius:'50%', background:'rgba(255,255,255,.08)', display:'grid', placeItems:'center', fontSize:12, color:'#fff'}}><i className="bi bi-instagram"></i></a>
              <a href="#/" aria-label="LinkedIn" style={{width:24, height:24, borderRadius:'50%', background:'rgba(255,255,255,.08)', display:'grid', placeItems:'center', fontSize:12, color:'#fff'}}><i className="bi bi-linkedin"></i></a>
            </div>
            <div className="d-flex align-items-center gap-2">
              <i className="bi bi-globe2" style={{color:'var(--t24-cyan)'}}></i>
              <select value={lang} onChange={e=>setLang(e.target.value)}
                      className="bg-transparent border-0"
                      style={{color:'#fff', fontSize:12.5, fontWeight:600, outline:'none'}}>
                <option value="en" style={{color:'#000'}}>English</option>
                <option value="bn" style={{color:'#000'}}>বাংলা</option>
              </select>
            </div>
            <button className="t24-icon-btn d-none d-md-inline-flex" style={{width:30, height:30, background:'rgba(255,255,255,.08)', borderColor:'transparent', color:'#fff'}}
              title={theme==='dark'?'Light theme':'Dark theme'}
              onClick={()=>setTheme(theme==='dark'?'light':'dark')}>
              <i className={"bi "+(theme==='dark'?'bi-sun':'bi-moon')} style={{fontSize:14}}></i>
            </button>
          </div>
        </div>
      </div>

      {/* Main nav with integrated search */}
      <nav className="t24-nav t24-nav--with-search">
        <div className="container d-flex align-items-center py-3 gap-3">
          <BrandMark size={36} />
          <div className="flex-grow-1 d-none d-lg-block" style={{maxWidth: 560, marginInline: '8px'}}>
            <MegaSearch lang={lang}/>
          </div>
          <div className="ms-auto d-flex align-items-center gap-1">
            <div className="d-none d-lg-flex align-items-center gap-1">
              <Dropdown trigger={<span><i className="bi bi-grid-3x3-gap me-1"></i> {lang==='bn'?'সকল সেবা':'All Services'}</span>} items={servicesMenu}/>
              <Dropdown trigger={<span>{lang==='bn'?'প্রতিষ্ঠান':'Company'}</span>} items={companyMenu}/>
            </div>
            {loggedIn ? (
              <a className="btn btn-t24 px-3 ms-2 d-none d-sm-inline-flex" href="#/" onClick={(e)=>{e.preventDefault();}}>
                <i className="bi bi-speedometer2 me-2"></i>{t(lang,'nav.dashboard')}
              </a>
            ) : (
              <a className="btn btn-t24 px-3 ms-2 d-none d-sm-inline-flex" href="#/login">
                {t(lang,'nav.login')}
              </a>
            )}
            <button className="t24-icon-btn d-lg-none" onClick={onOpenMobileMenu} aria-label="Open menu">
              <i className="bi bi-list"></i>
            </button>
          </div>
        </div>
        {/* Mobile: search on its own row */}
        <div className="container d-lg-none pb-3">
          <MegaSearch lang={lang}/>
        </div>
      </nav>
    </>
  );
}

// -------- Mobile menu drawer --------
function MobileMenu({ open, onClose, lang, setLang, theme, setTheme }) {
  if (!open) return null;
  const items = [
    ['categories', t(lang,'nav.categories')],
    ['services',   t(lang,'nav.services')],
    ['process',    t(lang,'nav.process')],
    ['about',      t(lang,'nav.about')],
    ['contact',    t(lang,'nav.contact')],
    ['faq',        t(lang,'nav.faq')],
    ['safety',     'Safety & Security'],
    ['opinion',    'Opinion & Feedback'],
  ];
  return (
    <div className="t24-modal-bd" onClick={onClose}>
      <div className="t24-modal" style={{maxWidth:380, marginTop:'5vh', alignSelf:'flex-start'}}
           onClick={(e)=>e.stopPropagation()}>
        <div className="p-3 d-flex align-items-center justify-content-between border-bottom" style={{borderColor:'var(--t24-card-border)'}}>
          <div className="brand-mark"><BrandMark size={28}/><span className="ms-2 fw-bold">Tasker<span style={{color:'var(--t24-blue)'}}>24</span></span></div>
          <button className="t24-icon-btn" onClick={onClose}><i className="bi bi-x-lg"></i></button>
        </div>
        <div className="p-3 d-flex flex-column gap-1">
          {items.map(([id, label]) => (
            <a key={id} className="nav-link" href={"#/"+id} onClick={onClose}>{label}</a>
          ))}
          <hr/>
          <div className="d-flex align-items-center justify-content-between">
            <small className="text-muted">Language</small>
            <div className="t24-seg">
              <button className={lang==='en'?'active':''} onClick={()=>setLang('en')}>EN</button>
              <button className={lang==='bn'?'active':''} onClick={()=>setLang('bn')}>বাং</button>
            </div>
          </div>
          <div className="d-flex align-items-center justify-content-between mt-2">
            <small className="text-muted">Theme</small>
            <div className="t24-seg">
              <button className={theme==='light'?'active':''} onClick={()=>setTheme('light')}>Light</button>
              <button className={theme==='dark'?'active':''} onClick={()=>setTheme('dark')}>Dark</button>
            </div>
          </div>
          <a className="btn btn-t24 mt-3" href="#/login" onClick={onClose}>{t(lang,'nav.login')}</a>
        </div>
      </div>
    </div>
  );
}

// -------- Page hero (breadcrumb) --------
function PageHero({ eyebrow, title, subtitle, crumbs = [], children }) {
  return (
    <section className="t24-page-hero">
      <div className="container">
        {crumbs.length>0 && (
          <nav className="crumb mb-3">
            {crumbs.map((c, i) => (
              <span key={i} className="d-inline-flex align-items-center gap-2">
                {c.href ? <a href={c.href}>{c.label}</a> : <span style={{color:'var(--t24-text-2)'}}>{c.label}</span>}
                {i < crumbs.length-1 && <i className="bi bi-chevron-right"></i>}
              </span>
            ))}
          </nav>
        )}
        {eyebrow && <div className="t24-chip mb-3"><i className="bi bi-stars"></i> {eyebrow}</div>}
        <h1 className="display-5 fw-bold mb-2" style={{maxWidth: '20ch'}}>{title}</h1>
        {subtitle && <p className="lead text-muted" style={{maxWidth:'70ch'}}>{subtitle}</p>}
        {children}
      </div>
    </section>
  );
}

// -------- Footer --------
function Footer({ lang }) {
  return (
    <footer className="t24-footer mt-auto">
      <div className="container">
        <div className="row gy-4">
          <div className="col-md-4">
            <div className="d-flex align-items-center gap-2 mb-3">
              <span style={{width:42, height:42, borderRadius:12, background:'rgba(34,211,238,.12)', display:'grid', placeItems:'center', border:'1px solid rgba(120,170,255,.2)'}}>
                <img src="assets/logo/tasker-logo.svg" alt="" style={{width:'70%', height:'70%', filter:'drop-shadow(0 0 14px rgba(34,211,238,.5))'}}/>
              </span>
              <div className="footer-brand">Tasker <span style={{color:'var(--t24-cyan)'}}>24</span></div>
            </div>
            <p style={{color:'#9FB3D9', lineHeight: 1.7}}>
              The bridge between Service Takers and Service Providers/Freelancers across Bangladesh.
              Take a service, offer a service, or do both — all on one platform.
            </p>
            <p className="lang-bn mb-3" style={{color:'#9FB3D9'}}>
              সেবা গ্রহণকারী এবং প্রদানকারীর সেতুবন্ধন
            </p>
            <div className="d-flex gap-2 flex-wrap">
              <a href="#/" className="t24-app-btn">
                <i className="bi bi-apple ic"></i>
                <div>
                  <div className="label">Download on the</div>
                  <div className="name">App Store</div>
                </div>
              </a>
              <a href="#/" className="t24-app-btn alt">
                <i className="bi bi-google-play ic"></i>
                <div>
                  <div className="label">Get it on</div>
                  <div className="name">Google Play</div>
                </div>
              </a>
            </div>
          </div>
          <div className="col-6 col-md-2">
            <h6 className="mb-3">Company</h6>
            <ul className="list-unstyled d-flex flex-column gap-2">
              <li><a href="#/about">About Us</a></li>
              <li><a href="#/process">Process</a></li>
              <li><a href="#/contact">Contact</a></li>
              <li><a href="#/opinion">Feedback</a></li>
              <li><a href="#/safety">Safety</a></li>
            </ul>
          </div>
          <div className="col-6 col-md-2">
            <h6 className="mb-3">Quick Links</h6>
            <ul className="list-unstyled d-flex flex-column gap-2">
              <li><a href="#/categories">Categories</a></li>
              <li><a href="#/services">All Services</a></li>
              <li><a href="#/registration">Registration</a></li>
              <li><a href="#/login">Login</a></li>
              <li><a href="#/faq">FAQ</a></li>
            </ul>
          </div>
          <div className="col-md-4">
            <h6 className="mb-3">Get in touch</h6>
            <ul className="list-unstyled d-flex flex-column gap-2 mb-3">
              <li><i className="bi bi-geo-alt me-2" style={{color:'var(--t24-cyan)'}}></i> House 24, Road 7, Dhanmondi, Dhaka 1209</li>
              <li><i className="bi bi-envelope me-2" style={{color:'var(--t24-cyan)'}}></i> info@tasker24.net &nbsp;·&nbsp; support@tasker24.net</li>
              <li><i className="bi bi-telephone me-2" style={{color:'var(--t24-cyan)'}}></i> +880 1700-000000</li>
              <li><i className="bi bi-clock me-2" style={{color:'var(--t24-cyan)'}}></i> Customer support — 24/7</li>
            </ul>
            <div className="d-flex gap-2 mb-3">
              <a className="t24-icon-btn" style={{background:'rgba(255,255,255,.06)', borderColor:'transparent', color:'#fff'}} href="#/" aria-label="Facebook"><i className="bi bi-facebook"></i></a>
              <a className="t24-icon-btn" style={{background:'rgba(255,255,255,.06)', borderColor:'transparent', color:'#fff'}} href="#/" aria-label="X"><i className="bi bi-twitter-x"></i></a>
              <a className="t24-icon-btn" style={{background:'rgba(255,255,255,.06)', borderColor:'transparent', color:'#fff'}} href="#/" aria-label="Instagram"><i className="bi bi-instagram"></i></a>
              <a className="t24-icon-btn" style={{background:'rgba(255,255,255,.06)', borderColor:'transparent', color:'#fff'}} href="#/" aria-label="LinkedIn"><i className="bi bi-linkedin"></i></a>
              <a className="t24-icon-btn" style={{background:'rgba(255,255,255,.06)', borderColor:'transparent', color:'#fff'}} href="#/" aria-label="YouTube"><i className="bi bi-youtube"></i></a>
            </div>
            <div>
              <div className="small mb-2" style={{color:'#9FB3D9'}}>Payments accepted</div>
              <div className="t24-pay-row">
                <span className="t24-pay-chip">bKash</span>
                <span className="t24-pay-chip">Nagad</span>
                <span className="t24-pay-chip">Rocket</span>
                <span className="t24-pay-chip">VISA</span>
                <span className="t24-pay-chip">MC</span>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div className="small-print">
        <div className="container d-flex justify-content-between align-items-center flex-wrap gap-2">
          <div>© {new Date().getFullYear()} <strong style={{color:'#fff'}}>Tasker24.Net</strong> — All rights reserved.</div>
          <div className="d-flex align-items-center gap-3 flex-wrap">
            <a href="#/terms">Terms</a>
            <a href="#/privacy">Privacy</a>
            <a href="#/refund">Refund</a>
            <a href="#/cookie">Cookie</a>
            <span className="opacity-50">·</span>
            <span>Powered by <strong style={{color:'#fff'}}>Technoration Ltd.</strong></span>
            <button className="t24-icon-btn" style={{width:32, height:32, background:'var(--t24-blue)', borderColor:'transparent', color:'#fff'}}
                    onClick={()=>window.scrollTo({top:0, behavior:'smooth'})} aria-label="Back to top">
              <i className="bi bi-arrow-up"></i>
            </button>
          </div>
        </div>
      </div>
    </footer>
  );
}

// -------- Category icon (uses SVG) --------
function CatIcon({ cat, size = 'md' }) {
  const cls = size === 'lg' ? 't24-iconbox t24-iconbox--lg' : (size==='sm' ? 't24-iconbox t24-iconbox--sm' : 't24-iconbox');
  return (
    <div className={cls}>
      <img src={cat.icon} alt={cat.name} />
    </div>
  );
}

// -------- Category card --------
function CategoryCard({ cat, lang, active, onClick }) {
  const name = lang==='bn' ? cat.nameBn : cat.name;
  const desc = lang==='bn' ? cat.descBn : cat.desc;
  return (
    <a href={"#/category/"+cat.id} onClick={(e)=>{ if(onClick){ e.preventDefault(); onClick(cat); } }}
       className={"t24-card t24-cat-card text-decoration-none "+(active?'t24-card--active':'')}>
      <CatIcon cat={cat} />
      <div>
        <div className="fw-bold mb-1" style={{color:'var(--t24-text-1)', fontSize: 16}}>{name}</div>
        <div className="small text-muted" style={{minHeight: 38}}>{desc}</div>
      </div>
      <div className="meta">
        <span className="count">{cat.count} {t(lang,'common.serviceCount')}</span>
        <i className="bi bi-arrow-right" style={{color:'var(--t24-blue)'}}></i>
      </div>
    </a>
  );
}

// -------- Service card --------
function ServiceCard({ svc, onOpen }) {
  // We map an FA-ish icon as a Bootstrap Icon fallback; otherwise the category icon
  const cat = window.T24.cats.find(c=>c.id===svc.catId);
  return (
    <div className="t24-card t24-svc-card t24-card--lift" role="button" onClick={()=>onOpen(svc)}>
      <div className="d-flex align-items-center gap-3">
        <div className="t24-iconbox t24-iconbox--sm"><img src={cat.icon} alt=""/></div>
        <div className="flex-grow-1">
          <div className="small text-muted text-uppercase" style={{letterSpacing:'.06em', fontSize: 10.5}}>{cat.name}</div>
          <div className="fw-bold" style={{color:'var(--t24-text-1)'}}>{svc.name}</div>
        </div>
      </div>
      <div className="small text-muted">{svc.description}</div>
      {svc.unit && svc.unit.length>0 && (
        <div className="sub-chips">
          {svc.unit.map((u,i)=>(<span key={i} className="t24-chip t24-chip--cyan"><i className="bi bi-dot"></i>{u.name}</span>))}
        </div>
      )}
      <div className="d-flex justify-content-between align-items-center mt-2">
        <span className="t24-chip"><i className="bi bi-people-fill"></i> Providers nearby</span>
        <span style={{color:'var(--t24-blue)', fontWeight: 700, fontSize: 13}}>Open <i className="bi bi-arrow-up-right"></i></span>
      </div>
    </div>
  );
}

// -------- Provider card --------
function ProviderCard({ p }) {
  return (
    <div className="t24-card t24-provider">
      <div className="avatar">{p.init}</div>
      <div className="flex-grow-1">
        <div className="d-flex align-items-center gap-2">
          <strong style={{fontSize:15}}>{p.name}</strong>
          {p.verified && <span className="t24-chip t24-chip--success" style={{padding:'2px 8px', fontSize:11}}><i className="bi bi-patch-check-fill"></i> Verified</span>}
        </div>
        <div className="small text-muted">{p.role} · {p.area}</div>
        <div className="d-flex align-items-center gap-3 mt-1">
          <span style={{color:'var(--t24-warning)', fontSize:13}}>
            <i className="bi bi-star-fill"></i> <strong style={{color:'var(--t24-text-1)'}}>{p.rating}</strong>
            <span className="text-muted ms-1">({p.jobs})</span>
          </span>
          {p.tags && p.tags.map((tg, i)=>(<span key={i} className="t24-chip" style={{fontSize:11, padding:'3px 8px'}}>{tg}</span>))}
        </div>
      </div>
      <button className="btn btn-t24-ghost btn-sm">Message</button>
    </div>
  );
}

// -------- Safety warning card --------
function SafetyCard({ lang, compact }) {
  return (
    <div className={"t24-card t24-safety p-3 p-md-4 d-flex gap-3 "+(compact?'':'mb-3')}>
      <div style={{fontSize: 28, lineHeight: 1}}><i className="bi bi-shield-exclamation"></i></div>
      <div>
        <div className="fw-bold mb-1">{t(lang,'safety.title')}</div>
        <div className="small">{t(lang,'safety.text')}</div>
      </div>
    </div>
  );
}

// -------- Cookie consent --------
function CookieConsent({ onClose }) {
  const [shown, setShown] = useState(false);
  const [open, setOpen] = useState(false);
  const [prefs, setPrefs] = useState({ necessary: true, analytics: true, marketing: false });
  useEffect(() => {
    const seen = sessionStorage.getItem('t24-cookies-seen');
    if (!seen) setTimeout(()=>setShown(true), 1200);
  }, []);
  if (!shown) return null;
  const dismiss = () => { sessionStorage.setItem('t24-cookies-seen', '1'); setShown(false); };
  return (
    <div className="t24-card t24-cookie t24-card--glass">
      {!open ? (
        <div className="d-flex flex-wrap align-items-center gap-3">
          <div style={{fontSize: 22}}>🍪</div>
          <div className="flex-grow-1" style={{minWidth:240}}>
            <strong>We use cookies to make Tasker24 work for you.</strong>
            <div className="small text-muted">Necessary cookies keep you signed in. Analytics & marketing help us improve. See <a href="#/cookie">Cookie Policy</a>.</div>
          </div>
          <div className="d-flex gap-2 flex-wrap">
            <button className="btn btn-t24-ghost btn-sm" onClick={()=>setOpen(true)}>Manage</button>
            <button className="btn btn-t24-outline btn-sm" onClick={()=>{ setPrefs({necessary:true, analytics:false, marketing:false}); dismiss(); }}>Reject optional</button>
            <button className="btn btn-t24 btn-sm" onClick={dismiss}>Accept all</button>
          </div>
        </div>
      ) : (
        <div>
          <div className="d-flex align-items-center justify-content-between mb-2">
            <strong>Cookie preferences</strong>
            <button className="t24-icon-btn" onClick={()=>setOpen(false)}><i className="bi bi-x-lg"></i></button>
          </div>
          <CookieToggle title="Necessary" desc="Required for sign-in, security, and core platform features." checked={true} disabled />
          <CookieToggle title="Analytics" desc="Help us improve UX by collecting anonymous usage data." checked={prefs.analytics} onChange={v=>setPrefs(p=>({...p, analytics:v}))} />
          <CookieToggle title="Marketing" desc="Personalize promotional content. Not used for selling data." checked={prefs.marketing} onChange={v=>setPrefs(p=>({...p, marketing:v}))} />
          <div className="d-flex justify-content-end gap-2 mt-3">
            <button className="btn btn-t24-outline btn-sm" onClick={dismiss}>Save preferences</button>
            <button className="btn btn-t24 btn-sm" onClick={dismiss}>Accept all</button>
          </div>
        </div>
      )}
    </div>
  );
}
function CookieToggle({ title, desc, checked, onChange, disabled }) {
  return (
    <label className="d-flex align-items-start gap-3 py-2" style={{cursor: disabled?'default':'pointer'}}>
      <input type="checkbox" className="form-check-input mt-1" checked={!!checked}
             disabled={disabled} onChange={(e)=>onChange && onChange(e.target.checked)} />
      <div>
        <div className="fw-semibold">{title}</div>
        <div className="small text-muted">{desc}</div>
      </div>
    </label>
  );
}

// -------- Hero carousel --------
function HeroCarousel({ banners, autoMs = 6000 }) {
  const [i, setI] = useState(0);
  useEffect(() => {
    const t = setInterval(() => setI(v => (v+1) % banners.length), autoMs);
    return () => clearInterval(t);
  }, [banners.length, autoMs]);
  return (
    <div className="position-relative t24-hero" style={{padding:0, overflow:'hidden'}}>
      <div style={{display:'flex', transform:`translateX(${-i*100}%)`, transition:'transform .7s cubic-bezier(.5,0,.2,1)'}}>
        {banners.map((b, idx) => (
          <div key={idx} style={{flex:'0 0 100%'}}>
            <img src={b.src} alt={b.alt} className="hero-img" style={{aspectRatio:'21/9', width:'100%', objectFit:'cover'}}/>
          </div>
        ))}
      </div>
      <div className="position-absolute" style={{left:16, right:16, bottom:16, display:'flex', justifyContent:'center'}}>
        <div className="t24-dots" style={{background:'rgba(8,18,42,.55)', backdropFilter:'blur(8px)', padding:'8px 12px', borderRadius:999}}>
          {banners.map((_, idx) => (
            <button key={idx} className={idx===i?'active':''} onClick={()=>setI(idx)} aria-label={"slide "+(idx+1)} />
          ))}
        </div>
      </div>
      <button className="t24-icon-btn position-absolute top-50 translate-middle-y" style={{left:14, background:'rgba(255,255,255,.85)', borderColor:'transparent'}}
        onClick={()=>setI((i-1+banners.length)%banners.length)} aria-label="Previous"><i className="bi bi-chevron-left"></i></button>
      <button className="t24-icon-btn position-absolute top-50 translate-middle-y" style={{right:14, background:'rgba(255,255,255,.85)', borderColor:'transparent'}}
        onClick={()=>setI((i+1)%banners.length)} aria-label="Next"><i className="bi bi-chevron-right"></i></button>
    </div>
  );
}

// -------- Search box --------
function SearchBox({ placeholder, value, onChange, onSubmit, dense }) {
  return (
    <form className="t24-search" onSubmit={(e)=>{ e.preventDefault(); onSubmit && onSubmit(value); }}
          style={dense ? {padding:'4px 4px 4px 14px'} : null}>
      <i className="bi bi-search" style={{color:'var(--t24-text-3)'}}></i>
      <input value={value||''} onChange={e=>onChange(e.target.value)} placeholder={placeholder} />
      <button className="btn btn-t24 px-4" type="submit"><i className="bi bi-arrow-right d-md-none"></i><span className="d-none d-md-inline">Search</span></button>
    </form>
  );
}

// -------- Toast --------
function Toast({ show, text, onClose }) {
  useEffect(() => { if (show) { const t=setTimeout(onClose, 2800); return ()=>clearTimeout(t);} }, [show]);
  if (!show) return null;
  return (
    <div className="t24-toast">
      <span className="dot"></span>
      <div className="flex-grow-1">
        <div className="fw-semibold" style={{fontSize:14}}>Success</div>
        <div className="small text-muted">{text}</div>
      </div>
      <button className="t24-icon-btn" onClick={onClose} aria-label="dismiss"><i className="bi bi-x"></i></button>
    </div>
  );
}

// -------- Category rail (left sidebar — sample UI direction) --------
function CategoryRail({ lang, openService }) {
  const { cats } = window.T24;
  const [hoverId, setHoverId] = useState(null);
  return (
    <div className="t24-rail">
      <div className="t24-rail__head">
        <strong>{lang==='bn'?'ক্যাটাগরি':'Browse categories'}</strong>
        <a href="#/categories" className="small fw-semibold" style={{color:'var(--t24-blue)'}}>
          {lang==='bn'?'সব':'See all'} <i className="bi bi-arrow-right"></i>
        </a>
      </div>
      <div onMouseLeave={()=>setHoverId(null)}>
        {cats.map(c => (
          <div key={c.id}
               className={"t24-rail__item "+(hoverId===c.id?'active':'')}
               onMouseEnter={()=>setHoverId(c.id)}
               onClick={()=>{ window.location.hash = '#/category/'+c.id; }}>
            <img src={c.icon} alt=""/>
            <span className="name">{lang==='bn'?c.nameBn:c.name}</span>
            <i className="bi bi-chevron-right chev"></i>
            {hoverId === c.id && (
              <div className="t24-rail__flyout" onClick={(e)=>e.stopPropagation()}>
                <div className="small text-muted px-2 pb-2" style={{fontSize:11, textTransform:'uppercase', letterSpacing:'.1em'}}>
                  {c.count} {lang==='bn'?'টি সেবা':'services'}
                </div>
                {c.services.slice(0, 10).map((s, i) => {
                  const svc = window.T24.services.find(x=>x.short===s.short && x.catId===c.id);
                  return (
                    <a key={i} href="#"
                       onClick={(e)=>{ e.preventDefault(); openService && openService(svc); }}>
                      <i className="bi bi-dot" style={{color:'var(--t24-blue)'}}></i>
                      {s.name}
                    </a>
                  );
                })}
                {c.services.length > 10 && (
                  <a href={"#/category/"+c.id} className="mt-1" style={{color:'var(--t24-blue)', fontWeight:700}}>
                    <i className="bi bi-arrow-right"></i> {lang==='bn'?'আরো দেখুন':'See all '+c.count+' services'}
                  </a>
                )}
              </div>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

// -------- Animated counter (count-up on enter) --------
function CountUp({ to, prefix = '', suffix = '+', duration = 1400 }) {
  const [val, setVal] = useState(0);
  const ref = useRef(null);
  const started = useRef(false);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach(en => {
        if (en.isIntersecting && !started.current) {
          started.current = true;
          const t0 = performance.now();
          const tick = (now) => {
            const p = Math.min(1, (now - t0) / duration);
            const eased = 1 - Math.pow(1 - p, 3);
            setVal(Math.floor(eased * to));
            if (p < 1) requestAnimationFrame(tick);
            else setVal(to);
          };
          requestAnimationFrame(tick);
        }
      });
    }, { threshold: 0.3 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [to, duration]);
  return <span ref={ref}>{prefix}{val.toLocaleString()}{suffix}</span>;
}

function CounterSection() {
  const items = [
    { n: 8420,  icon: 'bi-hand-thumbs-up-fill', label: 'Happy clients' },
    { n: 12500, icon: 'bi-people-fill',         label: 'Active providers' },
    { n: 94,    icon: 'bi-grid-3x3-gap-fill',   label: 'Services offered' },
    { n: 24,    icon: 'bi-clock-fill',          label: 'Hours support / day', suffix:'/7' },
  ];
  return (
    <section className="t24-counter-strip py-5">
      <div className="container">
        <div className="row g-3">
          {items.map((it, i) => (
            <div className="col-6 col-md-3" key={i}>
              <div className="t24-counter">
                <div className="ring"><i className={"bi "+it.icon}></i></div>
                <div className="n"><CountUp to={it.n} suffix={it.suffix || '+'} /></div>
                <div className="l">{it.label}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// -------- Section title --------
function SectionTitle({ eyebrow, title, subtitle, action }) {
  return (
    <div className="t24-section-title">
      <div>
        {eyebrow && <div className="eyebrow"><i className="bi bi-stars"></i>{eyebrow}</div>}
        <h2>{title}</h2>
        {subtitle && <p>{subtitle}</p>}
      </div>
      {action}
    </div>
  );
}

// -------- Expose to window --------
Object.assign(window, {
  useRoute, t, T24_DICT, T24_ROUTES,
  BrandMark, Dropdown, MegaSearch, TopNav, MobileMenu, PageHero, Footer,
  CatIcon, CategoryCard, ServiceCard, ProviderCard,
  SafetyCard, CookieConsent, HeroCarousel, SearchBox,
  Toast, SectionTitle, CategoryRail, CountUp, CounterSection,
});
