import {
  createContext,
  ReactNode,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import AsyncStorage from "@react-native-async-storage/async-storage";

import { syncBirthdayNotifications } from "@/utils/birthday-notifications";
export interface BirthdayEntry {
  id: string;
  name: string;
  date: string;
}

interface AddBirthdayInput {
  name: string;
  date: string;
}

interface BirthdaysContextValue {
  birthdays: BirthdayEntry[];
  addBirthday: (input: AddBirthdayInput) => void;
  deleteBirthday: (id: string) => void;
}

const STORAGE_KEY = "birthdays";

const BirthdaysContext = createContext<BirthdaysContextValue | undefined>(
  undefined
);

export function BirthdaysProvider({ children }: { children: ReactNode }) {
  const [birthdays, setBirthdays] = useState<BirthdayEntry[]>([]);
  const [isLoaded, setIsLoaded] = useState(false);

  // Load birthdays on app start from storage
  useEffect(() => {
    const loadBirthdays = async () => {
      try {
        const stored = await AsyncStorage.getItem(STORAGE_KEY);
        if (stored) {
          setBirthdays(JSON.parse(stored));
        }
      } catch(e) {
        console.log("Error loading birthdays", e);
      } finally {
        setIsLoaded(true);
      }
    };

    loadBirthdays();
  }, []);

  // Save birthdays whenever they change
  useEffect(() => {
    if (!isLoaded) return;

    const saveBirthdays = async () => {
      try {
        await AsyncStorage.setItem(
          STORAGE_KEY,
          JSON.stringify(birthdays)
        );
      } catch(e) {
        console.log("Error saving birthdays", e);
      }
    };

    saveBirthdays();
  }, [birthdays, isLoaded]);

  useEffect(() => {
    if (!isLoaded) {
      return;
    }

    const synchronizeNotifications = async () => {
      try {
        await syncBirthdayNotifications(birthdays);
      } catch (error) {
        console.log("Error syncing birthday notifications", error);
      }
    };

    synchronizeNotifications();
  }, [birthdays, isLoaded]);

  const value = useMemo(
    () => ({
      birthdays,
      addBirthday: ({ name, date }: AddBirthdayInput) => {
        const trimmedName = name.trim();

        if (!trimmedName) {
          return;
        }

        setBirthdays((currentBirthdays) => [
          ...currentBirthdays,
          {
            id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
            name: trimmedName,
            date,
          },
        ]);
      },
      deleteBirthday: (id: string) => {
        setBirthdays((currentBirthdays) =>
          currentBirthdays.filter((birthday) => birthday.id !== id)
        );
      },
    }),
    [birthdays]
  );

  return (
    <BirthdaysContext.Provider value={value}>
      {children}
    </BirthdaysContext.Provider>
  );
}

export function useBirthdays() {
  const context = useContext(BirthdaysContext);

  if (!context) {
    throw new Error("useBirthdays must be used within a BirthdaysProvider");
  }

  return context;
}
