import { useState, useEffect, useCallback } from "react";
import { toast } from "sonner";

export interface Reminder {
  id: string;
  notificationId: string;
  message: string;
  subject: { en: string; am?: string };
  remindAt: string; // ISO timestamp
  itemId: string;
  metadata?: {
    route?: string;
    recordType?: string;
  };
  createdAt: string;
  status: "pending" | "triggered" | "dismissed";
}

const STORAGE_KEY = "smartoffice_reminders";

// Helper to get reminders from localStorage
const getStoredReminders = (): Reminder[] => {
  try {
    const stored = localStorage.getItem(STORAGE_KEY);
    return stored ? JSON.parse(stored) : [];
  } catch (error) {
    console.error("Error reading reminders from localStorage:", error);
    return [];
  }
};

// Helper to save reminders to localStorage
const saveReminders = (reminders: Reminder[]) => {
  try {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(reminders));
  } catch (error) {
    console.error("Error saving reminders to localStorage:", error);
  }
};

export const useReminder = () => {
  const [reminders, setReminders] = useState<Reminder[]>([]);
  const [activeTimeouts, setActiveTimeouts] = useState<Map<string, NodeJS.Timeout>>(new Map());

  // Load reminders from localStorage on mount
  useEffect(() => {
    const stored = getStoredReminders();
    setReminders(stored);
  }, []);

  // Schedule a reminder
  const scheduleReminder = useCallback((reminder: Omit<Reminder, "createdAt" | "status">) => {
    const newReminder: Reminder = {
      ...reminder,
      createdAt: new Date().toISOString(),
      status: "pending",
    };

    setReminders((prev) => {
      const updated = [...prev, newReminder];
      saveReminders(updated);
      return updated;
    });

    return newReminder;
  }, []);

  // Trigger a reminder (show notification)
  const triggerReminder = useCallback((reminder: Reminder, onNavigate?: (reminder: Reminder) => void) => {
    // Show toast with action buttons
    toast(reminder.message, {
      description: reminder.subject.en,
      duration: 10000, // 10 seconds
      action: onNavigate ? {
        label: "View",
        onClick: () => onNavigate(reminder),
      } : undefined,
    });

    // Show browser notification if permission granted
    if ("Notification" in window && Notification.permission === "granted") {
      const notification = new Notification(reminder.subject.en, {
        body: reminder.message,
        icon: "/favicon.ico",
        tag: reminder.id,
      });

      notification.onclick = () => {
        if (onNavigate) onNavigate(reminder);
        notification.close();
      };
    }

    // Mark as triggered
    setReminders((prev) => {
      const updated = prev.map((r) =>
        r.id === reminder.id ? { ...r, status: "triggered" as const } : r
      );
      saveReminders(updated);
      return updated;
    });
  }, []);

  // Setup timers for pending reminders
  useEffect(() => {
    const now = Date.now();
    const newTimeouts = new Map<string, NodeJS.Timeout>();

    reminders.forEach((reminder) => {
      if (reminder.status !== "pending") return;

      const remindTime = new Date(reminder.remindAt).getTime();
      const delay = remindTime - now;

      if (delay <= 0) {
        // Missed reminder - trigger immediately
        triggerReminder(reminder);
      } else if (delay < 2147483647) {
        // Max setTimeout delay is ~24.8 days
        const timeout = setTimeout(() => {
          triggerReminder(reminder);
        }, delay);
        newTimeouts.set(reminder.id, timeout);
      }
    });

    // Clear old timeouts
    activeTimeouts.forEach((timeout, id) => {
      if (!newTimeouts.has(id)) {
        clearTimeout(timeout);
      }
    });

    setActiveTimeouts(newTimeouts);

    // Cleanup on unmount
    return () => {
      newTimeouts.forEach((timeout) => clearTimeout(timeout));
    };
  }, [reminders, triggerReminder]); // eslint-disable-line react-hooks/exhaustive-deps

  // Snooze a reminder (add X minutes)
  const snoozeReminder = useCallback((reminderId: string, minutes: number) => {
    setReminders((prev) => {
      const updated = prev.map((r) => {
        if (r.id === reminderId) {
          const newRemindAt = new Date(Date.now() + minutes * 60 * 1000).toISOString();
          return { ...r, remindAt: newRemindAt, status: "pending" as const };
        }
        return r;
      });
      saveReminders(updated);
      return updated;
    });

    toast.success(`Reminder snoozed for ${minutes} minutes`);
  }, []);

  // Dismiss a reminder
  const dismissReminder = useCallback((reminderId: string) => {
    setReminders((prev) => {
      const updated = prev.map((r) =>
        r.id === reminderId ? { ...r, status: "dismissed" as const } : r
      );
      saveReminders(updated);
      return updated;
    });
  }, []);

  // Delete a reminder
  const deleteReminder = useCallback((reminderId: string) => {
    setReminders((prev) => {
      const updated = prev.filter((r) => r.id !== reminderId);
      saveReminders(updated);
      return updated;
    });
  }, []);

  // Get pending reminders count
  const pendingCount = reminders.filter((r) => r.status === "pending").length;

  // Clear all reminders
  const clearAllReminders = useCallback(() => {
    setReminders([]);
    saveReminders([]);
    activeTimeouts.forEach((timeout) => clearTimeout(timeout));
    setActiveTimeouts(new Map());
  }, [activeTimeouts]);

  return {
    reminders,
    pendingReminders: reminders.filter((r) => r.status === "pending"),
    pendingCount,
    scheduleReminder,
    snoozeReminder,
    dismissReminder,
    deleteReminder,
    clearAllReminders,
  };
};
