"use client";

import { useState, useCallback, useEffect } from "react";
import type {
  InboxConversation,
  UnreadCounts,
  SocialTrendOutput,
  CalendarEvent,
  BestTimeSlot,
  PostIdea,
} from "@/lib/types/social-media.types";
import type { SocialAccountOutput } from "@/lib/types/social-media.types";
import { fetchWithCSRF } from "@/lib/csrf-client";

interface UseSocialDataReturn {
  // Accounts
  accounts: SocialAccountOutput[];
  accountsLoading: boolean;
  // Inbox
  conversations: InboxConversation[];
  unreadCounts: UnreadCounts | null;
  inboxLoading: boolean;
  // Trends
  trends: SocialTrendOutput[];
  postIdeas: PostIdea[];
  bestTimes: BestTimeSlot[];
  trendsLoading: boolean;
  // Calendar
  calendarEvents: CalendarEvent[];
  calendarLoading: boolean;
  // Errors
  errors: Record<string, string>;
  clearErrors: () => void;
  // Actions
  refreshAccounts: () => Promise<void>;
  refreshInbox: () => Promise<void>;
  refreshTrends: () => Promise<void>;
  refreshCalendar: (month?: number, year?: number) => Promise<void>;
  disconnectAccount: (id: string) => Promise<void>;
}

export function useSocialData(): UseSocialDataReturn {
  const [accounts, setAccounts] = useState<SocialAccountOutput[]>([]);
  const [accountsLoading, setAccountsLoading] = useState(true);

  const [conversations, setConversations] = useState<InboxConversation[]>([]);
  const [unreadCounts, setUnreadCounts] = useState<UnreadCounts | null>(null);
  const [inboxLoading, setInboxLoading] = useState(true);

  const [trends, setTrends] = useState<SocialTrendOutput[]>([]);
  const [postIdeas, setPostIdeas] = useState<PostIdea[]>([]);
  const [bestTimes, setBestTimes] = useState<BestTimeSlot[]>([]);
  const [trendsLoading, setTrendsLoading] = useState(true);

  const [calendarEvents, setCalendarEvents] = useState<CalendarEvent[]>([]);
  const [calendarLoading, setCalendarLoading] = useState(true);

  const [errors, setErrors] = useState<Record<string, string>>({});
  const clearErrors = useCallback(() => setErrors({}), []);

  const refreshAccounts = useCallback(async () => {
    setAccountsLoading(true);
    try {
      const res = await fetch("/api/social/accounts");
      if (res.ok) {
        setErrors((prev) => {
          const { accounts: _, ...rest } = prev;
          return rest;
        });
        const json = await res.json();
        setAccounts(json.data || []);
      } else {
        setErrors((prev) => ({ ...prev, accounts: "Failed to load accounts" }));
      }
    } catch {
      setErrors((prev) => ({ ...prev, accounts: "Failed to load accounts" }));
    } finally {
      setAccountsLoading(false);
    }
  }, []);

  const refreshInbox = useCallback(async () => {
    setInboxLoading(true);
    try {
      // Pull the latest Meta (Facebook/Instagram) messages before reading local inbox data.
      try {
        await fetchWithCSRF("/api/social/inbox/sync", {
          method: "POST",
        });
      } catch {
        // Fall back to cached/local data if sync fails.
      }

      const [convRes, countRes] = await Promise.all([
        fetch("/api/social/inbox"),
        fetch("/api/social/inbox/unread-counts"),
      ]);
      if (convRes.ok) {
        setErrors((prev) => {
          const { inbox: _, ...rest } = prev;
          return rest;
        });
        const json = await convRes.json();
        setConversations(json.data || []);
      } else {
        setErrors((prev) => ({ ...prev, inbox: "Failed to load inbox" }));
      }
      if (countRes.ok) {
        const json = await countRes.json();
        setUnreadCounts(json.data || null);
      }
    } catch {
      setErrors((prev) => ({ ...prev, inbox: "Failed to load inbox" }));
    } finally {
      setInboxLoading(false);
    }
  }, []);

  const refreshTrends = useCallback(async () => {
    setTrendsLoading(true);
    try {
      const [trendsRes, ideasRes, timesRes] = await Promise.all([
        fetch("/api/social/trends"),
        fetch("/api/social/trends/post-ideas"),
        fetch("/api/social/trends/best-times"),
      ]);
      if (trendsRes.ok) {
        setErrors((prev) => {
          const { trends: _, ...rest } = prev;
          return rest;
        });
        const json = await trendsRes.json();
        setTrends(json.data || []);
      } else {
        setErrors((prev) => ({ ...prev, trends: "Failed to load trends" }));
      }
      if (ideasRes.ok) {
        const json = await ideasRes.json();
        setPostIdeas(json.data || []);
      }
      if (timesRes.ok) {
        const json = await timesRes.json();
        setBestTimes(json.data || []);
      }
    } catch {
      setErrors((prev) => ({ ...prev, trends: "Failed to load trends" }));
    } finally {
      setTrendsLoading(false);
    }
  }, []);

  const refreshCalendar = useCallback(async (month?: number, year?: number) => {
    setCalendarLoading(true);
    try {
      const params = new URLSearchParams();
      if (month) params.set("month", String(month));
      if (year) params.set("year", String(year));
      const res = await fetch(`/api/social/calendar?${params}`);
      if (res.ok) {
        setErrors((prev) => {
          const { calendar: _, ...rest } = prev;
          return rest;
        });
        const json = await res.json();
        setCalendarEvents(json.data || []);
      } else {
        setErrors((prev) => ({ ...prev, calendar: "Failed to load calendar" }));
      }
    } catch {
      setErrors((prev) => ({ ...prev, calendar: "Failed to load calendar" }));
    } finally {
      setCalendarLoading(false);
    }
  }, []);

  const disconnectAccount = useCallback(async (id: string) => {
    try {
      const res = await fetchWithCSRF(`/api/social/accounts/${id}`, {
        method: "DELETE",
      });
      if (res.ok) {
        setAccounts((prev) => prev.filter((a) => a.id !== id));
        setErrors((prev) => {
          const { disconnect: _, ...rest } = prev;
          return rest;
        });
      } else {
        const json = await res.json().catch(() => null);
        setErrors((prev) => ({
          ...prev,
          disconnect: json?.error || "Failed to disconnect account",
        }));
      }
    } catch {
      setErrors((prev) => ({
        ...prev,
        disconnect: "Failed to disconnect account",
      }));
    }
  }, []);

  useEffect(() => {
    refreshAccounts();
    refreshInbox();
    refreshTrends();
    refreshCalendar();
  }, [refreshAccounts, refreshInbox, refreshTrends, refreshCalendar]);

  return {
    accounts,
    accountsLoading,
    conversations,
    unreadCounts,
    inboxLoading,
    trends,
    postIdeas,
    bestTimes,
    trendsLoading,
    calendarEvents,
    calendarLoading,
    errors,
    clearErrors,
    refreshAccounts,
    refreshInbox,
    refreshTrends,
    refreshCalendar,
    disconnectAccount,
  };
}
