/* AAU CRM — Shared flexible time-period navigator.
   One control used everywhere a screen shows a "mốc thời gian":
   - granularity (Ngày / Tuần / Tháng / Quý / Tùy chọn — configurable per screen)
   - ◀ ▶ history stepper so the user can walk back through past periods
   - a clickable label that opens a "jump to period" popover
   - "Hiện tại" reset chip when not on the current period
   - custom from→to range
   - compare-with dropdown
   Exposes usePeriod() + <PeriodNav/> on window. */

// Anchor "today" — ngày thật của máy (đầu ngày, giờ local). data.js TODAY dùng chung mốc này.
const _now = new Date();
const NOW = new Date(_now.getFullYear(), _now.getMonth(), _now.getDate());
const pad2 = n => ('0' + n).slice(-2);
const dmy = d => pad2(d.getDate()) + '/' + pad2(d.getMonth() + 1) + '/' + d.getFullYear();
const dm = d => pad2(d.getDate()) + '/' + pad2(d.getMonth() + 1);

function startOfWeek(d) { const x = new Date(d); const wd = (x.getDay() + 6) % 7; x.setDate(x.getDate() - wd); x.setHours(0, 0, 0, 0); return x; }
function isoWeek(d) {
  const t = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
  const day = (t.getUTCDay() + 6) % 7; t.setUTCDate(t.getUTCDate() - day + 3);
  const first = new Date(Date.UTC(t.getUTCFullYear(), 0, 4));
  return 1 + Math.round(((t - first) / 86400000 - 3 + ((first.getUTCDay() + 6) % 7)) / 7);
}

// Resolve a {gran, offset} pair (offset 0 = current, -1 = previous, …) into a concrete window + label.
function resolvePeriod(gran, offset, custom) {
  if (gran === 'custom') {
    const f = custom && custom.from ? new Date(custom.from) : NOW;
    const t = custom && custom.to ? new Date(custom.to) : NOW;
    return { gran, offset, from: f, to: t, kind: 'Tùy chọn', label: dm(f) + ' – ' + dm(t) + '/' + t.getFullYear(), short: dm(f) + '–' + dm(t) };
  }
  if (gran === 'today') {
    const d = new Date(NOW); d.setDate(d.getDate() + offset);
    return { gran, offset, from: d, to: d, kind: 'Ngày', label: (offset === 0 ? 'Hôm nay · ' : '') + dmy(d), short: dm(d) };
  }
  if (gran === '7d' || gran === '30d') {
    const span = gran === '7d' ? 7 : 30;
    const to = new Date(NOW); to.setDate(to.getDate() + offset * span);
    const from = new Date(to); from.setDate(from.getDate() - (span - 1));
    return { gran, offset, from, to, kind: span + ' ngày', label: dm(from) + ' – ' + dm(to) + '/' + to.getFullYear(), short: dm(from) + '–' + dm(to) };
  }
  if (gran === 'week') {
    const s = startOfWeek(NOW); s.setDate(s.getDate() + offset * 7);
    const e = new Date(s); e.setDate(e.getDate() + 6);
    return { gran, offset, from: s, to: e, kind: 'Tuần', label: 'Tuần ' + isoWeek(s) + ' · ' + dm(s) + '–' + dm(e), short: 'Tuần ' + isoWeek(s) };
  }
  if (gran === 'quarter') {
    const qIdx = Math.floor(NOW.getMonth() / 3) + offset;
    const m0 = new Date(NOW.getFullYear(), qIdx * 3, 1);
    const e = new Date(m0.getFullYear(), m0.getMonth() + 3, 0);
    return { gran, offset, from: m0, to: e, kind: 'Quý', label: 'Quý ' + (Math.floor(m0.getMonth() / 3) + 1) + ', ' + m0.getFullYear(), short: 'Q' + (Math.floor(m0.getMonth() / 3) + 1) + '·' + String(m0.getFullYear()).slice(-2) };
  }
  // month (default)
  const m0 = new Date(NOW.getFullYear(), NOW.getMonth() + offset, 1);
  const e = new Date(m0.getFullYear(), m0.getMonth() + 1, 0);
  return { gran: 'month', offset, from: m0, to: e, kind: 'Tháng', label: 'Tháng ' + (m0.getMonth() + 1) + ', ' + m0.getFullYear(), short: 'Th' + (m0.getMonth() + 1) + '/' + String(m0.getFullYear()).slice(-2) };
}

