// activity.jsx — 활동 로그 시각화 (C2, 디렉터 권고 P2)
// ──────────────────────────────────────────────────────────────
// owner 전용. 직원별 작업(견적/입고/주문변경/직원관리) 30일 타임라인.
// DAL.listActivity()가 있으면 사용, 없으면 mock 합성.
// ──────────────────────────────────────────────────────────────

const { useState, useEffect, useMemo } = React;

// 활동 타입 메타
const TYPES = {
  quote_create:  { emoji:"🧾", label:"견적 발행", color:"#0064FF" },
  quote_status:  { emoji:"✏️", label:"견적 상태 변경", color:"#8B95A1" },
  stock_in:      { emoji:"📦", label:"입고",         color:"#00C896" },
  stock_out:     { emoji:"📤", label:"출고",         color:"#FF7A00" },
  bike_create:   { emoji:"🆕", label:"모델 등록",     color:"#E31E26" },
  bike_price:    { emoji:"💰", label:"가격 변경",     color:"#FFB800" },
  staff_invite:  { emoji:"👥", label:"직원 초대",     color:"#8B5CF6" },
  staff_role:    { emoji:"🔐", label:"권한 변경",     color:"#EF4444" },
  login:         { emoji:"🔑", label:"로그인",        color:"#6B7684" },
  other:         { emoji:"•",  label:"기타",          color:"#8B95A1" },
};

// ── 헤더 ──────────────────────────────────────────────────────
function Header() {
  return (
    <header className="cat-header">
      <div className="cat-header-inner">
        <a className="cat-brand" href="관리자.html">
          <img className="cat-brand-mark" src="assets/symbol-brush.svg" alt="" />
          <div>
            <div className="cat-brand-name">스페셜라이즈드 세종점</div>
            <div className="cat-brand-sub">Admin · 활동 로그</div>
          </div>
        </a>
        <div className="cat-header-sep" />
        <div className="cat-header-title">활동 <b>로그</b></div>
        <div className="cat-header-tools">
          <span>최근 <b>30일</b></span>
          {window.HeaderUser && React.createElement(window.HeaderUser)}
        </div>
      </div>
    </header>
  );
}

// v3.25: 공용 PageNav 컴포넌트로 교체
function PageNav() {
  return window.PageNav ? React.createElement(window.PageNav, { active: "activity" }) : null;
}

// ── 권한 가드 — owner 외 차단 ─────────────────────────────────
function Forbidden() {
  return (
    <main className="adm-main">
      <div className="cat-inner" style={{padding:"60px 20px",textAlign:"center"}}>
        <div style={{fontSize:48,marginBottom:12}}>🔒</div>
        <h1 style={{margin:"0 0 8px",font:"700 24px/1.3 var(--font-sans)"}}>접근 권한이 없습니다</h1>
        <p style={{color:"var(--grey-600,#6B7684)",marginBottom:20}}>
          활동 로그는 사장님(owner) 전용입니다.
        </p>
        <a href="관리자.html" className="cat-print-btn" style={{display:"inline-block"}}>
          ← 대시보드로 돌아가기
        </a>
      </div>
    </main>
  );
}

// ── 활동 mock 합성 (실 DAL 없을 때) ─────────────────────────────
function generateMock() {
  const staffs = ["김사장", "박매니저", "이정비사", "최스태프"];
  const types = Object.keys(TYPES).filter(k => k !== "other");
  const rows = [];
  const now = Date.now();
  for (let i = 0; i < 60; i++) {
    const t = types[Math.floor(Math.random() * types.length)];
    const daysAgo = Math.floor(Math.random() * 30);
    const hoursAgo = Math.floor(Math.random() * 24);
    rows.push({
      id: "mock-" + i,
      type: t,
      staff: staffs[Math.floor(Math.random() * staffs.length)],
      detail: mockDetail(t),
      at: new Date(now - (daysAgo*24 + hoursAgo) * 3600 * 1000).toISOString(),
    });
  }
  return rows.sort((a,b) => b.at.localeCompare(a.at));
}

function mockDetail(type) {
  const samples = {
    quote_create: ["Tarmac SL8 Comp · 7,490,000원", "Roubaix Sport · 4,200,000원", "정비 풀튠 · 350,000원"],
    quote_status: ["대기 → 수락", "수락 → 만료", "대기 → 거절"],
    stock_in:     ["Tarmac SL8 +5대", "Allez Sprint +3대", "Roubaix +2대"],
    stock_out:    ["Tarmac SL8 −1대 (출고)", "Diverge −1대 (출고)"],
    bike_create:  ["새 모델 등록 · Aethos S-Works", "새 모델 등록 · Levo Comp"],
    bike_price:   ["Tarmac SL8: 7,200,000 → 7,490,000", "Roubaix: 4,000,000 → 4,200,000"],
    staff_invite: ["박매니저 초대", "최스태프 초대"],
    staff_role:   ["한지영: 미지정 → shop_master", "박미경: 미지정 → shop_master"],
    login:        ["로그인 성공", "로그인 성공 (모바일)"],
  };
  const s = samples[type] || ["—"];
  return s[Math.floor(Math.random() * s.length)];
}

