/* ===== Recurring reports: schedules, periods, submissions ===== */

const NOW_MS = Date.now();

const CADENCES = {
  daily:   { id: "daily",   label: "รายวัน",     en: "Daily",   win: 14 },
  weekly:  { id: "weekly",  label: "รายสัปดาห์", en: "Weekly",  win: 8 },
  monthly: { id: "monthly", label: "รายเดือน",   en: "Monthly", win: 6 },
};
const DOW_TH = ["อาทิตย์","จันทร์","อังคาร","พุธ","พฤหัส","ศุกร์","เสาร์"];

// schedule: { id, owner, name, cadence, dueHour, dueDow?, dueDom? }
const REPORT_SCHEDULES = [
  { id: "r1", owner: "u1", name: "สรุปงานดีไซน์",      cadence: "daily",   dueHour: 18 },
  { id: "r2", owner: "u2", name: "อัปเดต Frontend",     cadence: "weekly",  dueHour: 17, dueDow: 5 },
  { id: "r3", owner: "u3", name: "อัปเดต Backend",      cadence: "weekly",  dueHour: 17, dueDow: 5 },
  { id: "r4", owner: "u4", name: "สรุปผลทดสอบ (QA)",    cadence: "daily",   dueHour: 18 },
  { id: "r5", owner: "u5", name: "รายงานคอนเทนต์",      cadence: "monthly", dueHour: 17, dueDom: 1 },
  { id: "r6", owner: "u6", name: "สรุปการตลาด",          cadence: "monthly", dueHour: 17, dueDom: 1 },
  { id: "r7", owner: "u7", name: "อัปเดต Mobile",        cadence: "weekly",  dueHour: 17, dueDow: 5 },
  { id: "r8", owner: "u8", name: "สรุประบบ (DevOps)",   cadence: "daily",   dueHour: 18 },
];

function isoOf(d) {
  return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}-${String(d.getDate()).padStart(2,"0")}`;
}
function daysInMonth(y, m) { return new Date(y, m+1, 0).getDate(); }

function mkPeriod(s, date, dueHour, label) {
  const due = new Date(date); due.setHours(dueHour, 0, 0, 0);
  return { key: isoOf(date), date, due, dueMs: due.getTime(), label };
}

// returns trailing periods (oldest -> newest), the newest being current/upcoming
// periods ก่อน schedule.startDate จะถูกตัดทิ้ง
function periodsFor(s) {
  const base = new Date(TODAY); base.setHours(0,0,0,0);
  const dueHour = s.dueHour ?? 18;
  const win = CADENCES[s.cadence].win;
  const out = [];

  // parse start floor (ถ้าไม่กำหนด ใช้ค่าเก่า — ไม่กรองอะไร)
  const startFloor = s.startDate ? new Date(s.startDate + "T00:00:00") : null;

  if (s.cadence === "daily") {
    for (let i = win-1; i >= 0; i--) {
      const d = new Date(base); d.setDate(base.getDate()-i);
      out.push(mkPeriod(s, d, dueHour, `${d.getDate()} ${TH_MONTHS[d.getMonth()]}`));
    }
  } else if (s.cadence === "weekly") {
    const diffNext = (s.dueDow - base.getDay() + 7) % 7;
    const nextDue = new Date(base); nextDue.setDate(base.getDate() + diffNext);
    for (let i = win-1; i >= 0; i--) {
      const d = new Date(nextDue); d.setDate(nextDue.getDate() - i*7);
      out.push(mkPeriod(s, d, dueHour, `${d.getDate()} ${TH_MONTHS[d.getMonth()]}`));
    }
  } else { // monthly
    let refY = base.getFullYear(), refM = base.getMonth();
    if (base.getDate() > s.dueDom) { refM++; if (refM > 11) { refM = 0; refY++; } }
    for (let i = win-1; i >= 0; i--) {
      let y = refY, m = refM - i;
      while (m < 0) { m += 12; y--; }
      const d = new Date(y, m, Math.min(s.dueDom, daysInMonth(y, m)));
      out.push(mkPeriod(s, d, dueHour, `${TH_MONTHS[m]} ${String(y+543).slice(-2)}`));
    }
  }
  // filter: ตัด periods ที่ครบกำหนดก่อนวันที่เริ่ม
  if (startFloor) return out.filter(p => p.date >= startFloor);
  return out;
}

const subKey = (scheduleId, periodKey) => `${scheduleId}::${periodKey}`;

// status for one period given its submission (or undefined)
function reportStatus(period, sub) {
  if (sub) return sub.at <= period.dueMs ? "ontime" : "late";
  return NOW_MS > period.dueMs ? "missed" : "pending";
}

const REPORT_STATUS = {
  ontime:  { id: "ontime",  label: "ส่งตรงเวลา", color: "var(--done)",   soft: "var(--done-soft)" },
  late:    { id: "late",    label: "ส่งช้า",     color: "var(--review)", soft: "var(--review-soft)" },
  missed:  { id: "missed",  label: "ขาดส่ง",     color: "var(--high)",   soft: "var(--high-soft)" },
  pending: { id: "pending", label: "รอส่ง",      color: "var(--todo)",   soft: "var(--todo-soft)" },
};

// deterministic seed submissions for past periods
function buildSeedSubmissions() {
  const subs = {};
  REPORT_SCHEDULES.forEach((s, si) => {
    const seed = si + 1;
    periodsFor(s).forEach((p, i) => {
      if (NOW_MS <= p.dueMs) return;               // pending -> no submission
      const r = (i * 7 + seed * 3) % 13;
      if (r === 4 || r === 9) return;              // ~missed
      const late = (r === 2 || r === 7);           // ~late
      const offset = late
        ? (3 + (r % 4)) * 3600000                  // few hours after due
        : -(1 + (r % 3)) * 3600000;                // before due
      subs[subKey(s.id, p.key)] = { at: p.dueMs + offset, remark: "" };
    });
  });
  // a couple of sample remarks
  return subs;
}

Object.assign(window, {
  CADENCES, DOW_TH, REPORT_SCHEDULES,
  periodsFor, subKey, reportStatus, REPORT_STATUS,
  buildSeedSubmissions, NOW_MS,
});