// Deterministic "history" multiplier — the academy grew over time, so older periods read smaller.
// Lets KPIs/charts actually shift when you look back, making the lookup feel real (not static).
function periodScale(gran, offset) {
  if (offset === 0) return 1;
  const base = gran === 'quarter' ? 0.86 : gran === 'week' ? 0.985 : (gran === 'today' || gran === '7d' || gran === '30d') ? 0.97 : 0.93;
  const wig = 1 + 0.025 * Math.sin(offset * 1.7);
  return Math.pow(base, -offset) * wig; // offset<0 ⇒ <1
}

const CMP_OPTS = [
  { value: 'off', label: 'Không so sánh' },
  { value: 'prev', label: 'vs Kỳ trước' },
  { value: 'year', label: 'vs Cùng kỳ năm trước' },
];

function usePeriod(initGran = 'month') {
  const [gran, setGranRaw] = useState(initGran);
  const [offset, setOffset] = useState(0);
  const [custom, setCustom] = useState({ from: '2026-05-04', to: '2026-06-02' });
  const [cmp, setCmp] = useState('prev');
  const cur = resolvePeriod(gran, offset, custom);
  const prev = resolvePeriod(gran, offset - 1, custom);
  const setGran = g => { setGranRaw(g); setOffset(0); };
  return {
    gran, setGran, offset, setOffset, custom, setCustom, cmp, setCmp,
    cur, prev, scale: periodScale(gran, offset),
    step: d => setOffset(o => Math.min(0, o + d)), reset: () => setOffset(0),
    cmpLabel: (CMP_OPTS.find(o => o.value === cmp) || {}).label || '',
    compareOn: cmp !== 'off',
  };
}

const DEFAULT_GRANS = [
  { value: 'week', label: 'Tuần' },
  { value: 'month', label: 'Tháng' },
  { value: 'quarter', label: 'Quý' },
];

function PeriodNav({ p, grans = DEFAULT_GRANS, compare = false, jump = 8 }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    if (!open) return;
    const h = e => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('mousedown', h);
    return () => document.removeEventListener('mousedown', h);
  }, [open]);

  const isCustom = p.gran === 'custom';
  const atNow = p.offset === 0;
  const jumpList = Array.from({ length: jump }).map((_, i) => resolvePeriod(p.gran, -i, p.custom));

  return (
    <div className="row aic g8 pnav">
      <Seg value={p.gran} onChange={p.setGran} options={grans} />

      {isCustom ? (
        <div className="row aic g6">
          <input type="date" className="input pnav-date" value={p.custom.from} onChange={e => p.setCustom({ ...p.custom, from: e.target.value })} />
          <span className="subtle t12">→</span>
          <input type="date" className="input pnav-date" value={p.custom.to} onChange={e => p.setCustom({ ...p.custom, to: e.target.value })} />
        </div>
      ) : (
        <div className="pnav-step" ref={ref}>
          <button className="pnav-arrow" title="Kỳ trước" onClick={() => p.step(-1)}><Icon name="chevronLeft" size={15} /></button>
          <button className="pnav-cur" onClick={() => setOpen(o => !o)} title="Chọn nhanh kỳ">
            <Icon name="calendar" size={13} />
            <span className="pnav-lbl">{p.cur.label}</span>
            <Icon name="chevronDown" size={13} />
          </button>
          <button className="pnav-arrow" title="Kỳ sau" disabled={atNow} onClick={() => p.step(1)}><Icon name="chevronRight" size={15} /></button>
          {open && (
            <div className="pnav-pop">
              <div className="pnav-pop-h">Tra cứu lịch sử · {p.cur.kind}</div>
              {jumpList.map(j => (
                <button key={j.offset} className={'pnav-pop-i' + (j.offset === p.offset ? ' on' : '')} onClick={() => { p.setOffset(j.offset); setOpen(false); }}>
                  <span>{j.label}</span>
                  {j.offset === 0 && <span className="pnav-tag">hiện tại</span>}
                  {j.offset === p.offset && j.offset !== 0 && <Icon name="check" size={13} />}
                </button>
              ))}
            </div>
          )}
        </div>
      )}

      {!isCustom && !atNow && (
        <button className="pnav-reset" onClick={p.reset}><Icon name="refresh" size={12} />Về hiện tại</button>
      )}

      {compare && (
        <Select value={p.cmp} onChange={p.setCmp} style={{ width: 178 }} options={CMP_OPTS} />
      )}
    </div>
  );
}

Object.assign(window, { NOW, resolvePeriod, periodScale, usePeriod, PeriodNav, isoWeek, dmy, dm, CMP_OPTS });
