// Daily Report — shared UI components (React, no JSX build; via Babel).
// Exports to window at the end for cross-file use.
const { useState } = React;

const fmt = (n) => n == null || n === '' ? '—' : Number(n).toLocaleString('en-US') + '.-';
const fmtPlain = (n) => Number(n).toLocaleString('en-US');

/* ---------------- Top bar ---------------- */
function TopBar({ user, locked, onLock, onPrint, onExit }) {
  return (
    <div className="topbar">
      <div className="tb-left">
        <div className="logo-tile">H</div>
        <span className="tb-title">Daily Report — ห้าธารา</span>
      </div>
      <div className="tb-right">
        <div className="user-pill">
          <span className="dot">{user.name.slice(0, 1)}</span>
          {user.name}
        </div>
        {!locked && <button className="tb-icon green" onClick={onLock} title="ล็อกรอบ">LOCK</button>}
        {locked && <button className="tb-icon print" onClick={onPrint} title="พิมพ์ A5">PRINT</button>}
        <button className="tb-icon red" onClick={onExit} title="ออกจากระบบ">LOGOUT</button>
      </div>
    </div>
  );
}

/* ---------------- Left panel capsules ---------------- */
function DateTimeCap({ date, start, end, onTime }) {
  return (
    <div className="dt-cap glass">
      <div className="dt-row">
        <span className="dt-date z">{date}</span>
      </div>
      <div className="dt-times">
        <div className="dt-time-fld"><label>เริ่ม</label>
          <input value={start} onChange={(e) => onTime('start', e.target.value)} /></div>
        <div className="dt-time-fld"><label>จบ</label>
          <input value={end} onChange={(e) => onTime('end', e.target.value)} /></div>
      </div>
    </div>
  );
}

/* horizontal date bar — sits in the top action row; day can be navigated here or on the dashboard */
function DateTimeBar({ date, onPrev, onNext, onToday, onSelectDate, onPrevMonth, onNextMonth }) {
  // With calendar props: a SINGLE clickable date pill that opens the
  // MiniCalendar — no separate prev/next-day or TODAY buttons. The pill
  // shows dd/mm/yyyy with an English month name in the popover (enLabels)
  // and the popover's TODAY is also suppressed (hideToday). Without the
  // calendar props it falls back to a plain read-only date (unchanged
  // callers, e.g. Expense page).
  const clickableDate = typeof onSelectDate === 'function';
  return (
    <div className={'dt-bar glass' + (clickableDate ? ' dt-bar-cal' : '')}>
      <div className="dt-row">
        {clickableDate
          ? <MiniCalendar date={date} onSelect={onSelectDate} onPrevMonth={onPrevMonth} onNextMonth={onNextMonth} onToday={onToday} enLabels hideToday />
          : <span className="dt-date z">{date}</span>}
      </div>
    </div>
  );
}

function RoomStatus({ broken, free, sold }) {
  return (
    <div className="seg-wrap glass">
      <div className="seg"><span className="n z">{broken}</span><span className="l z">เสีย</span></div>
      <div className="seg"><span className="n z">{free}</span><span className="l z">ฟรี</span></div>
      <div className="seg"><span className="n z">{sold}</span><span className="l z">ขาย</span></div>
    </div>
  );
}

function Capsule({ label, value, variant }) {
  const cls = variant === 'amber' ? 'cap filled-amber'
    : variant === 'green' ? 'cap filled-green'
    : variant === 'red' ? 'cap filled-red'
    : variant === 'yellow' ? 'cap filled-yellow' : 'cap glass';
  return (
    <div className={cls}>
      <span className={'cap-lbl z' + (variant ? '' : ' muted')}>{label}</span>
      <span className="cap-amt z">{value}</span>
    </div>
  );
}

