import { atom } from "recoil";
import { syncEffect } from "recoil-sync";
import { number, string, array, object, union, literal, nullable, optional } from "@recoiljs/refine";
import { WallpaperHistoryEntry, WallpaperMetadata } from "@/types/wallpaper";
import { WallpaperMode } from "@/types/wallpaperModes";
import { STORE_MESSAGES } from "@/ipc/channels/messages";

// Import the update atoms
export * from "../state/atoms/updateAtoms";

// Types
export interface WallpaperData {
  objectKey: string;
  upscaledImageUrl: string | null;
  originalImageUrl: string;
  style: string;
  generatedAt: string;
  metadata?: WallpaperMetadata;
}

export interface SchedulerState {
  isActive: boolean;
  intervalMinutes: number | null;
  nextChangeCountdown: string;
}

// Type checkers
const locationChecker = object({
  city: string(),
  state: string(),
  country: string(),
  temperature: number(),
  local_time: string(),
});

const wallpaperMetadataChecker = object({
  style: string(),
  created_at: string(),
  prompt: nullable(string()),
  original_prompt: nullable(string()),
  custom_style: nullable(string()),
  location: nullable(locationChecker),
  upscaled: nullable(union(literal(true), literal(false))),
  upscale_date: nullable(string()),
});

const wallpaperDataChecker = object({
  objectKey: string(),
  upscaledImageUrl: nullable(string()),
  originalImageUrl: string(),
  style: string(),
  generatedAt: string(),
  metadata: nullable(wallpaperMetadataChecker),
});

const schedulerStateChecker = object({
  isActive: union(literal(true), literal(false)),
  intervalMinutes: nullable(number()),
  nextChangeCountdown: string(),
});

const stringArrayChecker = array(string());

const wallpaperHistoryEntryChecker = object({
  key: string(),
  upscaledImageUrl: string(),
  originalImageUrl: string(),
  imageUrl: optional(string()),
  setAt: string(),
  metadata: optional(nullable(wallpaperMetadataChecker)),
  isUpscaled: optional(union(literal(true), literal(false))),
});

// Atoms
export const lastWallpaperState = atom<WallpaperData | null>({
  key: "lastWallpaperState",
  default: null,
  effects: [
    syncEffect({
      storeKey: "electron-store",
      itemKey: STORE_MESSAGES.OPERATIONS.LAST_WALLPAPER,
      refine: nullable(wallpaperDataChecker),
    }),
  ],
});

export const wallpaperHistoryState = atom<readonly WallpaperHistoryEntry[]>({
  key: "wallpaperHistoryState",
  default: [],
  effects: [
    syncEffect({
      storeKey: "electron-store",
      itemKey: STORE_MESSAGES.OPERATIONS.WALLPAPER_HISTORY,
      refine: array(wallpaperHistoryEntryChecker),
    }),
  ],
});

export const schedulerState = atom<SchedulerState>({
  key: "schedulerState",
  default: {
    isActive: false,
    intervalMinutes: null,
    nextChangeCountdown: "",
  },
  effects: [
    syncEffect({
      storeKey: "electron-store",
      itemKey: STORE_MESSAGES.OPERATIONS.SCHEDULER_ACTIVE,
      refine: schedulerStateChecker,
    }),
  ],
});

export const expandedCategoriesState = atom<string[]>({
  key: "expandedCategoriesState",
  default: [],
  effects: [
    syncEffect({
      storeKey: "electron-store",
      itemKey: STORE_MESSAGES.OPERATIONS.EXPANDED_CATEGORIES,
      refine: stringArrayChecker,
    }),
  ],
});

export const activeStylesState = atom<string[]>({
  key: "activeStylesState",
  default: [],
  effects: [
    syncEffect({
      storeKey: "electron-store",
      itemKey: STORE_MESSAGES.OPERATIONS.ACTIVE_STYLES,
      refine: stringArrayChecker,
    }),
  ],
});

export const customStyleState = atom<string>({
  key: "customStyleState",
  default: "",
  effects: [
    syncEffect({
      storeKey: "electron-store",
      itemKey: STORE_MESSAGES.OPERATIONS.CUSTOM_STYLE,
      refine: string(),
    }),
  ],
});

export const currentWallpaperModeState = atom<WallpaperMode>({
  key: "currentWallpaperModeState",
  default: "RandomStyleSelection",
  effects: [
    syncEffect({
      storeKey: "electron-store",
      itemKey: STORE_MESSAGES.OPERATIONS.CURRENT_MODE,
      refine: union(literal("RandomStyleSelection"), literal("CustomStyle"), literal("Location"), literal("Mood")),
    }),
  ],
});
