/**
 * Scheduler — plugin-based cron job manager.
 *
 * Drop a file exporting `job: ScheduledJob` in this directory
 * and it will be automatically scheduled.
 *
 * Slot-specific jobs (poll open/lock/close) are registered separately
 * via Scheduler.scheduleSlots() since they depend on runtime config.
 */

 import cron from "node-cron";
 import { Client, TextChannel } from "discord.js";
 import { ScheduledJob } from "./types";
 import { Config } from "@systems/config";
 import { TGSlot } from "@types";
 
 // Import all jobs
 import { job as weeklyReset }     from "@scheduler/weekly-reset";
 import { job as midnightCleanup } from "@scheduler/midnight-cleanup";
 import { job as midnightSnapshot } from "@scheduler/midnight-snapshot";
 
 const STATIC_JOBS: ScheduledJob[] = [
   weeklyReset,
   midnightCleanup,
   midnightSnapshot
 ];
 
 type PollCallback  = (slot: TGSlot) => Promise<void>;
 type LockCallback  = (slot: TGSlot) => Promise<void>;
 type CloseCallback = (slot: TGSlot) => Promise<void>;
 
 let _tasks: cron.ScheduledTask[] = [];
 
 function stopAll(): void {
   _tasks.forEach((t) => t.stop());
   _tasks = [];
 }
 
 export const Scheduler = {
   /**
    * Schedule all jobs — static crons + slot-based polls.
    */
   schedule(
     client:      Client,
     onPollOpen:  PollCallback,
     onPollLock:  LockCallback,
     onPollClose: CloseCallback,
   ): void {
     stopAll();
 
     const tz    = process.env.TZ ?? "Etc/GMT-2";
     const slots = Config.get({ section: "poll", key: "slots" }).filter((s) => s.active);

     console.log(`[Scheduler] Weekly reset scheduled: "0 0 * * 1" in ${tz}`);
     
     // Static jobs
     for (const job of STATIC_JOBS) {
       _tasks.push(cron.schedule(
         job.cron,
         () => job.run(client),
         { timezone: job.timezone ?? tz }
       ));
       console.log(`[Scheduler] Registered: ${job.name} (${job.cron})`);
     }
 
     // Slot-based jobs
     for (const slot of slots) {
       const [openHour, openMin] = slot.pollOpens.split(":").map(Number);
 
       _tasks.push(cron.schedule(
         `${openMin} ${openHour} * * *`,
         () => onPollOpen(slot),
         { timezone: tz }
       ));
 
       _tasks.push(cron.schedule(
         `0 ${slot.tgHour} * * *`,
         () => onPollLock(slot),
         { timezone: tz }
       ));
 
       const closeMinTotal = slot.tgHour * 60 + slot.closesAfter;
       const closeHour     = Math.floor(closeMinTotal / 60) % 24;
       const closeMin      = closeMinTotal % 60;
       _tasks.push(cron.schedule(
         `${closeMin} ${closeHour} * * *`,
         () => onPollClose(slot),
         { timezone: tz }
       ));
     }
 
     console.log(`[Scheduler] ${STATIC_JOBS.length} static jobs + ${slots.length} slot(s) scheduled.`);
   },
 
   reschedule(
     client:      Client,
     onPollOpen:  PollCallback,
     onPollLock:  LockCallback,
     onPollClose: CloseCallback,
   ): void {
     Scheduler.schedule(client, onPollOpen, onPollLock, onPollClose);
   },
 
   stop(): void {
     stopAll();
     console.log(`[Scheduler] All jobs stopped.`);
   },
 };