import { create } from "zustand";

const CLAIMED_STORAGE_KEY  = "mindavio-claimed-rewards";
const DISMISSED_STORAGE_KEY = "mindavio-dismissed-smart-notifs";

/* ── Smart notification types ─────────────────────────────────────────────── */

export type SmartNotificationType =
  | "task_overdue"
  | "task_deadline_today"
  | "task_deadline_tomorrow"
  | "event_upcoming"
  | "journal_reminder"
  | "reminder_due"
  | "achievement_completed"
  | "reward_claimable";

export type SmartNotificationLevel =
  | "urgent"
  | "warning"
  | "info"
  | "achievement"
  | "reward";

export interface SmartNotification {
  id:        string;
  type:      SmartNotificationType;
  title:     string;
  body:      string;
  level:     SmartNotificationLevel;
  link?:     string;
  createdAt: number;
}

/* ── Store ────────────────────────────────────────────────────────────────── */

interface NotificationStore {
  smartNotifications: SmartNotification[];
  dismissedIds:       string[];
  lastCheckedAt:      number | null;

  /* Claimed rewards (keyed by achievementId → ISO date string) */
  claimedRewards:     Record<string, string>;

  addSmartNotification:    (notif: SmartNotification) => void;
  dismissSmartNotification:(id: string) => void;
  clearAllSmart:           () => void;
  setLastChecked:          (ts: number) => void;

  claimReward:     (achievementId: string) => void;
  isRewardClaimed: (achievementId: string) => boolean;
}

/* ── Persistence helpers ─────────────────────────────────────────────────── */

function loadClaimed(): Record<string, string> {
  if (typeof window === "undefined") return {};
  try { return JSON.parse(localStorage.getItem(CLAIMED_STORAGE_KEY) || "{}"); }
  catch { return {}; }
}

function saveClaimed(r: Record<string, string>) {
  try { localStorage.setItem(CLAIMED_STORAGE_KEY, JSON.stringify(r)); } catch { /* ignore */ }
}

function loadDismissed(): string[] {
  if (typeof window === "undefined") return [];
  try { return JSON.parse(localStorage.getItem(DISMISSED_STORAGE_KEY) || "[]"); }
  catch { return []; }
}

function saveDismissed(ids: string[]) {
  // Keep only last 200 dismissed IDs to avoid unbounded growth
  const trimmed = ids.slice(-200);
  try { localStorage.setItem(DISMISSED_STORAGE_KEY, JSON.stringify(trimmed)); } catch { /* ignore */ }
}

/* ── Store instance ──────────────────────────────────────────────────────── */

export const useNotificationStore = create<NotificationStore>((set, get) => ({
  smartNotifications: [],
  dismissedIds:       loadDismissed(),
  lastCheckedAt:      null,
  claimedRewards:     loadClaimed(),

  addSmartNotification: (notif) => set((s) => {
    // Skip if already exists or has been dismissed
    if (s.smartNotifications.some((n) => n.id === notif.id)) return s;
    if (s.dismissedIds.includes(notif.id)) return s;
    return { smartNotifications: [notif, ...s.smartNotifications].slice(0, 30) };
  }),

  dismissSmartNotification: (id) => set((s) => {
    const dismissedIds = [...s.dismissedIds, id];
    saveDismissed(dismissedIds);
    return {
      smartNotifications: s.smartNotifications.filter((n) => n.id !== id),
      dismissedIds,
    };
  }),

  clearAllSmart: () => set((s) => {
    const ids = s.smartNotifications.map((n) => n.id);
    const dismissedIds = [...s.dismissedIds, ...ids];
    saveDismissed(dismissedIds);
    return { smartNotifications: [], dismissedIds };
  }),

  setLastChecked: (ts) => set({ lastCheckedAt: ts }),

  claimReward: (achievementId) => set((s) => {
    const claimedRewards = { ...s.claimedRewards, [achievementId]: new Date().toISOString() };
    saveClaimed(claimedRewards);
    return { claimedRewards };
  }),

  isRewardClaimed: (achievementId) => {
    return !!get().claimedRewards[achievementId];
  },
}));