// ── 통계 카드 ─────────────────────────────────────────────────
function StatsCards({ rows }) {
  const totals = useMemo(() => {
    const byType = {};
    const byStaff = {};
    const today = new Date().toISOString().slice(0,10);
    let todayCount = 0;
    rows.forEach(r => {
      byType[r.type] = (byType[r.type] || 0) + 1;
      byStaff[r.staff] = (byStaff[r.staff] || 0) + 1;
      if (r.at.startsWith(today)) todayCount++;
    });
    const topStaff = Object.entries(byStaff).sort((a,b)=>b[1]-a[1])[0];
    return { total: rows.length, today: todayCount, topStaff };
  }, [rows]);

  const cardStyle = {
    flex:1, padding:"18px 20px", background:"#fff",
    border:"1px solid var(--grey-200,#E5E8EB)", borderRadius:12,
  };

  return (
    <div style={{display:"flex",gap:12,marginBottom:20,flexWrap:"wrap"}}>
      <div style={cardStyle}>
        <div style={{fontSize:13,color:"var(--grey-600,#6B7684)"}}>전체 활동</div>
        <div style={{font:"700 28px/1.2 var(--font-sans)",marginTop:4}}>{totals.total}<small style={{fontSize:14,color:"var(--grey-500,#8B95A1)",marginLeft:4}}>건</small></div>
        <div style={{fontSize:12,color:"var(--grey-500,#8B95A1)",marginTop:4}}>최근 30일</div>
      </div>
      <div style={cardStyle}>
        <div style={{fontSize:13,color:"var(--grey-600,#6B7684)"}}>오늘 활동</div>
        <div style={{font:"700 28px/1.2 var(--font-sans)",marginTop:4}}>{totals.today}<small style={{fontSize:14,color:"var(--grey-500,#8B95A1)",marginLeft:4}}>건</small></div>
        <div style={{fontSize:12,color:"var(--grey-500,#8B95A1)",marginTop:4}}>{new Date().toLocaleDateString("ko-KR")}</div>
      </div>
      <div style={cardStyle}>
        <div style={{fontSize:13,color:"var(--grey-600,#6B7684)"}}>가장 활발한 직원</div>
        <div style={{font:"700 22px/1.2 var(--font-sans)",marginTop:4}}>
          {totals.topStaff ? totals.topStaff[0] : "—"}
          {totals.topStaff && <small style={{fontSize:13,color:"var(--grey-500,#8B95A1)",marginLeft:6}}>{totals.topStaff[1]}건</small>}
        </div>
        <div style={{fontSize:12,color:"var(--grey-500,#8B95A1)",marginTop:4}}>30일 누적</div>
      </div>
    </div>
  );
}

// ── 필터 바 ───────────────────────────────────────────────────
function FilterBar({ filters, setFilters, staffList }) {
  return (
    <div style={{
      display:"flex",gap:10,marginBottom:16,flexWrap:"wrap",
      padding:"12px 14px",background:"#fff",
      border:"1px solid var(--grey-200,#E5E8EB)",borderRadius:12,
    }}>
      <div style={{display:"flex",alignItems:"center",gap:6,fontSize:13,color:"var(--grey-600,#6B7684)"}}>
        🔍 필터
      </div>
      <select value={filters.staff} onChange={e=>setFilters({...filters,staff:e.target.value})}
        style={{padding:"6px 10px",border:"1px solid var(--grey-300,#D1D6DB)",borderRadius:8,fontSize:13}}>
        <option value="">모든 직원</option>
        {staffList.map(s => <option key={s} value={s}>{s}</option>)}
      </select>
      <select value={filters.type} onChange={e=>setFilters({...filters,type:e.target.value})}
        style={{padding:"6px 10px",border:"1px solid var(--grey-300,#D1D6DB)",borderRadius:8,fontSize:13}}>
        <option value="">모든 작업</option>
        {Object.entries(TYPES).map(([k,v]) => <option key={k} value={k}>{v.emoji} {v.label}</option>)}
      </select>
      <input type="text" value={filters.q} onChange={e=>setFilters({...filters,q:e.target.value})}
        placeholder="키워드 검색 (예: Tarmac, 정비)"
        style={{flex:1,minWidth:180,padding:"6px 10px",border:"1px solid var(--grey-300,#D1D6DB)",borderRadius:8,fontSize:13}} />
      <button onClick={()=>setFilters({staff:"",type:"",q:""})} style={{
        padding:"6px 12px",border:"1px solid var(--grey-300,#D1D6DB)",borderRadius:8,
        background:"#fff",cursor:"pointer",fontSize:12,color:"var(--grey-600,#6B7684)",
      }}>초기화</button>
    </div>
  );
}

