/* Shared store — used by both customer site and admin dashboard.
   Persists in localStorage. Seeded with demo data on first load. */

const STORE_KEYS = {
  requests: 'prestige.requests',
  session:  'prestige.adminSession',
};

const ADMIN_USER = { username: 'admin', password: 'prestige2026' };
const SESSION_TTL_HOURS = 12;

const STATUS = {
  PENDING:   'pending',
  CONFIRMED: 'confirmed',
  COMPLETED: 'completed',
  CANCELLED: 'cancelled',
};

const STATUS_LABEL = {
  pending:   'Pending review',
  confirmed: 'Confirmed',
  completed: 'Completed',
  cancelled: 'Cancelled',
};

/* --- Date helpers ----------------------------------------- */
const ymd = (d) => {
  const dt = (d instanceof Date) ? d : new Date(d);
  const y = dt.getFullYear();
  const m = String(dt.getMonth()+1).padStart(2,'0');
  const day = String(dt.getDate()).padStart(2,'0');
  return `${y}-${m}-${day}`;
};
const fromYmd = (s) => {
  const [y, m, d] = s.split('-').map(Number);
  return new Date(y, m-1, d);
};
const today = () => { const d = new Date(); d.setHours(0,0,0,0); return d; };
const addDays = (d, n) => { const r = new Date(d); r.setDate(r.getDate()+n); return r; };
const fmtDate = (d) => (d instanceof Date ? d : fromYmd(d)).toLocaleDateString('en-US',{
  weekday:'short', month:'short', day:'numeric'
});
const fmtDateLong = (d) => (d instanceof Date ? d : fromYmd(d)).toLocaleDateString('en-US',{
  weekday:'long', year:'numeric', month:'long', day:'numeric'
});

/* --- Seed mock data --------------------------------------- */
const VEHICLE_OPTIONS = [
  { id:'sedan',  label:'Sedan / Hatchback', mult:1.00, base:60 },
  { id:'suv',    label:'SUV',               mult:1.25, base:60 },
  { id:'pickup', label:'Pickup Truck',      mult:1.35, base:60 },
  { id:'van',    label:'Van / Family',      mult:1.30, base:60 },
  { id:'lux',    label:'Luxury / Sports',   mult:1.45, base:60 },
  { id:'comm',   label:'Commercial Van',    mult:1.55, base:60 },
];
const SERVICE_OPTIONS = [
  { id:'ext',    label:'Exterior Wash',           duration:45,  price:0 },
  { id:'both',   label:'Interior & Exterior',     duration:75,  price:30 },
  { id:'detail', label:'Full Detail',             duration:150, price:90 },
  { id:'intd',   label:'Interior Deep Cleaning',  duration:120, price:70 },
  { id:'wax',    label:'Wax & Paint Protection',  duration:90,  price:60 },
  { id:'spa',    label:'Premium Auto Spa',        duration:210, price:160 },
];
const SLOT_OPTIONS = ['8:00 AM','9:30 AM','11:00 AM','12:30 PM','2:00 PM','3:30 PM','5:00 PM'];

const buildSeed = () => {
  const t = today();
  const make = (offset, slot, vehId, svcId, status, customer) => {
    const veh = VEHICLE_OPTIONS.find(v => v.id === vehId);
    const svc = SERVICE_OPTIONS.find(s => s.id === svcId);
    const subtotal = Math.round((veh.base + svc.price) * veh.mult);
    return {
      id: `REQ-${Date.now().toString(36).slice(-4)}-${Math.random().toString(36).slice(2,6).toUpperCase()}`,
      createdAt: addDays(t, offset - 2).toISOString(),
      status,
      paid: status !== 'cancelled',
      customer,
      address: { line: customer.addr || '1245 Sunset Blvd', city: customer.city || 'Beverly Hills', zip: customer.zip || '90210', notes: '' },
      vehicle: veh,
      service: svc,
      date: ymd(addDays(t, offset)),
      slot,
      payment: 'card',
      promo: null,
      pricing: { subtotal, total: Math.round(subtotal * 1.04) },
      emailSent: status === 'confirmed' || status === 'completed',
      emailSentAt: status === 'confirmed' || status === 'completed' ? addDays(t, offset - 1).toISOString() : null,
      notes: '',
    };
  };

  return [
    make(-3, '11:00 AM', 'lux',    'spa',    'completed', { name:'Marisa Velasquez', email:'marisa.v@example.com', phone:'(310) 555-0142', addr:'9100 Wilshire Blvd', city:'Beverly Hills', zip:'90212' }),
    make(-1, '2:00 PM',  'sedan',  'both',   'completed', { name:'Daniel Kim',       email:'dkim@example.com',     phone:'(424) 555-0188', addr:'500 Ocean Ave',      city:'Santa Monica',  zip:'90402' }),
    make(0,  '9:30 AM',  'suv',    'detail', 'confirmed', { name:'Sofia Ramos',      email:'sofia.r@example.com',  phone:'(310) 555-0177', addr:'250 Newport Center Dr', city:'Newport Beach', zip:'92660' }),
    make(0,  '2:00 PM',  'lux',    'wax',    'pending',   { name:'James Lambert',    email:'jlambert@example.com', phone:'(310) 555-0103', addr:'27900 Pacific Coast Hwy', city:'Malibu', zip:'90265' }),
    make(1,  '8:00 AM',  'pickup', 'ext',    'pending',   { name:'Carla Mendoza',    email:'cmendoza@example.com', phone:'(323) 555-0150', addr:'1100 Sunset Plaza Dr', city:'West Hollywood', zip:'90069' }),
    make(1,  '12:30 PM', 'sedan',  'both',   'confirmed', { name:'Ethan Park',       email:'epark@example.com',    phone:'(310) 555-0166', addr:'620 Manhattan Ave', city:'Manhattan Beach', zip:'90266' }),
    make(2,  '11:00 AM', 'van',    'intd',   'pending',   { name:'Priya Shah',       email:'pshah@example.com',    phone:'(310) 555-0124', addr:'1800 Avenue of the Stars', city:'Los Angeles', zip:'90067' }),
    make(3,  '9:30 AM',  'suv',    'detail', 'confirmed', { name:'Aaron Reyes',      email:'areyes@example.com',   phone:'(424) 555-0192', addr:'200 Pier Ave', city:'Hermosa Beach', zip:'90254' }),
    make(4,  '3:30 PM',  'comm',   'ext',    'pending',   { name:'Logistics Co.',    email:'ops@logisticsco.example.com', phone:'(310) 555-0145', addr:'5000 W Century Blvd', city:'Los Angeles', zip:'90045' }),
    make(7,  '11:00 AM', 'lux',    'spa',    'pending',   { name:'Maya Brennan',     email:'mb@example.com',       phone:'(310) 555-0118', addr:'1500 Stone Canyon Rd', city:'Bel Air', zip:'90077' }),
  ];
};