function SummaryCards({ inv, noinv }) {
  const Line = ({ k, v }) => (
    <div style={{display:'flex',justifyContent:'space-between',fontSize:9,padding:'1px 0'}}>
      <span style={{color:'#8a8680'}}>{k}</span>
      <span style={{fontWeight:600,color:'#8a8680'}}>{v}</span>
    </div>
  );
  const colStyle = {background:'#d6d4cf',boxShadow:'inset 1px 1px 3px rgba(20,18,14,.12),inset -1px -1px 2px rgba(255,255,255,.55)',borderRadius:8,padding:'4px 7px'};
  const headStyle = {fontSize:8,fontWeight:700,letterSpacing:'.05em',textTransform:'uppercase',color:'#185FA5',display:'block',paddingBottom:2,marginBottom:1,borderBottom:'1px solid rgba(24,95,165,.15)'};
  return (
    <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:6,padding:'6px 8px 2px'}}>
      <div style={colStyle}>
        <span style={headStyle}>Invoice</span>
        <Line k="CASH" v={fmt(inv.cash)} /><Line k="QR" v={fmt(inv.qr)} />
        <Line k="EDC" v={fmt(inv.edc)} /><Line k="KEY-IN" v={fmt(inv.keyin)} />
      </div>
      <div style={colStyle}>
        <span style={headStyle}>No Invoice</span>
        <Line k="CASH" v={fmt(noinv.cash)} /><Line k="QR" v={fmt(noinv.qr)} />
        <Line k="BBL" v={fmt(noinv.bbl)} /><Line k="AGP" v={fmt(noinv.agp)} />
      </div>
    </div>
  );
}

function MiniCalendar({ date, dataDates = [], onSelect, onPrevMonth, onNextMonth, onToday, enLabels = false, hideToday = false }) {
  const [expanded, setExpanded] = useS(false);
  const [day, month, year] = String(date).split('/').map(Number);
  const selected = new Date(year, month - 1, day);
  const today = new Date();
  const first = new Date(year, month - 1, 1);
  const daysInMonth = new Date(year, month, 0).getDate();
  const lead = first.getDay();
  const cells = [...Array(lead).fill(null), ...Array.from({ length: daysInMonth }, (_, i) => i + 1)];
  // enLabels: month header in English + Gregorian year (e.g. "July 2026"),
  // collapsed field in dd/mm/yyyy. Otherwise keep the Thai/Buddhist labels.
  const monthLabel = enLabels
    ? selected.toLocaleDateString('en-GB', { month: 'long', year: 'numeric' })
    : selected.toLocaleDateString('th-TH', { month: 'long', year: 'numeric' });
  const isToday = day === today.getDate() && month === today.getMonth() + 1 && year === today.getFullYear();
  const dateLabel = enLabels
    ? `${String(day).padStart(2, '0')}/${String(month).padStart(2, '0')}/${year}`
    : selected.toLocaleDateString('th-TH', { day: 'numeric', month: 'short', year: 'numeric' });
  return (
    <div className="mini-cal-anchor">
      <div className="mini-cal mini-cal-collapsed" onClick={() => setExpanded(true)}>
        <div className={'mini-cal-collapsed-field' + (isToday ? ' is-today' : ' is-other')}>{dateLabel}</div>
      </div>
      {expanded && (
        <React.Fragment>
          <div className="mini-cal-scrim" onClick={() => setExpanded(false)} />
          <div className="mini-cal mini-cal-popover">
            <div className="mini-cal-head">
              <div className="mini-cal-title">{monthLabel}</div>
              <div className="mini-cal-actions">
                <button onClick={onPrevMonth}>‹</button><button onClick={onNextMonth}>›</button>
                {!hideToday && <button className="mini-cal-today" onClick={onToday}>TODAY</button>}
                <button className="mini-cal-collapse-btn" onClick={() => setExpanded(false)} title="ย่อปฏิทิน">▴</button>
              </div>
            </div>
            <div className="mini-cal-week">{['S','M','T','W','T','F','S'].map((d, i) => <span key={i}>{d}</span>)}</div>
            <div className="mini-cal-grid">
              {cells.map((d, i) => d == null
                ? <span key={'e' + i}></span>
                : <button key={d} className={(d === day ? 'selected ' : '') + (d === today.getDate() && month === today.getMonth() + 1 && year === today.getFullYear() ? 'today ' : '')} onClick={() => { onSelect(new Date(year, month - 1, d)); setExpanded(false); }}>{d}</button>)}
            </div>
          </div>
        </React.Fragment>
      )}
    </div>
  );
}

