/**
 * 월 매출 (Monthly Sales) — 완전 재기획
 *
 *  3 탭:
 *   1. 개요         — KPI + 일별 차트 + 채널 + TOP 업체 + 자동 인사이트
 *   2. 매출 달력    — 8컬럼 (일~토+주간종합), 각 셀에 메뉴별 [name·count·amount] 정렬
 *   3. 업체 통계    — 와이드 테이블 (메뉴별 설정단가 / 개수 / 금액)
 */

// ─── 아이콘 ───
function Icon({ name, size=14, color='currentColor', strokeWidth=2 }) {
  const paths = {
    chart:     <><line x1="12" y1="20" x2="12" y2="10"/><line x1="18" y1="20" x2="18" y2="4"/><line x1="6" y1="20" x2="6" y2="16"/></>,
    calendar:  <><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></>,
    building:  <><rect x="4" y="2" width="16" height="20" rx="1"/><line x1="9" y1="6" x2="9" y2="6"/><line x1="15" y1="6" x2="15" y2="6"/><line x1="9" y1="10" x2="9" y2="10"/><line x1="15" y1="10" x2="15" y2="10"/><line x1="9" y1="14" x2="9" y2="14"/><line x1="15" y1="14" x2="15" y2="14"/><path d="M10 22v-4h4v4"/></>,
    download:  <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></>,
    file:      <><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></>,
    card:      <><rect x="2" y="5" width="20" height="14" rx="2"/><line x1="2" y1="10" x2="22" y2="10"/></>,
    bank:      <><line x1="3" y1="22" x2="21" y2="22"/><line x1="6" y1="18" x2="6" y2="11"/><line x1="10" y1="18" x2="10" y2="11"/><line x1="14" y1="18" x2="14" y2="11"/><line x1="18" y1="18" x2="18" y2="11"/><polygon points="12 2 20 7 4 7"/></>,
    clipboard: <><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><rect x="8" y="2" width="8" height="4" rx="1"/></>,
    cash:      <><rect x="2" y="6" width="20" height="12" rx="2"/><circle cx="12" cy="12" r="2"/><line x1="6" y1="12" x2="6" y2="12"/><line x1="18" y1="12" x2="18" y2="12"/></>,
    alert:     <><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></>,
    won:       <><path d="M4 6l3 12 3-9 2 9 3-12"/><path d="M3 11h12"/><path d="M3 14h12"/></>,
    bowl:      <><path d="M3 11h18"/><path d="M3 11a9 9 0 0 0 18 0"/><path d="M12 4v3"/><path d="M9 7h6"/></>,
    search:    <><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></>,
    trendUp:   <><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"/><polyline points="17 6 23 6 23 12"/></>,
  }[name];
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round" style={{ flexShrink:0 }}>
      {paths}
    </svg>
  );
}

// ─── 데이터 ───
const MENUS = [
  { name: '일반',   bg: '#e2e8f0', fg: '#334155' },
  { name: '정찬',   bg: '#dcfce7', fg: '#15803d' },
  { name: '곤드레', bg: '#fef3c7', fg: '#92400e' },
  { name: '베지',   bg: '#dbeafe', fg: '#1d4ed8' },
  { name: '특식',   bg: '#fee2e2', fg: '#b91c1c' },
];
const MENU_NAMES = MENUS.map(m => m.name);
const MENU_BY_NAME = Object.fromEntries(MENUS.map(m => [m.name, m]));

// 5월 영업일별 메뉴 배포 (count) — 평일 ~150~200식 / 주말 휴무
// 1일=목요일
function buildCalendar() {
  const baseByDay = {
    1:[60,40,18,8,12], 2:[68,45,22,6,10], 3:[55,38,15,5,9],
    6:[88,62,30,12,18], 7:[95,70,32,14,22], 8:[92,66,28,12,20],
    9:[80,58,26,10,16], 10:[100,72,32,15,25],
    13:[110,80,38,16,28], 14:[118,86,40,18,30], 15:[122,90,42,20,32],
    16:[115,84,38,16,28], 17:[128,94,46,22,36],
  };
  const prices = { 일반:7000, 정찬:8500, 곤드레:9000, 베지:8000, 특식:11000 };
  return Object.fromEntries(Object.entries(baseByDay).map(([d, counts])=>{
    const items = MENU_NAMES.map((n,i)=>({
      name:n, count: counts[i], amount: counts[i]*prices[n],
      color: MENU_BY_NAME[n].bg, text_color: MENU_BY_NAME[n].fg,
    })).filter(x => x.count > 0);
    return [parseInt(d), {
      items,
      totalCount: items.reduce((s,i)=>s+i.count,0),
      totalAmount: items.reduce((s,i)=>s+i.amount,0),
    }];
  }));
}
const CALENDAR = buildCalendar();

// 업체 통계 데이터
const COMPANIES = [
  { group:'1-1',  name:'대치 A학원',    isMember:true,  custom:{일반:6800,정찬:8200},
    counts:{일반:412,정찬:280,곤드레:115,베지:48,특식:92}, days:18 },
  { group:'1-2',  name:'B엔지니어링',   isMember:true,  custom:{일반:7200},
    counts:{일반:380,정찬:210,곤드레:88,베지:65,특식:80}, days:20 },
  { group:'2-1',  name:'D콜센터',       isMember:false, custom:{},
    counts:{일반:312,정찬:160,곤드레:62,베지:25,특식:48}, days:21 },
  { group:'2-2',  name:'E요양원',       isMember:false, custom:{정찬:8800,베지:7800},
    counts:{일반:180,정찬:240,곤드레:42,베지:80,특식:30}, days:22 },
  { group:'3-1',  name:'C어린이집',     isMember:false, custom:{},
    counts:{일반:140,정찬:95,곤드레:0,베지:35,특식:25}, days:18 },
  { group:'3-2',  name:'G스타트업',     isMember:true,  custom:{},
    counts:{일반:142,정찬:88,곤드레:35,베지:18,특식:42}, days:15 },
  { group:'4-1',  name:'H건설',         isMember:false, custom:{일반:6500},
    counts:{일반:280,정찬:120,곤드레:55,베지:18,특식:38}, days:19 },
  { group:'4-2',  name:'I로지스틱스',   isMember:false, custom:{},
    counts:{일반:165,정찬:88,곤드레:40,베지:12,특식:25}, days:17 },
  { group:'5-1',  name:'J병원 영양과',  isMember:false, custom:{정찬:8200,베지:7600},
    counts:{일반:90,정찬:180,곤드레:32,베지:60,특식:18}, days:21 },
  { group:'5-2',  name:'K연구소',       isMember:true,  custom:{},
    counts:{일반:92,정찬:62,곤드레:25,베지:14,특식:30}, days:14 },
  { group:'-',    name:'L카페',         isMember:false, custom:{},
    counts:{일반:48,정찬:35,곤드레:0,베지:0,특식:18}, days:11 },
  { group:'-',    name:'M사옥',         isMember:false, custom:{},
    counts:{일반:62,정찬:40,곤드레:18,베지:8,특식:22}, days:13 },
  { group:'6-1',  name:'F중학교',       isMember:false, custom:{},
    counts:{일반:0,정찬:0,곤드레:0,베지:0,특식:0}, days:0 },
];
const DEFAULT_PRICES = { 일반:7000, 정찬:8500, 곤드레:9000, 베지:8000, 특식:11000 };
const getCustomPrice = (c, m) => c.custom[m] ?? DEFAULT_PRICES[m];
const getCompanyAmount = (c, m) => (c.counts[m] || 0) * getCustomPrice(c, m);
const getCompanyTotalCount  = c => MENU_NAMES.reduce((s,m)=>s+(c.counts[m]||0), 0);
const getCompanyTotalAmount = c => MENU_NAMES.reduce((s,m)=>s+getCompanyAmount(c,m), 0);

