"use client";

import {
  createContext,
  useContext,
  useState,
  useEffect,
  useCallback,
  ReactNode,
} from "react";
import {
  getAllAnnouncements,
  markAnnouncementRead,
  getAnnouncementReadCount,
} from "@/lib/api/apis";
import { useLanguage } from "@/src/hooks/LanguageContext";

export interface Announcement {
  id: string;
  title: string;
  description: string;
  language?: string;
  status: string;
  created_at: string;
  is_read?: boolean;
}

interface AnnouncementContextType {
  announcements: Announcement[];
  unreadCount: number;
  totalCount: number;
  loading: boolean;
  markAsRead: (announcementIds: number[]) => Promise<void>;
  markAllAsRead: () => Promise<void>;
  refreshAnnouncements: () => Promise<void>;
}

const AnnouncementContext = createContext<AnnouncementContextType | undefined>(
  undefined,
);

export function AnnouncementProvider({ children }: { children: ReactNode }) {
  const { language } = useLanguage();
  const [announcements, setAnnouncements] = useState<Announcement[]>([]);
  const [unreadCount, setUnreadCount] = useState(0);
  const [totalCount, setTotalCount] = useState(0);
  const [loading, setLoading] = useState(true);
  const [userId, setUserId] = useState<string | null>(null);

  useEffect(() => {
    if (typeof window === "undefined") return;
    const data = localStorage.getItem("user_data");
    if (data) {
      const userData = JSON.parse(data);
      setUserId(userData?.id || null);
    }
  }, []);

  const refreshAnnouncements = useCallback(async () => {
    if (!userId) {
      setLoading(false);
      return;
    }

    try {
      setLoading(true);

      // Fetch announcements and read count in parallel
      const [announcementsRes, readCountRes] = await Promise.all([
        getAllAnnouncements(language),
        getAnnouncementReadCount(userId, language),
      ]);

      if (announcementsRes?.data) {
        const activeAnnouncements = (
          Array.isArray(announcementsRes.data)
            ? announcementsRes.data
            : announcementsRes.data.announcements || []
        )
          .filter((a: Announcement) => a.status === "1")
          .sort(
            (a: Announcement, b: Announcement) =>
              new Date(b.created_at).getTime() - new Date(a.created_at).getTime(),
          );

        setTotalCount(activeAnnouncements.length);

        // Get read announcement IDs from the read count API
        const readIds = readCountRes?.data?.read_announcement_ids || [];

        // Mark announcements as read/unread based on API data
        const announcementsWithReadStatus = activeAnnouncements.map((a: Announcement) => ({
          ...a,
          is_read: readIds.includes(Number(a.id)),
        }));

        setAnnouncements(announcementsWithReadStatus);
      }

      if (readCountRes?.data) {
        setUnreadCount(readCountRes.data.unread_count || 0);
      }
    } catch (error) {
      console.error("Error fetching announcements:", error);
    } finally {
      setLoading(false);
    }
  }, [userId, language]);

  useEffect(() => {
    if (userId) {
      refreshAnnouncements();
    }
  }, [userId, language, refreshAnnouncements]);

  const markAsRead = useCallback(
    async (announcementIds: number[]) => {
      if (!userId || announcementIds.length === 0) return;

      try {
        await markAnnouncementRead(userId, announcementIds);

        // Update local state
        setAnnouncements((prev) =>
          prev.map((a) =>
            announcementIds.includes(Number(a.id))
              ? { ...a, is_read: true }
              : a,
          ),
        );

        // Refresh read count
        const readCountRes = await getAnnouncementReadCount(userId, language);
        if (readCountRes?.data) {
          setUnreadCount(readCountRes.data.unread_count || 0);
        }
      } catch (error) {
        console.error("Error marking announcements as read:", error);
      }
    },
    [userId, language],
  );

  const markAllAsRead = useCallback(async () => {
    const unreadIds = announcements
      .filter((a) => !a.is_read)
      .map((a) => Number(a.id));

    if (unreadIds.length > 0) {
      await markAsRead(unreadIds);
    }
  }, [announcements, markAsRead]);

  return (
    <AnnouncementContext.Provider
      value={{
        announcements,
        unreadCount,
        totalCount,
        loading,
        markAsRead,
        markAllAsRead,
        refreshAnnouncements,
      }}
    >
      {children}
    </AnnouncementContext.Provider>
  );
}

export function useAnnouncements() {
  const context = useContext(AnnouncementContext);
  if (context === undefined) {
    throw new Error(
      "useAnnouncements must be used within an AnnouncementProvider",
    );
  }
  return context;
}
