import { getForm16Config } from '../services/form16Config.service';
import { runForm16AlertSubmitJob, runForm16ReminderJob, runForm16Remind26AsUploadJob } from '../services/form16Notification.service';
import logger from '../utils/logger';

const TZ = process.env.TZ || 'Asia/Kolkata';
// 26AS reminder is quarter-based; we evaluate once daily at this fixed time.
const RE_26AS_REMINDER_CHECK_TIME = '08:30';

/** Last date (YYYY-MM-DD) we ran the alert job in the configured timezone. */
let lastAlertRunDate: string | null = null;
/** Last date (YYYY-MM-DD) we ran the reminder job in the configured timezone. */
let lastReminderRunDate: string | null = null;
/** Last date (YYYY-MM-DD) we ran the 26AS upload reminder job in the configured timezone. */
let last26AsReminderRunDate: string | null = null;

/**
 * Get current time in configured TZ as HH:mm (24h, zero-padded).
 */
function getCurrentTimeHHmm(): string {
  const now = new Date();
  const str = now.toLocaleTimeString('en-CA', { hour: '2-digit', minute: '2-digit', hour12: false, timeZone: TZ });
  const [h, m] = str.split(':').map((x) => parseInt(x, 10));
  if (Number.isNaN(h) || Number.isNaN(m)) return '00:00';
  return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;
}

/**
 * Get current date in configured TZ as YYYY-MM-DD.
 */
function getCurrentDateString(): string {
  const now = new Date();
  const str = now.toLocaleDateString('en-CA', { timeZone: TZ });
  return str;
}

/**
 * Tick: run every minute; if current time matches config run-at time and we haven't run today, run the job.
 */
async function form16NotificationTick(): Promise<void> {
  try {
    const config = await getForm16Config();
    const nowTime = getCurrentTimeHHmm();
    const today = getCurrentDateString();

    const alertTime = (config.alertSubmitForm16RunAtTime || '').trim();
    if (config.alertSubmitForm16Enabled && alertTime && alertTime === nowTime && lastAlertRunDate !== today) {
      lastAlertRunDate = today;
      logger.info(`[Form16 Job] Running alert submit job (scheduled at ${alertTime})`);
      await runForm16AlertSubmitJob();
    }

    const reminderTime = (config.reminderRunAtTime || '').trim();
    if (config.reminderNotificationEnabled && reminderTime && reminderTime === nowTime && lastReminderRunDate !== today) {
      lastReminderRunDate = today;
      logger.info(`[Form16 Job] Running reminder job (scheduled at ${reminderTime})`);
      await runForm16ReminderJob();
    }

    if (config.reminder26AsUploadEnabled && RE_26AS_REMINDER_CHECK_TIME === nowTime && last26AsReminderRunDate !== today) {
      last26AsReminderRunDate = today;
      logger.info(`[Form16 Job] Running 26AS upload reminder job (daily check at ${RE_26AS_REMINDER_CHECK_TIME})`);
      await runForm16Remind26AsUploadJob();
    }
  } catch (e) {
    logger.error('[Form16 Job] Tick error:', e);
  }
}

/**
 * Start Form 16 scheduled notification jobs.
 * Schedule is read from Form 16 admin config (alertSubmitForm16RunAtTime, reminderRunAtTime).
 * A tick runs every minute; when server time (in configured TZ) matches the run-at time, the job runs once that day.
 */
export function startForm16NotificationJobs(): void {
  const cron = require('node-cron');
  cron.schedule('* * * * *', () => {
    form16NotificationTick();
  }, { timezone: TZ });

  logger.info(`[Form16 Job] Form 16 notification jobs scheduled (config-driven run times, TZ: ${TZ})`);
}