// ─── 메인 ───
function SalesPage({ tweaks={} }) {
  const compareWith = tweaks.compareWith || 'prev_month';
  const [tab, setTab] = React.useState('overview');

  // 누적 데이터 (개요용)
  const totalAmount = Object.values(CALENDAR).reduce((s,d)=>s+d.totalAmount, 0);
  const totalCount  = Object.values(CALENDAR).reduce((s,d)=>s+d.totalCount, 0);
  const prevTotal   = Math.round(totalAmount * 0.92);
  const delta       = ((totalAmount - prevTotal) / prevTotal * 100);

  const TABS = [
    { k:'overview', label:'개요',     icon:'chart' },
    { k:'calendar', label:'매출 달력', icon:'calendar' },
    { k:'company',  label:'업체 통계', icon:'building' },
  ];

  return (
    <div style={{ display:'flex', flexDirection:'column', height:'100%', background:'#f8fafc', overflow:'auto' }}>
      {/* 헤더 */}
      <div style={{ flexShrink:0, padding:'16px 22px 0', background:'#fff', borderBottom:'1px solid #e2e8f0' }}>
        <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between' }}>
          <div style={{ display:'flex', alignItems:'center', gap:12 }}>
            <button style={{ width:30, height:30, border:'1px solid #e2e8f0', background:'#fff', borderRadius:5, fontSize:14, cursor:'pointer' }}>‹</button>
            <div>
              <div style={{ fontSize:11, color:'#64748b', fontWeight:600 }}>월 매출</div>
              <div style={{ fontSize:22, fontWeight:800, color:'#0f172a', letterSpacing:'-0.5px' }}>2025년 5월 <span style={{ fontSize:13, color:'#94a3b8', fontWeight:600, marginLeft:6 }}>1일 ~ 17일 기준</span></div>
            </div>
            <button style={{ width:30, height:30, border:'1px solid #e2e8f0', background:'#fff', borderRadius:5, fontSize:14, cursor:'pointer' }}>›</button>
          </div>
          <div style={{ display:'flex', gap:8, alignItems:'center' }}>
            <label style={{ display:'flex', alignItems:'center', gap:6, fontSize:11, fontWeight:600, color:'#64748b', padding:'6px 10px', border:'1px solid #e2e8f0', borderRadius:5, background:'#fff', cursor:'pointer' }}>
              <input type="checkbox" style={{ accentColor:'#16a34a' }}/> 메뉴 그룹으로 보기
            </label>
            <button style={btnSec}><Icon name="file" size={13}/> PDF 리포트</button>
            <button style={btnSec}><Icon name="download" size={13}/> CSV 다운로드</button>
          </div>
        </div>

        {/* 서브탭 */}
        <div style={{ display:'flex', gap:0, marginTop:14 }}>
          {TABS.map(t => {
            const on = tab === t.k;
            return (
              <button key={t.k} onClick={()=>setTab(t.k)} style={{
                padding:'10px 16px', fontSize:13, fontWeight:on?800:600,
                color: on ? '#16a34a' : '#64748b',
                background:'transparent', border:'none',
                borderBottom: on ? '2px solid #16a34a' : '2px solid transparent',
                marginBottom:-1, cursor:'pointer',
                display:'flex', alignItems:'center', gap:6,
              }}>
                <Icon name={t.icon} size={14} color={on ? '#16a34a' : '#94a3b8'}/>{t.label}
              </button>
            );
          })}
        </div>
      </div>

      {tab === 'overview' && <OverviewTab totalAmount={totalAmount} prevTotal={prevTotal} delta={delta} totalCount={totalCount}/>}
      {tab === 'calendar' && <SalesCalendarView/>}
      {tab === 'company'  && <CompanyStatsView/>}
    </div>
  );
}

const btnSec = {
  padding:'6px 10px', fontSize:11, fontWeight:600, color:'#475569',
  background:'#fff', border:'1px solid #e2e8f0', borderRadius:5, cursor:'pointer',
  display:'inline-flex', alignItems:'center', gap:5,
};

// ─── 개요 탭 ───
function OverviewTab({ totalAmount, prevTotal, delta, totalCount }) {
  const TOP_COMPANIES = [...COMPANIES]
    .map(c => ({ name:c.name, amount:getCompanyTotalAmount(c), members:Math.round(getCompanyTotalCount(c)/15), delta:Math.round((Math.random()-0.3)*30) }))
    .sort((a,b)=>b.amount-a.amount).slice(0, 6);

  const PAYMENT_METHODS = [
    { k:'card',     label:'카드',       amount: Math.round(totalAmount*0.46), share:46, color:'#3b82f6', icon:'card' },
    { k:'transfer', label:'계좌이체',   amount: Math.round(totalAmount*0.28), share:28, color:'#16a34a', icon:'bank' },
    { k:'vbank',    label:'가상계좌',   amount: Math.round(totalAmount*0.14), share:14, color:'#8b5cf6', icon:'clipboard' },
    { k:'cash',     label:'현금',       amount: Math.round(totalAmount*0.08), share:8,  color:'#f59e0b', icon:'cash' },
    { k:'pending',  label:'미수금',     amount: Math.round(totalAmount*0.04), share:4,  color:'#dc2626', icon:'alert' },
  ];

  // 배송 그룹별 통계 (지역 단위)
  const DELIVERY_GROUPS = [
    { id:1, name:'강남·역삼',  companies:14, orders:1842, amount: 31200000, prevAmount: 28400000, prevOrders: 1720 },
    { id:2, name:'송파·잠실',  companies:9,  orders:1240, amount: 19850000, prevAmount: 21100000, prevOrders: 1320 },
    { id:3, name:'강동·천호',  companies:6,  orders:842,  amount: 12600000, prevAmount: 10200000, prevOrders: 720 },
    { id:4, name:'성동·왕십리',companies:5,  orders:680,  amount: 9800000,  prevAmount: 9100000,  prevOrders: 640 },
    { id:5, name:'마포·공덕',  companies:4,  orders:520,  amount: 7400000,  prevAmount: 7600000,  prevOrders: 560 },
    { id:0, name:'미배정',     companies:2,  orders:148,  amount: 1850000,  prevAmount: 0,        prevOrders: 0 },
  ];

  // 일별 매출 (만원 단위, 17일까지)
  const DAILY = Array.from({length:17}, (_,i)=>{
    const d = i+1;
    return CALENDAR[d] ? Math.round(CALENDAR[d].totalAmount/10000) : 0;
  });
  const PREV_DAILY = DAILY.map(v => Math.round(v*0.92));

  return (
    <div style={{ padding:20, display:'flex', flexDirection:'column', gap:16 }}>
      <div style={{ display:'grid', gridTemplateColumns:'2fr 1fr 1fr 1fr', gap:12 }}>
        <MegaKPI total={totalAmount} delta={parseFloat(delta.toFixed(1))} prevTotal={prevTotal} compareLabel="지난달 대비"/>
        <MiniKPI label="객단가" value={`${Math.round(totalAmount/totalCount).toLocaleString()}원`} delta={+3.2} icon="won" color="#3b82f6"/>
        <MiniKPI label="총 식수" value={`${totalCount.toLocaleString()}식`} delta={+18} deltaUnit="%" icon="bowl" color="#8b5cf6"/>
        <MiniKPI label="활성 업체" value={`${COMPANIES.filter(c=>c.days>0).length}개`} delta={+1} deltaUnit="개" icon="building" color="#f59e0b"/>
      </div>

      <Card title="일별 매출 추이" subtitle={`5월 1일 ~ 17일 · 일평균 ${Math.round(DAILY.filter(v=>v>0).reduce((a,b)=>a+b,0)/DAILY.filter(v=>v>0).length)}만원`}>
        <DailyChart values={DAILY} prev={PREV_DAILY}/>
      </Card>

      <div style={{ display:'grid', gridTemplateColumns:'1fr 1.4fr', gap:16 }}>
        <Card title="결제 방법별 매출 구성" subtitle="카드 결제가 46% · 계좌이체 28%">
          <PaymentMethodBars data={PAYMENT_METHODS}/>
        </Card>
        <Card title="매출 TOP 업체" subtitle="이번달 기준 상위 6개사" action="전체 보기 →">
          <TopCompanyTable rows={TOP_COMPANIES}/>
        </Card>
      </div>

      <Card title="배송 그룹별 통계" subtitle="지역별 배송 그룹 단위 매출·주문 수 · 전월 대비" action="배송순서 관리 →">
        <DeliveryGroupGrid groups={DELIVERY_GROUPS}/>
      </Card>
    </div>
  );
}

