import fs from 'fs';
import path from 'path';
import { v4 as uuidv4 } from 'uuid';
import { toggleCategory } from './policyEngine.js';

const DATA_PATH = '/data/timers.json';

let activeTimers = [];
let timeoutHandles = new Map();

export function loadTimers() {
  try {
    if (fs.existsSync(DATA_PATH)) {
      const raw = fs.readFileSync(DATA_PATH, 'utf-8');
      activeTimers = JSON.parse(raw);
      console.log(`[TimerService] Loaded ${activeTimers.length} timers from disk`);
      resumeTimers();
    } else {
      activeTimers = [];
      saveTimers();
    }
  } catch (err) {
    console.error('[TimerService] Error loading timers:', err.message);
    activeTimers = [];
  }
}

function saveTimers() {
  const dir = path.dirname(DATA_PATH);
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
  fs.writeFileSync(DATA_PATH, JSON.stringify(activeTimers, null, 2));
}

function resumeTimers() {
  const now = Date.now();
  const expired = [];
  const valid = [];

  for (const timer of activeTimers) {
    const remaining = timer.expiresAt - now;
    if (remaining <= 0) {
      expired.push(timer);
    } else {
      valid.push(timer);
      scheduleTimeout(timer, remaining);
    }
  }

  // Fire expired timers immediately
  for (const timer of expired) {
    console.log(`[TimerService] Timer ${timer.id} expired while offline, re-blocking ${timer.category}`);
    onTimerExpire(timer);
  }
}

function scheduleTimeout(timer, ms) {
  const handle = setTimeout(() => onTimerExpire(timer), ms);
  timeoutHandles.set(timer.id, handle);
}

async function onTimerExpire(timer) {
  console.log(`[TimerService] Timer expired: ${timer.id} for ${timer.category}`);
  try {
    await toggleCategory(timer.category, false); // Re-block
  } catch (err) {
    console.error(`[TimerService] Failed to re-block ${timer.category}:`, err.message);
  }
  activeTimers = activeTimers.filter((t) => t.id !== timer.id);
  timeoutHandles.delete(timer.id);
  saveTimers();
}

export async function createTimer(category, minutes) {
  const now = Date.now();
  const expiresAt = now + minutes * 60 * 1000;
  const timer = {
    id: uuidv4(),
    category,
    minutes,
    createdAt: now,
    expiresAt,
  };

  // Allow the category during bonus time
  await toggleCategory(category, true);

  activeTimers.push(timer);
  saveTimers();
  scheduleTimeout(timer, minutes * 60 * 1000);

  console.log(`[TimerService] Created timer ${timer.id}: ${category} for ${minutes}m`);
  return timer;
}

export function getTimers() {
  const now = Date.now();
  return activeTimers.map((t) => ({
    ...t,
    remainingMs: Math.max(0, t.expiresAt - now),
  }));
}

export function cancelTimer(id) {
  const timer = activeTimers.find((t) => t.id === id);
  if (!timer) throw new Error('Timer not found');

  const handle = timeoutHandles.get(id);
  if (handle) clearTimeout(handle);
  timeoutHandles.delete(id);

  activeTimers = activeTimers.filter((t) => t.id !== id);
  saveTimers();

  console.log(`[TimerService] Cancelled timer ${id}`);
  return timer;
}