function DateSelectorBar({ date, onPrevDay, onNextDay, onToggleCalendar, onSelectDate }) {
  const todayRaw = new Date();
  const today = new Date(todayRaw.getFullYear(), todayRaw.getMonth(), todayRaw.getDate());
  const days = Array.from({ length: 7 }, (_, i) => {
    const d = new Date(today);
    d.setDate(today.getDate() - 6 + i);
    const dateText = `${String(d.getDate()).padStart(2, '0')}/${String(d.getMonth() + 1).padStart(2, '0')}/${d.getFullYear()}`;
    const isSelected = dateText === date;
    const isToday = d.getTime() === today.getTime();
    return { date: d, dateText, day: d.getDate(), isSelected, isToday };
  });
  return (
    <div className="dash-date-selector">
      <div className="dash-date-strip" aria-label="เลือกวันที่">
        {days.map((d) => (
          <button
            key={d.dateText}
            className={'dash-date-pill z' + (d.isSelected ? ' selected' : '') + (d.isToday ? ' today' : '')}
            onClick={() => onSelectDate(d.date)}
            title={d.dateText}
          >
            {d.day}
          </button>
        ))}
      </div>
      <button className="dash-date-calendar" onClick={onToggleCalendar} title="เปิดปฏิทิน"></button>
    </div>
  );
}

function RoomGrid({ roomsByFloor, sold, broken }) {
  const soldSet = new Set(sold.map(String));
  const brokenSet = new Set(broken.map(String));
  const allRooms = Object.values(roomsByFloor).flat();
  return (
    <div className="room-grid glass">
      <div className="room-cells-flat">
        {allRooms.map((r) => {
          const st = brokenSet.has(String(r)) ? 'broken' : soldSet.has(String(r)) ? 'sold' : 'free';
          return <div key={r} className={'room-cell ' + st}>{r}</div>;
        })}
      </div>
      <div className="room-legend">
        <span className="rl sold">Sold</span>
        <span className="rl free">Free</span>
        <span className="rl broken">Repair</span>
      </div>
    </div>
  );
}

/* ---------------- Dashboard: transaction card (left panel, 3/row) ---------------- */
/* colour CONDITION kept from the transactions tables:
   paid → green accent, ค้างชำระ (due>0) → amber accent + tint;
   invoice = solid navy tag, no-invoice = navy-outline tag. */
function TxCard({ row }) {
  const due = row.paymentStatus === 'pending_payment';
  const partial = row.paymentStatus === 'partial_deposit';
  const isInv = row._kind === 'inv';
  return (
    <div className={'tx-card' + (due ? ' due' : partial ? ' partial' : ' paid')}>
      <div className="tx-top">
        <span className="tx-room z">{row.room || '—'}</span>
        <span className={'tx-tag ' + (isInv ? 'inv' : 'noinv')}>{isInv ? 'INVOICE' : 'NO INV'}</span>
      </div>
      <div className="tx-guest">{row.guest || '—'}</div>
      <div className="tx-meta">{[row.source, row.channel, row.time].filter(Boolean).join(' · ')}</div>
      <div className="tx-foot">
        <span className="tx-amt z">{fmt(row.recv)}</span>
        <span className={'badge ' + (due ? 'due' : partial ? 'partial' : 'paid')}>{due ? 'PENDING PAYMENT' : partial ? 'PARTIAL / DEPOSIT' : 'RECEIVED'}</span>
      </div>
    </div>
  );
}

/* ---------------- Dashboard: room board card (left panel, 3/row) ---------------- */
/* status: 'sold' (has a transaction) | 'free' (clickable → add) | 'repair'.
   condition colour kept from the transactions tables:
   paid → green accent, ค้างชำระ → amber accent + tint. */