// ─── 매출 달력 ───
function SalesCalendarView() {
  // 5월 — 1일이 목요일 (Thu, weekday=4 in 일=0 system)
  const [year, month] = [2025, 5];
  const firstDow = new Date(year, month-1, 1).getDay(); // 0~6
  const daysInMonth = new Date(year, month, 0).getDate();

  // 주차별로 묶기
  const weeks = [];
  let curWeek = { days:Array(firstDow).fill(null), summary:{ items:{}, count:0, amount:0 } };
  for (let d=1; d<=daysInMonth; d++) {
    const data = CALENDAR[d] || { items:[], totalCount:0, totalAmount:0 };
    const prev7 = CALENDAR[d-7];
    const growth = (prev7 && prev7.totalAmount>0)
      ? ((data.totalAmount - prev7.totalAmount)/prev7.totalAmount*100).toFixed(1)
      : null;
    curWeek.days.push({ d, ...data, growth });

    // weekly aggregate
    data.items.forEach(it => {
      if (!curWeek.summary.items[it.name]) curWeek.summary.items[it.name] = { ...it };
      else { curWeek.summary.items[it.name].count += it.count; curWeek.summary.items[it.name].amount += it.amount; }
    });
    curWeek.summary.count  += data.totalCount;
    curWeek.summary.amount += data.totalAmount;

    if (curWeek.days.length === 7) { weeks.push(curWeek); curWeek = { days:[], summary:{ items:{}, count:0, amount:0 } }; }
  }
  if (curWeek.days.length > 0) {
    while (curWeek.days.length < 7) curWeek.days.push(null);
    weeks.push(curWeek);
  }

  // weekly growth — 같은 주 vs 전주
  weeks.forEach((w, i) => {
    if (i === 0) { w.summary.growth = null; return; }
    const prev = weeks[i-1].summary.amount;
    w.summary.growth = prev > 0 ? ((w.summary.amount - prev)/prev*100).toFixed(1) : null;
  });

  const fmt = v => v ? v.toLocaleString() : '0';
  const headers = ['일','월','화','수','목','금','토'];
  const today = 17;

  return (
    <div style={{ padding:20 }}>
      <div style={{ background:'#fff', border:'1px solid #e2e8f0', borderRadius:10, overflow:'hidden' }}>
        <div style={{ padding:'14px 18px', borderBottom:'1px solid #e2e8f0', display:'flex', alignItems:'center', justifyContent:'space-between' }}>
          <div>
            <div style={{ fontSize:14, fontWeight:800, color:'#0f172a' }}>매출 달력</div>
            <div style={{ fontSize:11, color:'#64748b', marginTop:2 }}>일별 메뉴별 식수·매출과 전주 동요일 대비 증감률</div>
          </div>
          <div style={{ display:'flex', gap:12, alignItems:'center', fontSize:11, color:'#64748b' }}>
            {MENUS.map(m => (
              <span key={m.name} style={{ display:'flex', alignItems:'center', gap:5 }}>
                <span style={{ width:10, height:10, background:m.bg, border:`1px solid ${m.fg}40`, borderRadius:2 }}/>
                <span style={{ color:m.fg, fontWeight:700 }}>{m.name}</span>
              </span>
            ))}
          </div>
        </div>

        {/* Calendar grid: 7 days + weekly column */}
        <div style={{ display:'grid', gridTemplateColumns:'repeat(7, 1fr) 1.2fr', borderTop:'1px solid #e2e8f0' }}>
          {/* header row */}
          {headers.map((h,i)=>(
            <div key={h} style={{
              padding:'8px 10px', fontSize:11, fontWeight:800,
              color: i===0?'#dc2626':i===6?'#3b82f6':'#475569',
              background:'#f8fafc', borderBottom:'1px solid #e2e8f0', borderRight:'1px solid #f1f5f9',
            }}>{h}</div>
          ))}
          <div style={{ padding:'8px 10px', fontSize:11, fontWeight:800, color:'#15803d', background:'#f0fdf4', borderBottom:'1px solid #e2e8f0' }}>주간종합</div>

          {/* week rows */}
          {weeks.map((w, wi) => (
            <React.Fragment key={wi}>
              {w.days.map((day, di) => {
                if (!day) return <div key={di} style={{ minHeight:170, background:'#fafbfc', borderRight:'1px solid #f1f5f9', borderBottom:'1px solid #f1f5f9' }}/>;
                const isWeekend = di === 0 || di === 6;
                const isToday = day.d === today;
                const isFuture = day.d > today;
                const dayColor = di===0?'#dc2626':di===6?'#3b82f6':'#0f172a';
                return (
                  <div key={di} style={{
                    padding:'7px 9px', minHeight:170, position:'relative',
                    background: isToday ? '#fffbeb' : isFuture ? '#fafbfc' : '#fff',
                    borderRight:'1px solid #f1f5f9', borderBottom:'1px solid #f1f5f9',
                    display:'flex', flexDirection:'column', gap:3,
                    outline: isToday ? '2px solid #f59e0b' : 'none', outlineOffset:'-2px',
                  }}>
                    <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:2 }}>
                      <span style={{ fontSize:13, fontWeight:800, color:dayColor, opacity:isFuture?0.35:1 }}>
                        {day.d}{isToday && <span style={{ marginLeft:4, fontSize:9, padding:'1px 4px', background:'#f59e0b', color:'#fff', borderRadius:3 }}>오늘</span>}
                      </span>
                      {day.growth !== null && day.totalAmount > 0 && (
                        <span style={{
                          fontSize:9, fontWeight:800, padding:'1px 5px', borderRadius:8,
                          background: parseFloat(day.growth) >= 0 ? '#dcfce7' : '#fee2e2',
                          color:    parseFloat(day.growth) >= 0 ? '#15803d' : '#b91c1c',
                        }}>{parseFloat(day.growth) >= 0 ? '▲' : '▼'} {Math.abs(parseFloat(day.growth))}%</span>
                      )}
                    </div>

                    {/* aligned menu rows */}
                    {MENU_NAMES.map(mn => {
                      const it = day.items.find(i => i.name === mn);
                      const meta = MENU_BY_NAME[mn];
                      return (
                        <div key={mn} style={{
                          display:'grid', gridTemplateColumns:'auto 26px 1fr',
                          alignItems:'center', gap:4, fontSize:10, fontVariantNumeric:'tabular-nums',
                          opacity: it ? 1 : 0.35,
                        }}>
                          <span style={{
                            fontSize:9, fontWeight:700, padding:'1px 5px', borderRadius:3,
                            background: meta.bg, color: meta.fg,
                          }}>{mn}</span>
                          <span style={{ textAlign:'right', color: it?'#0f172a':'#cbd5e1', fontWeight:600 }}>{it?it.count:'·'}</span>
                          <span style={{ textAlign:'right', color: it?'#475569':'#cbd5e1' }}>{it?fmt(it.amount):'·'}</span>
                        </div>
                      );
                    })}

                    {/* daily total */}
                    {day.totalAmount > 0 && (
                      <div style={{
                        display:'grid', gridTemplateColumns:'auto 26px 1fr', alignItems:'center', gap:4,
                        fontSize:10, fontVariantNumeric:'tabular-nums',
                        marginTop:'auto', paddingTop:4, borderTop:'1px dashed #e2e8f0',
                      }}>
                        <span style={{ fontSize:9, fontWeight:800, color:'#0f172a' }}>총</span>
                        <span style={{ textAlign:'right', fontWeight:800, color:'#0f172a' }}>{day.totalCount}</span>
                        <span style={{ textAlign:'right', fontWeight:800, color:'#0f172a' }}>{fmt(day.totalAmount)}</span>
                      </div>
                    )}
                  </div>
                );
              })}
              {/* weekly summary */}
              <WeeklyCell summary={w.summary} fmt={fmt}/>
            </React.Fragment>
          ))}
        </div>
      </div>

      {/* Below: month total strip */}
      <MonthTotalStrip/>
    </div>
  );
}