// ── 타임라인 ──────────────────────────────────────────────────
function Timeline({ rows }) {
  if (rows.length === 0) {
    return (
      <div style={{
        padding:"60px 20px",textAlign:"center",
        background:"#fff",border:"1px dashed var(--grey-300,#D1D6DB)",borderRadius:12,
      }}>
        <div style={{fontSize:32,marginBottom:8}}>📭</div>
        <div style={{color:"var(--grey-600,#6B7684)"}}>조건에 맞는 활동이 없습니다.</div>
      </div>
    );
  }
  // 날짜별 그룹
  const byDate = {};
  rows.forEach(r => {
    const d = r.at.slice(0,10);
    (byDate[d] = byDate[d] || []).push(r);
  });
  const dates = Object.keys(byDate).sort().reverse();

  const labelDate = (d) => {
    const today = new Date().toISOString().slice(0,10);
    const yest = new Date(Date.now()-86400000).toISOString().slice(0,10);
    if (d === today) return "오늘";
    if (d === yest) return "어제";
    const [y,m,day] = d.split("-");
    return `${m}월 ${day}일`;
  };

  return (
    <div style={{display:"flex",flexDirection:"column",gap:20}}>
      {dates.map(d => (
        <section key={d}>
          <div style={{
            fontSize:14,fontWeight:600,color:"var(--grey-700,#4E5968)",
            marginBottom:10,paddingLeft:4,
          }}>
            {labelDate(d)} <small style={{color:"var(--grey-500,#8B95A1)",fontWeight:400,marginLeft:6}}>{d} · {byDate[d].length}건</small>
          </div>
          <div style={{
            background:"#fff",border:"1px solid var(--grey-200,#E5E8EB)",borderRadius:12,
            overflow:"hidden",
          }}>
            {byDate[d].map((r,i) => {
              const meta = TYPES[r.type] || TYPES.other;
              return (
                <div key={r.id} style={{
                  display:"flex",alignItems:"center",gap:14,padding:"14px 16px",
                  borderTop: i>0 ? "1px solid var(--grey-100,#F2F4F6)" : "none",
                }}>
                  <div style={{
                    width:36,height:36,borderRadius:10,
                    background: meta.color + "15", color: meta.color,
                    display:"flex",alignItems:"center",justifyContent:"center",fontSize:18,flexShrink:0,
                  }}>{meta.emoji}</div>
                  <div style={{flex:1,minWidth:0}}>
                    <div style={{fontSize:14,color:"var(--grey-900,#191F28)",fontWeight:500}}>
                      <b>{r.staff}</b> · {meta.label}
                    </div>
                    <div style={{fontSize:13,color:"var(--grey-600,#6B7684)",marginTop:2,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}>
                      {r.detail}
                    </div>
                  </div>
                  <div style={{fontSize:12,color:"var(--grey-500,#8B95A1)",flexShrink:0}}>
                    {r.at.slice(11,16)}
                  </div>
                </div>
              );
            })}
          </div>
        </section>
      ))}
    </div>
  );
}

// ── 메인 앱 ───────────────────────────────────────────────────
function App() {
  const role = window.AUTH?.role || "owner";
  const [rows, setRows] = useState([]);
  const [loading, setLoading] = useState(true);
  const [filters, setFilters] = useState({ staff:"", type:"", q:"" });

  useEffect(() => {
    let cancelled = false;
    async function load() {
      try {
        let data = [];
        if (window.DAL?.listActivity) {
          data = await window.DAL.listActivity({ days: 30 });
        } else {
          data = generateMock();
        }
        if (!cancelled) { setRows(data); setLoading(false); }
      } catch (e) {
        console.warn("[activity] load fail, fallback to mock:", e);
        if (!cancelled) { setRows(generateMock()); setLoading(false); }
      }
    }
    load();
    return () => { cancelled = true; };
  }, []);

  // RBAC v1.1: activity.view_all 권한 체크
  const canView = window.AUTH?.can?.("activity.view_all") ?? (role === "owner");
  if (!canView) {
    return (
      <div className="cat-app">
        <Header /><PageNav />
        <Forbidden />
      </div>
    );
  }

  const staffList = useMemo(() => [...new Set(rows.map(r => r.staff))].sort(), [rows]);
  const filtered = useMemo(() => rows.filter(r => {
    if (filters.staff && r.staff !== filters.staff) return false;
    if (filters.type && r.type !== filters.type) return false;
    if (filters.q && !(r.detail || "").toLowerCase().includes(filters.q.toLowerCase())) return false;
    return true;
  }), [rows, filters]);

  return (
    <div className="cat-app">
      <Header />
      <PageNav />
      <main className="adm-main">
        <div className="cat-inner">
          <div className="adm-page-head">
            <div>
              <h1>활동 로그</h1>
              <p>최근 30일간 직원이 수행한 모든 작업의 시간순 기록입니다.</p>
            </div>
            <div className="adm-page-head-tools">
              <a href="관리자.html" className="cat-print-btn" style={{height:36,lineHeight:"36px"}}>
                ← 대시보드
              </a>
            </div>
          </div>

          {loading ? (
            <div style={{padding:"60px 20px",textAlign:"center",color:"var(--grey-500,#8B95A1)"}}>
              불러오는 중...
            </div>
          ) : (
            <React.Fragment>
              <StatsCards rows={rows} />
              <FilterBar filters={filters} setFilters={setFilters} staffList={staffList} />
              <Timeline rows={filtered} />
            </React.Fragment>
          )}
        </div>
      </main>
    </div>
  );
}

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