function RoomCard({ room, tx, status, stayProgress, conditionDuringStay, onClick, onClose, onSettle }) {
  const dashboardName = (value) => String(value || '').trim().split(/\s+/)[0] || '—';
  // เสีย (broken) — reason centered, no tag. Flat solid-colour card, no inner frame.
  if (status === 'broken') {
    return (
      <div className="tx-card-wrap">
        <div className="tx-card broken clickable" onClick={onClick}>
          <span className="tx-room z">{room}</span>
          <div className="tx-free-center">
            <div className="tx-free-label">{conditionDuringStay ? 'เสียระหว่างเข้าพัก' : 'เสีย'}</div>
            {tx && tx.reason && <div className="tx-free-detail">{tx.reason}</div>}
          </div>
          {stayProgress && <div className="tx-foot"><span className="tx-night">{stayProgress}</span></div>}
        </div>
      </div>
    );
  }
  // ฟรี / complimentary
  if (status === 'free') {
    const detail = String((tx && tx.note) || '').trim();
    return (
      <div className="tx-card-wrap">
        <div className="tx-card comp clickable" onClick={onClick}>
          <span className="tx-room z">{room}</span>
          <div className="tx-comp-center">
            <div className="tx-free-label">ฟรี</div>
            {detail && <div className="tx-free-detail">{detail}</div>}
          </div>
          {stayProgress && <div className="tx-foot"><span className="tx-night">{stayProgress}</span></div>}
        </div>
      </div>
    );
  }
  // available (empty) — click to add, wrench to set เสีย/ฟรี
  if (status === 'available' || !tx) {
    return (
      <div className="tx-card-wrap">
        <div className="tx-card avail" onClick={onClick}>
          <div className="tx-room z free-room">{room}</div>
        </div>
      </div>
    );
  }
  const due = tx.paymentStatus === 'pending_payment';
  const partial = tx.paymentStatus === 'partial_deposit';
  const privateOta = !!(tx.privateOta || tx.paymentStatus === 'private_ota');
  const isInv = tx._kind === 'inv';
  // Amount shown bottom-right: Paid card -> total received; Outstanding card -> outstanding amount.
  // Number only -- no รับ/ค้าง word, no currency symbol, no invoice number.
  const amountValue = due || partial ? tx.pendingAmount : tx.recv;
  const statusKey = due ? 'due' : partial ? 'partial' : 'paid';
  return (
    <div className="tx-card-wrap">
      <div className={'tx-card status-bar-card' + (onClick ? ' clickable' : '')} onClick={onClick}>
        <span className="tx-room z">{room}</span>
        {tx.paymentGroupCode && <span className={'pg-badge ' + (tx.paymentGroupIsPrimary ? 'pg-primary' : 'pg-member')}>{tx.paymentGroupCode}</span>}
        {isInv && <span className={'tx-tag inv-status ' + (String(tx.id || '').trim() ? 'inv-number' : 'waiting-inv')}>INV</span>}
        {privateOta ? (
          <React.Fragment>
            <div className="tx-guest">{tx._privateHidden ? 'ขายแล้ว' : (tx.guest ? dashboardName(tx.guest) : (tx.source || 'Private OTA'))}</div>
            {stayProgress && <div className={'tx-foot status-bar ' + statusKey}><span className="tx-night paid-night">{stayProgress}</span></div>}
          </React.Fragment>
        ) : (
          <React.Fragment>
            <div className="tx-guest">{dashboardName(tx.guest)}</div>
            <div className={'tx-foot status-bar ' + statusKey}>
              <span className="tx-night">{stayProgress}</span>
              {!tx._pgMember && <span className="tx-due mono">{fmtPlain(amountValue)}</span>}
            </div>
          </React.Fragment>
        )}
      </div>
    </div>
  );
}

/* open shift → close shift */
function ShiftCard({ start, end, onTime, locked }) {
  const inputStyle = {
    height: 46, fontSize: 20, fontWeight: 900, textAlign: 'center',
    background: '#cac9c4', color: '#2a2825', border: 0, borderRadius: 10,
    boxShadow: 'inset 1px 1px 3px rgba(20,18,14,.15),inset -1px -1px 2px rgba(255,255,255,.40)',
    width: '100%', padding: 0, margin: 0, boxSizing: 'border-box',
    letterSpacing: '.02em', display: 'block',
  };
  const emptyStyle = { ...inputStyle, color: '#b0aea8', fontWeight: 700 };
  return (
    <div className="rp-card" style={{padding: 10}}>
      <div style={{display:'grid',gridTemplateColumns:'1fr 1fr',gap:8}}>
        <div style={{display:'flex',flexDirection:'column',gap:6}}>
          <span style={{fontSize:10,fontWeight:800,color:'#8a8680',letterSpacing:'.03em',textAlign:'center'}}>เปิดรอบ</span>
          <input style={inputStyle} value={start} disabled={locked} onChange={(e) => onTime('start', e.target.value)} />
        </div>
        <div style={{display:'flex',flexDirection:'column',gap:6}}>
          <span style={{fontSize:10,fontWeight:800,color:'#8a8680',letterSpacing:'.03em',textAlign:'center'}}>ปิดรอบ</span>
          <input style={end ? inputStyle : emptyStyle} value={end} placeholder="––:––" disabled={locked} onChange={(e) => onTime('end', e.target.value)} />
        </div>
      </div>
    </div>
  );
}