function WeeklyCell({ summary, fmt }) {
  if (summary.count === 0) return <div style={{ minHeight:170, background:'#f8fafc', borderBottom:'1px solid #f1f5f9' }}/>;
  return (
    <div style={{
      padding:'7px 10px', minHeight:170,
      background:'#f0fdf4', borderBottom:'1px solid #f1f5f9',
      display:'flex', flexDirection:'column', gap:3,
    }}>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:2 }}>
        <span style={{ fontSize:11, fontWeight:800, color:'#15803d' }}>주간합계</span>
        {summary.growth !== null && (
          <span style={{
            fontSize:9, fontWeight:800, padding:'1px 5px', borderRadius:8,
            background: parseFloat(summary.growth) >= 0 ? '#15803d' : '#b91c1c',
            color: '#fff',
          }}>{parseFloat(summary.growth) >= 0 ? '▲' : '▼'} {Math.abs(parseFloat(summary.growth))}%</span>
        )}
      </div>
      {MENU_NAMES.map(mn => {
        const it = summary.items[mn];
        const meta = MENU_BY_NAME[mn];
        return (
          <div key={mn} style={{
            display:'grid', gridTemplateColumns:'auto 30px 1fr', alignItems:'center', gap:4,
            fontSize:10, fontVariantNumeric:'tabular-nums', opacity: it?1:0.3,
          }}>
            <span style={{ fontSize:9, fontWeight:700, padding:'1px 5px', borderRadius:3, background:meta.bg, color:meta.fg }}>{mn}</span>
            <span style={{ textAlign:'right', color: it?'#15803d':'#cbd5e1', fontWeight:700 }}>{it?it.count:'·'}</span>
            <span style={{ textAlign:'right', color: it?'#15803d':'#cbd5e1' }}>{it?fmt(it.amount):'·'}</span>
          </div>
        );
      })}
      <div style={{
        display:'grid', gridTemplateColumns:'auto 30px 1fr', alignItems:'center', gap:4,
        fontSize:11, fontVariantNumeric:'tabular-nums',
        marginTop:'auto', paddingTop:4, borderTop:'1px solid #15803d40',
      }}>
        <span style={{ fontSize:10, fontWeight:800, color:'#15803d' }}>총</span>
        <span style={{ textAlign:'right', fontWeight:800, color:'#15803d' }}>{summary.count}</span>
        <span style={{ textAlign:'right', fontWeight:800, color:'#15803d' }}>{fmt(summary.amount)}</span>
      </div>
    </div>
  );
}