/* --- Storage primitives ---------------------------------- */
const readJSON = (key, fallback) => {
  try { const v = localStorage.getItem(key); return v ? JSON.parse(v) : fallback; }
  catch { return fallback; }
};
const writeJSON = (key, value) => {
  try { localStorage.setItem(key, JSON.stringify(value)); } catch {}
};

/* --- Public store API ------------------------------------ */
const Store = {
  STATUS, STATUS_LABEL, SLOT_OPTIONS,

  ensureSeed(){
    const cur = readJSON(STORE_KEYS.requests, null);
    if (!cur || !Array.isArray(cur)) writeJSON(STORE_KEYS.requests, buildSeed());
  },
  resetSeed(){ writeJSON(STORE_KEYS.requests, buildSeed()); },

  getRequests(){
    Store.ensureSeed();
    return readJSON(STORE_KEYS.requests, []);
  },
  setRequests(list){
    writeJSON(STORE_KEYS.requests, list);
    window.dispatchEvent(new CustomEvent('prestige:requests-changed'));
  },
  upsert(req){
    const list = Store.getRequests();
    const idx = list.findIndex(r => r.id === req.id);
    if (idx >= 0) list[idx] = req; else list.unshift(req);
    Store.setRequests(list);
  },
  updateStatus(id, status, extra={}){
    const list = Store.getRequests();
    const idx = list.findIndex(r => r.id === id);
    if (idx < 0) return null;
    list[idx] = { ...list[idx], status, ...extra };
    Store.setRequests(list);
    return list[idx];
  },

  /* Slot blocking — takes a Date or YYYY-MM-DD, returns set of taken slot strings */
  takenSlotsForDate(date){
    const key = (typeof date === 'string') ? date : ymd(date);
    const blockingStatuses = new Set([STATUS.PENDING, STATUS.CONFIRMED, STATUS.COMPLETED]);
    const reqs = Store.getRequests();
    return new Set(
      reqs
        .filter(r => r.date === key && r.paid && blockingStatuses.has(r.status))
        .map(r => r.slot)
    );
  },

  /* Auth — mock username/password, session in localStorage */
  login(username, password){
    const u = (username || '').trim().toLowerCase();
    const p = (password || '').trim();
    if (u !== ADMIN_USER.username.toLowerCase() || p !== ADMIN_USER.password) {
      return { ok: false, error: 'Invalid username or password' };
    }
    const session = {
      user: username,
      issuedAt: Date.now(),
      expiresAt: Date.now() + SESSION_TTL_HOURS * 60 * 60 * 1000,
    };
    writeJSON(STORE_KEYS.session, session);
    return { ok: true, session };
  },
  logout(){ try { localStorage.removeItem(STORE_KEYS.session); } catch {} },
  getSession(){
    const s = readJSON(STORE_KEYS.session, null);
    if (!s || s.expiresAt < Date.now()) return null;
    return s;
  },

  /* Email mock — replace with EmailJS/backend call later */
  sendConfirmationEmail(req){
    return new Promise((resolve) => {
      setTimeout(() => {
        Store.updateStatus(req.id, STATUS.CONFIRMED, {
          emailSent: true,
          emailSentAt: new Date().toISOString(),
        });
        resolve({ ok: true, to: req.customer.email });
      }, 700);
    });
  },

  buildEmailPreview(req){
    const dStr = fmtDateLong(req.date);
    const total = req.pricing?.total ? `$${req.pricing.total.toFixed(2)}` : '—';
    return {
      to: req.customer.email,
      subject: `Your Prestige Auto Spa booking is confirmed — ${dStr} · ${req.slot}`,
      body: [
        `Hi ${req.customer.name.split(' ')[0]},`,
        ``,
        `Your booking with Prestige Auto Spa Mobile is confirmed.`,
        ``,
        `Service: ${req.service.label}`,
        `Vehicle: ${req.vehicle.label}`,
        `Date:    ${dStr}`,
        `Time:    ${req.slot}`,
        `Where:   ${req.address.line}, ${req.address.city} ${req.address.zip}`,
        `Total:   ${total}`,
        ``,
        `Our technician will arrive on time and ready. If anything changes, reply to this email or call (310) 555-0110.`,
        ``,
        `— Prestige Auto Spa Mobile`,
      ].join('\n'),
    };
  },
};

/* --- Date utils exposed for components ------------------- */
const DateUtils = { ymd, fromYmd, today, addDays, fmtDate, fmtDateLong };

window.PrestigeStore = Store;
window.PrestigeDate  = DateUtils;