/* room status — three equal cards: ฟรี | เสีย | ขายแล้ว */
function RoomSummary({ sold, free, broken }) {
  const wrap = {display:'grid',gridTemplateColumns:'1fr 1fr 1.2fr',gap:7,padding:8,background:'#e2e1dc',borderRadius:14,boxShadow:'3px 5px 10px rgba(20,18,14,.10),-2px -2px 5px rgba(255,255,255,.65)'};
  const cell = {background:'#d6d4cf',boxShadow:'inset 1px 1px 3px rgba(20,18,14,.12),inset -1px -1px 2px rgba(255,255,255,.55)',borderRadius:12,padding:'10px 4px',display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',gap:4};
  const num = {fontSize:30,fontWeight:900,lineHeight:1};
  const lbl = {fontSize:10,fontWeight:800,color:'#8a8680'};
  const soldWrap = {...cell,background:'#18B76A',boxShadow:'2px 4px 8px rgba(24,183,106,.22)'};
  const soldNum = {...num,color:'#fff'};
  const soldLbl = {...lbl,color:'rgba(255,255,255,.88)'};
  return (
    <div style={wrap}>
      <div style={cell}><span style={{...num,color:'#c0392b'}}>{broken}</span><span style={lbl}>เสีย</span></div>
      <div style={cell}><span style={{...num,color:'#18B76A'}}>{free}</span><span style={lbl}>ฟรี</span></div>
      <div style={soldWrap}><span style={soldNum}>{sold}</span><span style={soldLbl}>ขายแล้ว</span></div>
    </div>
  );
}

/* expense detail list with red total below the card */
function ExpenseBreakdown({ rows, total, onAdd, locked, onEditRow }) {
  return (
    <div style={{background:'#e2e1dc',borderRadius:14,boxShadow:'3px 5px 10px rgba(20,18,14,.10),-2px -2px 5px rgba(255,255,255,.65)',overflow:'hidden',display:'flex',flexDirection:'column'}}>
      <div style={{padding:'9px 11px 6px',display:'flex',alignItems:'center',gap:7}}>
        <span style={{width:7,height:7,borderRadius:'50%',background:'#d63a30',flexShrink:0}}></span>
        <span style={{fontSize:14,fontWeight:800,color:'#3d3935',flex:1}}>รายจ่าย</span>
        <span style={{fontSize:9,color:'#9a9690',fontWeight:700,marginRight:6}}>{rows.length} รายการ</span>
        {onAdd && <button onClick={onAdd} disabled={locked} style={{height:24,padding:'0 10px',border:0,borderRadius:7,background:'#d63a30',color:'#fff',fontSize:9,fontWeight:800,cursor:locked?'not-allowed':'pointer',opacity:locked?.5:1,flexShrink:0}}>+ เพิ่ม</button>}
      </div>
      <div style={{background:'#d6d4cf',boxShadow:'inset 1px 1px 3px rgba(20,18,14,.12),inset -1px -1px 2px rgba(255,255,255,.50)',borderRadius:8,margin:'6px 8px',maxHeight:124,padding:'8px 5px 6px',overflowY: rows.length > 3 ? 'auto' : 'hidden',display:'flex',flexDirection:'column',gap:4}}>
        {rows.map((r, i) => (
          <div className="exp-row" key={i} onClick={onEditRow ? () => onEditRow(r, i) : undefined} style={onEditRow ? {cursor:'pointer'} : undefined}>
            <span className="exp-cat" style={{fontSize:9,color:'#8a8680',fontWeight:600}}>{r.cat}</span>
            <span className="exp-detail" style={{fontSize:8,color:'#a8a4a0'}}>{r.detail}</span>
            <span className="exp-amt mono" style={{fontSize:9,fontWeight:600,color:'#8a8680'}}>{fmt(r.amount)}</span>
          </div>
        ))}
        {Array.from({ length: Math.max(0, 3 - rows.length) }).map((_, i) => (
          <div className="exp-row exp-placeholder" key={'exp-placeholder-' + i} aria-hidden="true"></div>
        ))}
      </div>
      <div style={{background:'#d63a30',borderRadius:8,margin:'6px 9px 9px',padding:'7px 10px',display:'flex',justifyContent:'space-between',alignItems:'center'}}>
        <span style={{fontSize:13,fontWeight:700,color:'#fff'}}>รวมรายจ่าย</span>
        <span style={{fontSize:15,fontWeight:700,color:'#fff'}} className="z">{fmt(total)}</span>
      </div>
    </div>
  );
}

Object.assign(window, { fmt, fmtPlain, TopBar, DateTimeCap, DateTimeBar, MiniCalendar, DateSelectorBar, RoomStatus, RoomGrid, Capsule, SummaryCards, TxCard, RoomCard, ShiftCard, RoomSummary, ExpenseBreakdown });