// 월 합계 띠
function MonthTotalStrip() {
  const totals = MENU_NAMES.map(mn => {
    let count = 0, amount = 0;
    Object.values(CALENDAR).forEach(day => {
      const it = day.items.find(i => i.name === mn);
      if (it) { count += it.count; amount += it.amount; }
    });
    return { name:mn, count, amount, ...MENU_BY_NAME[mn] };
  });
  const monthCount  = totals.reduce((s,t)=>s+t.count, 0);
  const monthAmount = totals.reduce((s,t)=>s+t.amount, 0);

  return (
    <div style={{ marginTop:14, padding:'14px 18px', background:'#fff', border:'1px solid #e2e8f0', borderRadius:10 }}>
      <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:10 }}>
        <div>
          <div style={{ fontSize:13, fontWeight:800, color:'#0f172a' }}>5월 메뉴별 총합</div>
          <div style={{ fontSize:11, color:'#64748b' }}>17일까지 누적</div>
        </div>
        <div style={{ display:'flex', gap:18, alignItems:'baseline' }}>
          <span style={{ fontSize:11, color:'#64748b' }}>총 식수</span>
          <span style={{ fontSize:18, fontWeight:800, color:'#0f172a', fontVariantNumeric:'tabular-nums' }}>{monthCount.toLocaleString()}식</span>
          <span style={{ fontSize:11, color:'#64748b', marginLeft:8 }}>총 매출</span>
          <span style={{ fontSize:20, fontWeight:800, color:'#16a34a', fontVariantNumeric:'tabular-nums' }}>{monthAmount.toLocaleString()}원</span>
        </div>
      </div>
      <div style={{ display:'grid', gridTemplateColumns:`repeat(${totals.length}, 1fr)`, gap:8 }}>
        {totals.map(t => (
          <div key={t.name} style={{
            padding:'10px 12px', borderRadius:8, background:t.bg, border:`1px solid ${t.fg}30`,
          }}>
            <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between' }}>
              <span style={{ fontSize:12, fontWeight:800, color:t.fg }}>{t.name}</span>
              <span style={{ fontSize:10, color:t.fg, fontWeight:600 }}>{(t.count/monthCount*100).toFixed(0)}%</span>
            </div>
            <div style={{ marginTop:4, fontSize:14, fontWeight:800, color:t.fg, fontVariantNumeric:'tabular-nums' }}>{t.count.toLocaleString()}식</div>
            <div style={{ fontSize:11, color:t.fg, opacity:0.8, fontVariantNumeric:'tabular-nums' }}>{t.amount.toLocaleString()}원</div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ─── 업체 통계 ───
function CompanyStatsView() {
  const [search, setSearch] = React.useState('');
  const [groupFilter, setGroupFilter] = React.useState('all');
  const [minCount, setMinCount] = React.useState('');
  const [maxCount, setMaxCount] = React.useState('');
  const [sortBy, setSortBy] = React.useState('total_amount');
  const [sortDir, setSortDir] = React.useState('desc');

  const uniqueGroups = [...new Set(COMPANIES.map(c => c.group.split('-')[0]).filter(g => g !== '-'))].sort();

  const filtered = COMPANIES.filter(c => {
    if (search && !c.name.toLowerCase().includes(search.toLowerCase())) return false;
    if (groupFilter === 'set' && c.group === '-') return false;
    if (groupFilter === 'unset' && c.group !== '-') return false;
    if (groupFilter !== 'all' && groupFilter !== 'set' && groupFilter !== 'unset') {
      if (!c.group.startsWith(groupFilter + '-')) return false;
    }
    const total = getCompanyTotalCount(c);
    if (minCount && total < parseInt(minCount)) return false;
    if (maxCount && total > parseInt(maxCount)) return false;
    return true;
  });

  const sorted = [...filtered].sort((a,b)=>{
    let av, bv;
    if (sortBy === 'total_amount') { av = getCompanyTotalAmount(a); bv = getCompanyTotalAmount(b); }
    else if (sortBy === 'total_count') { av = getCompanyTotalCount(a); bv = getCompanyTotalCount(b); }
    else if (sortBy === 'name') { return sortDir==='asc' ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name); }
    else if (sortBy === 'group') {
      const ag = a.group === '-' ? '999' : a.group;
      const bg = b.group === '-' ? '999' : b.group;
      return sortDir==='asc' ? ag.localeCompare(bg, undefined, {numeric:true}) : bg.localeCompare(ag, undefined, {numeric:true});
    }
    return sortDir === 'asc' ? av - bv : bv - av;
  });

  const totalCounts  = MENU_NAMES.map(m => sorted.reduce((s,c)=>s+(c.counts[m]||0), 0));
  const totalAmounts = MENU_NAMES.map(m => sorted.reduce((s,c)=>s+getCompanyAmount(c,m), 0));
  const grandCount   = totalCounts.reduce((a,b)=>a+b, 0);
  const grandAmount  = totalAmounts.reduce((a,b)=>a+b, 0);

  const toggleSort = key => {
    if (sortBy === key) setSortDir(d => d==='asc'?'desc':'asc');
    else { setSortBy(key); setSortDir('desc'); }
  };

  return (
    <div style={{ padding:20, display:'flex', flexDirection:'column', gap:14 }}>
      {/* 필터 바 */}
      <div style={{ background:'#fff', border:'1px solid #e2e8f0', borderRadius:10, padding:'12px 16px' }}>
        <div style={{ display:'flex', gap:14, alignItems:'center', flexWrap:'wrap' }}>
          <FilterGroup label="그룹">
            <div style={{ display:'flex', gap:4 }}>
              {[
                { v:'all', l:'전체' }, { v:'set', l:'설정' }, { v:'unset', l:'미설정' },
                ...uniqueGroups.map(g => ({ v:g, l:g })),
              ].map(opt => (
                <Chip key={opt.v} active={groupFilter===opt.v} onClick={()=>setGroupFilter(opt.v)}>{opt.l}</Chip>
              ))}
            </div>
          </FilterGroup>
          <FilterGroup label="총 개수">
            <input value={minCount} onChange={e=>setMinCount(e.target.value)} placeholder="최소" style={inp(70)}/>
            <span style={{ color:'#94a3b8' }}>~</span>
            <input value={maxCount} onChange={e=>setMaxCount(e.target.value)} placeholder="최대" style={inp(70)}/>
          </FilterGroup>
          <div style={{ marginLeft:'auto', position:'relative' }}>
            <div style={{ position:'relative' }}>
              <span style={{ position:'absolute', left:9, top:'50%', transform:'translateY(-50%)', color:'#94a3b8', display:'flex' }}><Icon name="search" size={13}/></span>
              <input value={search} onChange={e=>setSearch(e.target.value)} placeholder="업체명 검색" style={{
                padding:'7px 10px 7px 28px', fontSize:12, color:'#0f172a', width:200,
                border:'1px solid #e2e8f0', borderRadius:5, outline:'none', background:'#fff',
              }}/>
            </div>
          </div>
          <div style={{ display:'flex', gap:6, fontSize:11, color:'#64748b' }}>
            <span>정렬:</span>
            {[
              { k:'total_amount', l:'매출' },
              { k:'total_count',  l:'식수' },
              { k:'name',         l:'업체명' },
              { k:'group',        l:'그룹' },
            ].map(s => (
              <button key={s.k} onClick={()=>toggleSort(s.k)} style={{
                padding:'4px 8px', fontSize:11, fontWeight:700, cursor:'pointer',
                background: sortBy===s.k ? '#0f172a' : '#fff',
                color: sortBy===s.k ? '#fff' : '#64748b',
                border:'1px solid', borderColor: sortBy===s.k?'#0f172a':'#e2e8f0', borderRadius:5,
              }}>{s.l} {sortBy===s.k && (sortDir==='asc' ? '↑' : '↓')}</button>
            ))}
          </div>
        </div>
        <div style={{ marginTop:8, display:'flex', alignItems:'center', gap:8, fontSize:11, color:'#64748b' }}>
          <span style={{ fontWeight:700, color:'#0f172a' }}>{sorted.length}개</span> 업체
          {(search || groupFilter !== 'all' || minCount || maxCount) && (
            <button onClick={()=>{ setSearch(''); setGroupFilter('all'); setMinCount(''); setMaxCount(''); }} style={{
              padding:'2px 8px', fontSize:10, fontWeight:700, color:'#dc2626',
              background:'#fef2f2', border:'1px solid #fecaca', borderRadius:10, cursor:'pointer',
            }}>필터 초기화 ✕</button>
          )}
        </div>
      </div>

      {/* 와이드 테이블 */}
      <div style={{ background:'#fff', border:'1px solid #e2e8f0', borderRadius:10, overflow:'auto' }}>
        <table style={{ width:'100%', borderCollapse:'collapse', fontSize:11, fontVariantNumeric:'tabular-nums' }}>
          <thead>
            {/* group header row */}
            <tr style={{ background:'#f8fafc', borderBottom:'1px solid #e2e8f0' }}>
              <th rowSpan="2" style={thStickyL(0, 50, '#f8fafc')}>#</th>
              <th rowSpan="2" style={thStickyL(50, 70, '#f8fafc')}>그룹</th>
              <th rowSpan="2" style={thStickyL(120, 160, '#f8fafc')}>업체명</th>
              <th colSpan={MENU_NAMES.length} style={thGroup('#fef3c7', '#92400e')}>설정 단가</th>
              <th colSpan={MENU_NAMES.length+1} style={thGroup('#dbeafe', '#1d4ed8')}>식수 (개)</th>
              <th colSpan={MENU_NAMES.length+1} style={thGroup('#dcfce7', '#15803d')}>매출 (원)</th>
            </tr>
            {/* sub-column row */}
            <tr style={{ background:'#fff', borderBottom:'2px solid #e2e8f0' }}>
              {MENU_NAMES.map((m,i) => (
                <th key={'p'+m} style={thMenu(MENU_BY_NAME[m], i===0, i===MENU_NAMES.length-1, false, true)}>
                  <span style={{ fontSize:10, fontWeight:700, color:MENU_BY_NAME[m].fg }}>{m}</span>
                </th>
              ))}
              {MENU_NAMES.map((m,i) => (
                <th key={'c'+m} style={thMenu(MENU_BY_NAME[m], i===0, false, false, true)}>
                  <span style={{ fontSize:10, fontWeight:700, color:MENU_BY_NAME[m].fg }}>{m}</span>
                </th>
              ))}
              <th style={{ ...thMenu({}, false, true, true, true), color:'#1d4ed8', background:'#dbeafe' }}>총</th>
              {MENU_NAMES.map((m,i) => (
                <th key={'a'+m} style={thMenu(MENU_BY_NAME[m], i===0, false, false, true)}>
                  <span style={{ fontSize:10, fontWeight:700, color:MENU_BY_NAME[m].fg }}>{m}</span>
                </th>
              ))}
              <th style={{ ...thMenu({}, false, true, true, true), color:'#15803d', background:'#dcfce7' }}>총</th>
            </tr>
          </thead>
          <tbody>
            {sorted.map((c, idx) => (
              <CompanyRow key={c.name} idx={idx+1} c={c}/>
            ))}
            {sorted.length === 0 && (
              <tr><td colSpan={MENU_NAMES.length*3 + 5} style={{ padding:40, textAlign:'center', color:'#94a3b8' }}>
                조건에 맞는 업체가 없습니다.
              </td></tr>
            )}
          </tbody>
          {/* 합계 푸터 */}
          {sorted.length > 0 && (
            <tfoot>
              <tr style={{ background:'#f8fafc', borderTop:'2px solid #0f172a', position:'sticky', bottom:0 }}>
                <td colSpan="3" style={{ padding:'10px 14px', fontWeight:800, color:'#0f172a' }}>합계 ({sorted.length}개사)</td>
                {MENU_NAMES.map(m => (
                  <td key={'fp'+m} style={tdNum()}>
                    <span style={{ fontSize:10, color:'#94a3b8' }}>{DEFAULT_PRICES[m].toLocaleString()}</span>
                  </td>
                ))}
                {totalCounts.map((t,i) => (
                  <td key={'fc'+i} style={{ ...tdNum(), fontWeight:800 }}>{t.toLocaleString()}</td>
                ))}
                <td style={{ ...tdNum(), fontWeight:800, color:'#1d4ed8', background:'#eff6ff' }}>{grandCount.toLocaleString()}</td>
                {totalAmounts.map((t,i) => (
                  <td key={'fa'+i} style={{ ...tdNum(), fontWeight:800 }}>{t.toLocaleString()}</td>
                ))}
                <td style={{ ...tdNum(), fontWeight:800, color:'#15803d', background:'#f0fdf4' }}>{grandAmount.toLocaleString()}</td>
              </tr>
            </tfoot>
          )}
        </table>
      </div>
    </div>
  );
}

function CompanyRow({ idx, c }) {
  const totalCount  = getCompanyTotalCount(c);
  const totalAmount = getCompanyTotalAmount(c);
  const empty = totalCount === 0;
  return (
    <tr style={{ borderBottom:'1px solid #f1f5f9', opacity: empty ? 0.5 : 1 }}>
      <td style={tdStickyL(0, 50, idx%2?'#fff':'#fafbfc', '#94a3b8', 600)}>{idx}</td>
      <td style={tdStickyL(50, 70, idx%2?'#fff':'#fafbfc', '#475569', 600)}>{c.group !== '-' ? c.group : <span style={{ color:'#cbd5e1' }}>—</span>}</td>
      <td style={{ ...tdStickyL(120, 160, idx%2?'#fff':'#fafbfc', '#0f172a', 700), display:'flex', alignItems:'center', gap:6 }}>
        <span style={{ cursor:'pointer' }}>{c.name}</span>
        {c.isMember && <span style={{ padding:'1px 5px', fontSize:9, fontWeight:700, color:'#3b82f6', background:'#eff6ff', border:'1px solid #bfdbfe', borderRadius:3 }}>회원</span>}
      </td>

      {/* 설정 단가 */}
      {MENU_NAMES.map(m => {
        const isCustom = m in c.custom;
        return (
          <td key={'p'+m} style={tdNum()}>
            {isCustom && <span style={{ marginRight:4, padding:'1px 4px', fontSize:9, fontWeight:700, background:'#15803d', color:'#fff', borderRadius:2 }}>설정</span>}
            <span style={{ color: isCustom ? '#15803d' : '#94a3b8', fontWeight: isCustom ? 700 : 500 }}>
              {getCustomPrice(c,m).toLocaleString()}
            </span>
          </td>
        );
      })}

      {/* 식수 */}
      {MENU_NAMES.map(m => {
        const v = c.counts[m] || 0;
        return <td key={'c'+m} style={{ ...tdNum(), color: v>0 ? '#0f172a' : '#cbd5e1', fontWeight: v>0 ? 700 : 400 }}>{v>0 ? v.toLocaleString() : '·'}</td>;
      })}
      <td style={{ ...tdNum(), background:'#eff6ff', color:'#1d4ed8', fontWeight:800 }}>{totalCount.toLocaleString()}</td>

      {/* 매출 */}
      {MENU_NAMES.map(m => {
        const v = getCompanyAmount(c, m);
        return <td key={'a'+m} style={{ ...tdNum(), color: v>0 ? '#0f172a' : '#cbd5e1' }}>{v>0 ? v.toLocaleString() : '·'}</td>;
      })}
      <td style={{ ...tdNum(), background:'#f0fdf4', color:'#15803d', fontWeight:800 }}>{totalAmount.toLocaleString()}</td>
    </tr>
  );
}

const thGroup = (bg, fg) => ({
  padding:'8px 14px', fontSize:11, fontWeight:800, color:fg, background:bg,
  borderBottom:'1px solid #e2e8f0', borderLeft:'1px solid #e2e8f0', textAlign:'center',
});
const thMenu = (meta, isFirst, isLast, isTotal, _) => ({
  padding:'7px 8px', fontSize:11, fontWeight:700, textAlign:'right',
  borderLeft: isFirst ? '2px solid #e2e8f0' : '1px solid #f1f5f9',
  borderRight: isLast ? '2px solid #e2e8f0' : 'none',
  background: isTotal ? '#f8fafc' : '#fff',
});
const thStickyL = (left, w, bg) => ({
  padding:'10px 14px', fontSize:11, fontWeight:800, color:'#475569', textAlign:'left',
  background:bg, borderBottom:'1px solid #e2e8f0', position:'sticky', left, minWidth:w, zIndex:2,
});
const tdStickyL = (left, w, bg, color, fw) => ({
  padding:'10px 14px', fontSize:12, color, fontWeight:fw, textAlign:'left',
  background:bg, position:'sticky', left, minWidth:w, zIndex:1, borderRight:'1px solid #f1f5f9',
});
const tdNum = () => ({
  padding:'9px 8px', textAlign:'right', fontSize:11, fontVariantNumeric:'tabular-nums',
  borderLeft:'1px solid #f8fafc',
});
const inp = w => ({
  padding:'5px 8px', fontSize:11, color:'#0f172a', width:w,
  border:'1px solid #e2e8f0', borderRadius:4, outline:'none', background:'#fff',
});

function FilterGroup({ label, children }) {
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:4 }}>
      <span style={{ fontSize:10, fontWeight:700, color:'#94a3b8', letterSpacing:'0.3px', textTransform:'uppercase' }}>{label}</span>
      <div style={{ display:'flex', gap:5, alignItems:'center' }}>{children}</div>
    </div>
  );
}
function Chip({ active, onClick, children }) {
  return <button onClick={onClick} style={{
    padding:'4px 10px', fontSize:11, fontWeight:700, cursor:'pointer',
    background: active ? '#16a34a' : '#fff',
    color: active ? '#fff' : '#475569',
    border:'1px solid', borderColor: active ? '#16a34a' : '#e2e8f0', borderRadius:14,
  }}>{children}</button>;
}

// ─── 공통 컴포넌트 (Overview) ───
function MegaKPI({ total, delta, prevTotal, compareLabel }) {
  const up = delta >= 0;
  return (
    <div style={{ padding:'18px 22px', background:'linear-gradient(135deg, #16a34a, #15803d)', borderRadius:10, color:'#fff', position:'relative', overflow:'hidden' }}>
      <div style={{ fontSize:11, fontWeight:700, opacity:0.85, letterSpacing:'0.3px' }}>이번달 누적 매출</div>
      <div style={{ display:'flex', alignItems:'baseline', gap:8, marginTop:6 }}>
        <span style={{ fontSize:34, fontWeight:800, fontVariantNumeric:'tabular-nums', letterSpacing:'-1px' }}>{(total/10000).toLocaleString(undefined, {maximumFractionDigits:0})}</span>
        <span style={{ fontSize:14, opacity:0.9, fontWeight:700 }}>만원</span>
        <span style={{ marginLeft:10, padding:'4px 10px', fontSize:12, fontWeight:800, background:'rgba(255,255,255,0.18)', borderRadius:14 }}>
          {up?'▲':'▼'} {Math.abs(delta)}%
        </span>
      </div>
      <div style={{ fontSize:11, opacity:0.85, marginTop:6, fontVariantNumeric:'tabular-nums' }}>{compareLabel} {(prevTotal/10000).toLocaleString(undefined,{maximumFractionDigits:0})}만원</div>
      <div style={{ position:'absolute', right:-10, bottom:-10, opacity:0.12 }}><Icon name="trendUp" size={140} color="#fff" strokeWidth={1.5}/></div>
    </div>
  );
}
function MiniKPI({ label, value, delta, deltaUnit='%', icon, color }) {
  const up = delta >= 0;
  return (
    <div style={{ padding:'14px 16px', background:'#fff', border:'1px solid #e2e8f0', borderRadius:10 }}>
      <div style={{ display:'flex', alignItems:'center', gap:6 }}>
        <span style={{ width:24, height:24, borderRadius:6, background:`${color}15`, color, display:'flex', alignItems:'center', justifyContent:'center' }}><Icon name={icon} size={13}/></span>
        <span style={{ fontSize:11, fontWeight:700, color:'#64748b' }}>{label}</span>
      </div>
      <div style={{ fontSize:22, fontWeight:800, color:'#0f172a', marginTop:6, fontVariantNumeric:'tabular-nums', letterSpacing:'-0.5px' }}>{value}</div>
      <div style={{ fontSize:11, fontWeight:700, color: up?'#16a34a':'#dc2626', marginTop:2 }}>
        {up?'▲':'▼'} {Math.abs(delta)}{deltaUnit}<span style={{ color:'#94a3b8', fontWeight:500, marginLeft:4 }}>전월대비</span>
      </div>
    </div>
  );
}
function Card({ title, subtitle, action, children, pillBg, pillFg, pillText }) {
  return (
    <div style={{ padding:'16px 18px', background:'#fff', border:'1px solid #e2e8f0', borderRadius:10 }}>
      <div style={{ display:'flex', alignItems:'flex-start', justifyContent:'space-between', marginBottom:14 }}>
        <div>
          <div style={{ display:'flex', alignItems:'center', gap:8 }}>
            <span style={{ fontSize:14, fontWeight:800, color:'#0f172a' }}>{title}</span>
            {pillText && <span style={{ padding:'2px 8px', fontSize:10, fontWeight:700, background:pillBg, color:pillFg, borderRadius:10 }}>{pillText}</span>}
          </div>
          {subtitle && <div style={{ fontSize:11, color:'#64748b', marginTop:2 }}>{subtitle}</div>}
        </div>
        {action && <button style={{ padding:'4px 10px', background:'transparent', border:'none', fontSize:11, fontWeight:700, color:'#16a34a', cursor:'pointer' }}>{action}</button>}
      </div>
      {children}
    </div>
  );
}
function DailyChart({ values, prev }) {
  const max = Math.max(...values, ...prev);
  const days = ['목','금','토','일','월','화','수','목','금','토','일','월','화','수','목','금','토'];
  return (
    <div>
      <div style={{ display:'flex', alignItems:'flex-end', gap:6, height:200, padding:'4px 0' }}>
        {values.map((v, i)=>{
          const h = (v/max)*100;
          const ph = (prev[i]/max)*100;
          const isWeekend = i % 7 === 2 || i % 7 === 3;
          return (
            <div key={i} style={{ flex:1, height:'100%', display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'flex-end', position:'relative' }}>
              {v>0 && (
                <div style={{ position:'absolute', top:-2, transform:'translateY(-100%)', fontSize:9, color:'#475569', fontWeight:700, fontVariantNumeric:'tabular-nums' }}>{v}</div>
              )}
              <div style={{ width:'100%', display:'flex', alignItems:'flex-end', gap:2, height:'100%' }}>
                <div style={{ flex:1, height:`${ph}%`, background:'#e2e8f0', borderRadius:'3px 3px 0 0' }}/>
                <div style={{ flex:1, height:`${h}%`, background: v===0 ? '#f1f5f9' : (isWeekend ? '#cbd5e1' : 'linear-gradient(180deg, #22c55e, #16a34a)'), borderRadius:'3px 3px 0 0' }}/>
              </div>
            </div>
          );
        })}
      </div>
      <div style={{ display:'flex', gap:6, paddingTop:6, borderTop:'1px solid #f1f5f9' }}>
        {values.map((v,i)=>(
          <div key={i} style={{ flex:1, textAlign:'center', fontSize:9, color:'#94a3b8', fontVariantNumeric:'tabular-nums' }}>{i+1}<br/>{days[i]}</div>
        ))}
      </div>
      <div style={{ display:'flex', gap:14, marginTop:10, paddingTop:10, borderTop:'1px solid #f1f5f9' }}>
        <Legend color="#16a34a" label="이번달"/>
        <Legend color="#e2e8f0" label="지난달"/>
        <Legend color="#cbd5e1" label="주말"/>
      </div>
    </div>
  );
}
const Legend = ({ color, label }) => (
  <span style={{ display:'inline-flex', alignItems:'center', gap:5, fontSize:10, color:'#64748b', fontWeight:600 }}>
    <span style={{ width:10, height:10, background:color, borderRadius:2 }}/>{label}
  </span>
);
function PaymentMethodBars({ data }) {
  const total = data.reduce((a,b)=>a+b.amount,0);
  return (
    <div>
      {/* 통합 비율 바 */}
      <div style={{ display:'flex', height:28, borderRadius:6, overflow:'hidden', marginBottom:14, boxShadow:'inset 0 0 0 1px #e2e8f0' }}>
        {data.map(c => <div key={c.k} style={{ width:`${c.share}%`, background:c.color, position:'relative', display:'flex', alignItems:'center', justifyContent:'center' }}>
          {c.share >= 10 && <span style={{ fontSize:10, fontWeight:800, color:'#fff' }}>{c.share}%</span>}
        </div>)}
      </div>
      {data.map(c=>(
        <div key={c.k} style={{ display:'flex', alignItems:'center', gap:10, padding:'9px 0', borderBottom:'1px solid #f8fafc' }}>
          <span style={{ width:24, height:24, background:`${c.color}15`, color:c.color, borderRadius:5, display:'flex', alignItems:'center', justifyContent:'center' }}><Icon name={c.icon} size={13}/></span>
          <span style={{ fontSize:12, fontWeight:700, color:'#0f172a', flex:1 }}>{c.label}</span>
          <span style={{ fontSize:13, fontWeight:800, color:'#0f172a', fontVariantNumeric:'tabular-nums' }}>{(c.amount/10000).toFixed(0)}만</span>
          <span style={{ width:42, textAlign:'right', fontSize:11, color:'#64748b', fontVariantNumeric:'tabular-nums', fontWeight:600 }}>{c.share}%</span>
        </div>
      ))}
      <div style={{ display:'flex', justifyContent:'space-between', padding:'10px 0 0', fontSize:12, fontWeight:700 }}>
        <span style={{ color:'#64748b' }}>합계</span>
        <span style={{ color:'#0f172a', fontVariantNumeric:'tabular-nums' }}>{total.toLocaleString()}원</span>
      </div>
    </div>
  );
}

function DeliveryGroupGrid({ groups }) {
  const totalAmount = groups.reduce((s,g)=>s+g.amount, 0);
  const maxAmount = Math.max(...groups.map(g=>g.amount));
  return (
    <div style={{ display:'grid', gridTemplateColumns:'repeat(3, 1fr)', gap:10 }}>
      {groups.map(g => {
        const amountDelta = g.prevAmount > 0 ? ((g.amount - g.prevAmount) / g.prevAmount * 100) : null;
        const orderDelta  = g.prevOrders > 0 ? ((g.orders - g.prevOrders) / g.prevOrders * 100) : null;
        const isNew = g.prevAmount === 0;
        const up = (amountDelta ?? 0) >= 0;
        return (
          <div key={g.id} style={{
            padding:'14px 16px', background:'#fff', border:'1px solid #e2e8f0', borderRadius:8,
            position:'relative', overflow:'hidden',
          }}>
            {/* heat indicator */}
            <div style={{
              position:'absolute', left:0, top:0, bottom:0, width:3,
              background: g.id === 0 ? '#94a3b8' : `linear-gradient(180deg, #16a34a, #22c55e)`,
              opacity: g.id === 0 ? 0.5 : (g.amount / maxAmount * 0.8 + 0.2),
            }}/>
            <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between' }}>
              <div style={{ display:'flex', alignItems:'center', gap:6 }}>
                <span style={{
                  width:22, height:22, borderRadius:'50%', display:'inline-flex', alignItems:'center', justifyContent:'center',
                  background: g.id === 0 ? '#f1f5f9' : '#dcfce7',
                  color: g.id === 0 ? '#94a3b8' : '#15803d',
                  fontSize:10, fontWeight:800, fontVariantNumeric:'tabular-nums',
                }}>{g.id === 0 ? '?' : g.id}</span>
                <span style={{ fontSize:13, fontWeight:800, color: g.id === 0 ? '#94a3b8' : '#0f172a' }}>{g.name}</span>
              </div>
              {isNew && <span style={{ padding:'2px 6px', fontSize:9, fontWeight:800, background:'#eff6ff', color:'#3b82f6', borderRadius:8 }}>NEW</span>}
            </div>

            <div style={{ display:'flex', alignItems:'baseline', gap:6, marginTop:10 }}>
              <span style={{ fontSize:22, fontWeight:800, color:'#0f172a', fontVariantNumeric:'tabular-nums', letterSpacing:'-0.5px' }}>
                {(g.amount/10000).toLocaleString(undefined, {maximumFractionDigits:0})}
              </span>
              <span style={{ fontSize:11, color:'#94a3b8', fontWeight:700 }}>만원</span>
              {amountDelta !== null && (
                <span style={{
                  marginLeft:'auto', fontSize:11, fontWeight:800,
                  color: up ? '#16a34a' : '#dc2626',
                }}>{up ? '▲' : '▼'} {Math.abs(amountDelta).toFixed(1)}%</span>
              )}
            </div>

            <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:8, marginTop:10, paddingTop:10, borderTop:'1px solid #f1f5f9' }}>
              <DGStat label="업체" value={`${g.companies}개`} sub={`전체 ${(g.companies/groups.reduce((s,gg)=>s+gg.companies,0)*100).toFixed(0)}%`}/>
              <DGStat label="주문" value={`${g.orders.toLocaleString()}건`} delta={orderDelta} />
            </div>
          </div>
        );
      })}
    </div>
  );
}

function DGStat({ label, value, sub, delta }) {
  const up = (delta ?? 0) >= 0;
  return (
    <div>
      <div style={{ fontSize:10, fontWeight:700, color:'#94a3b8', textTransform:'uppercase', letterSpacing:'0.3px' }}>{label}</div>
      <div style={{ fontSize:14, fontWeight:800, color:'#0f172a', marginTop:2, fontVariantNumeric:'tabular-nums' }}>{value}</div>
      {sub && <div style={{ fontSize:10, color:'#94a3b8', marginTop:1 }}>{sub}</div>}
      {delta !== undefined && delta !== null && (
        <div style={{ fontSize:10, fontWeight:700, color: up?'#16a34a':'#dc2626', marginTop:1 }}>
          {up?'▲':'▼'} {Math.abs(delta).toFixed(1)}% <span style={{ color:'#94a3b8', fontWeight:500 }}>전월</span>
        </div>
      )}
    </div>
  );
}
function TopCompanyTable({ rows }) {
  const max = Math.max(...rows.map(r=>r.amount));
  return (
    <div>
      {rows.map((r, i) => (
        <div key={r.name} style={{ display:'flex', alignItems:'center', gap:10, padding:'10px 0', borderBottom:i<rows.length-1?'1px solid #f1f5f9':'none' }}>
          <span style={{ width:20, fontSize:11, fontWeight:800, color:'#94a3b8', fontVariantNumeric:'tabular-nums' }}>#{i+1}</span>
          <div style={{ flex:1, minWidth:0 }}>
            <div style={{ display:'flex', alignItems:'center', gap:6 }}>
              <span style={{ fontSize:12, fontWeight:700, color:'#0f172a' }}>{r.name}</span>
              <span style={{ fontSize:10, color:'#94a3b8' }}>· {r.members}명</span>
            </div>
            <div style={{ height:4, background:'#f1f5f9', borderRadius:2, marginTop:4, overflow:'hidden' }}>
              <div style={{ width:`${r.amount/max*100}%`, height:'100%', background:'linear-gradient(90deg, #16a34a, #22c55e)' }}/>
            </div>
          </div>
          <div style={{ textAlign:'right' }}>
            <div style={{ fontSize:13, fontWeight:800, color:'#0f172a', fontVariantNumeric:'tabular-nums' }}>{(r.amount/10000).toFixed(0)}만</div>
            <div style={{ fontSize:10, fontWeight:700, color: r.delta>0?'#16a34a':r.delta<0?'#dc2626':'#94a3b8' }}>
              {r.delta>0?'▲':r.delta<0?'▼':'—'} {r.delta!==0 ? Math.abs(r.delta)+'%' : '변동없음'}
            </div>
          </div>
        </div>
      ))}
    </div>
  );
}
window.SalesPage = SalesPage;
