/**
 * Tests for SocialMediaPanel connect/disconnect flows
 *
 * Verifies:
 * - Connect Facebook uses fetchWithCSRF (not raw fetch)
 * - 401/503 errors show appropriate messages
 * - Disconnect button calls DELETE with CSRF and removes account from UI
 * - Network errors are handled gracefully
 */

// ── Mocks (before imports) ──────────────────────────────────────────────

const mockFetchWithCSRF = jest.fn();
jest.mock("@/lib/csrf-client", () => ({
  fetchWithCSRF: (...args: unknown[]) => mockFetchWithCSRF(...args),
}));

const mockUseSocialData = jest.fn();
jest.mock(
  "@/app/[lang]/dashboard/components/social-media/useSocialData",
  () => ({
    useSocialData: () => mockUseSocialData(),
  }),
);

jest.mock(
  "@/app/[lang]/dashboard/components/social-media/InboxView",
  () =>
    function InboxView() {
      return <div data-testid="inbox-view" />;
    },
);
jest.mock(
  "@/app/[lang]/dashboard/components/social-media/AIAssistantView",
  () =>
    function AIAssistantView() {
      return <div data-testid="ai-view" />;
    },
);
jest.mock(
  "@/app/[lang]/dashboard/components/social-media/TrendsView",
  () =>
    function TrendsView() {
      return <div data-testid="trends-view" />;
    },
);
jest.mock(
  "@/app/[lang]/dashboard/components/social-media/CalendarView",
  () =>
    function CalendarView() {
      return <div data-testid="calendar-view" />;
    },
);

// ── Imports ─────────────────────────────────────────────────────────────

import React from "react";
import {
  render,
  screen,
  fireEvent,
  waitFor,
  act,
} from "@testing-library/react";
import SocialMediaPanel from "@/app/[lang]/dashboard/components/social-media/SocialMediaPanel";

// ── Helpers ─────────────────────────────────────────────────────────────

function makeResponse(body: object, status = 200): Response {
  return new Response(JSON.stringify(body), {
    status,
    headers: { "Content-Type": "application/json" },
  });
}

const defaultSocialData = {
  accounts: [],
  accountsLoading: false,
  conversations: [],
  unreadCounts: null,
  inboxLoading: false,
  trends: [],
  postIdeas: [],
  bestTimes: [],
  trendsLoading: false,
  calendarEvents: [],
  calendarLoading: false,
  errors: {},
  clearErrors: jest.fn(),
  refreshAccounts: jest.fn(),
  refreshInbox: jest.fn(),
  refreshTrends: jest.fn(),
  refreshCalendar: jest.fn(),
  disconnectAccount: jest.fn(),
};

const connectedAccount = {
  id: "acc-1",
  userId: "user-1",
  platform: "FACEBOOK",
  platformAccountId: "fb-123",
  accountName: "My Business Page",
  status: "CONNECTED",
  tokenExpiry: null,
  metadata: null,
};

// ── Tests ───────────────────────────────────────────────────────────────

describe("SocialMediaPanel", () => {
  beforeEach(() => {
    jest.clearAllMocks();
    mockUseSocialData.mockReturnValue(defaultSocialData);
  });

  describe("ConnectAccountsPrompt (no accounts)", () => {
    it("renders connect button when no accounts exist", () => {
      render(<SocialMediaPanel lang="en" hasAccess />);
      expect(screen.getByText("Connect Facebook")).toBeInTheDocument();
    });

    it("uses fetchWithCSRF for Facebook authorize request", async () => {
      mockFetchWithCSRF.mockResolvedValueOnce(
        makeResponse({
          success: true,
          data: { url: "https://facebook.com/oauth" },
        }),
      );

      render(<SocialMediaPanel lang="en" hasAccess />);
      await act(async () => {
        fireEvent.click(screen.getByText("Connect Facebook"));
      });

      expect(mockFetchWithCSRF).toHaveBeenCalledWith(
        "/api/social/auth/facebook/authorize",
        { method: "POST" },
      );
    });

    it("shows session expired on 401", async () => {
      mockFetchWithCSRF.mockResolvedValueOnce(
        makeResponse({ error: "Unauthorized" }, 401),
      );

      render(<SocialMediaPanel lang="en" hasAccess />);
      await act(async () => {
        fireEvent.click(screen.getByText("Connect Facebook"));
      });

      await waitFor(() => {
        expect(
          screen.getByText(
            "Session expired. Please refresh the page and try again.",
          ),
        ).toBeInTheDocument();
      });
    });

    it("shows service unavailable on 503", async () => {
      mockFetchWithCSRF.mockResolvedValueOnce(
        makeResponse({ error: "Unavailable" }, 503),
      );

      render(<SocialMediaPanel lang="en" hasAccess />);
      await act(async () => {
        fireEvent.click(screen.getByText("Connect Facebook"));
      });

      await waitFor(() => {
        expect(
          screen.getByText(
            "Facebook integration is temporarily unavailable. Please try again later.",
          ),
        ).toBeInTheDocument();
      });
    });

    it("shows network error on fetch failure", async () => {
      mockFetchWithCSRF.mockRejectedValueOnce(new Error("Network error"));

      render(<SocialMediaPanel lang="en" hasAccess />);
      await act(async () => {
        fireEvent.click(screen.getByText("Connect Facebook"));
      });

      await waitFor(() => {
        expect(
          screen.getByText("Network error. Please try again."),
        ).toBeInTheDocument();
      });
    });

    it("shows server error message from response body", async () => {
      mockFetchWithCSRF.mockResolvedValueOnce(
        makeResponse({ success: false, error: "App not configured" }, 200),
      );

      render(<SocialMediaPanel lang="en" hasAccess />);
      await act(async () => {
        fireEvent.click(screen.getByText("Connect Facebook"));
      });

      await waitFor(() => {
        expect(screen.getByText("App not configured")).toBeInTheDocument();
      });
    });

    it("renders Arabic connect prompt when lang=ar", () => {
      render(<SocialMediaPanel lang="ar" hasAccess />);
      expect(screen.getByText("ربط فيسبوك")).toBeInTheDocument();
    });
  });

  describe("ConnectedAccountsHeader (with accounts)", () => {
    beforeEach(() => {
      mockUseSocialData.mockReturnValue({
        ...defaultSocialData,
        accounts: [connectedAccount],
      });
    });

    it("renders connected account name and platform", () => {
      render(<SocialMediaPanel lang="en" hasAccess />);
      expect(screen.getByText("My Business Page")).toBeInTheDocument();
      expect(screen.getByText("FACEBOOK")).toBeInTheDocument();
    });

    it("calls disconnectAccount on disconnect button click", async () => {
      const mockDisconnect = jest.fn().mockResolvedValue(undefined);
      mockUseSocialData.mockReturnValue({
        ...defaultSocialData,
        accounts: [connectedAccount],
        disconnectAccount: mockDisconnect,
      });

      render(<SocialMediaPanel lang="en" hasAccess />);

      const disconnectBtn = screen.getByTitle("Disconnect account");
      await act(async () => {
        fireEvent.click(disconnectBtn);
      });

      expect(mockDisconnect).toHaveBeenCalledWith("acc-1");
    });

    it("renders Arabic disconnect title when lang=ar", () => {
      render(<SocialMediaPanel lang="ar" hasAccess />);
      expect(screen.getByTitle("فصل الحساب")).toBeInTheDocument();
    });

    it("renders multiple connected accounts", () => {
      const igAccount = {
        ...connectedAccount,
        id: "acc-2",
        platform: "INSTAGRAM",
        accountName: "@mybiz",
      };
      mockUseSocialData.mockReturnValue({
        ...defaultSocialData,
        accounts: [connectedAccount, igAccount],
      });

      render(<SocialMediaPanel lang="en" hasAccess />);
      expect(screen.getByText("My Business Page")).toBeInTheDocument();
      expect(screen.getByText("@mybiz")).toBeInTheDocument();
    });
  });

  describe("UpgradePrompt (no access)", () => {
    it("shows upgrade prompt when hasAccess is false", () => {
      render(<SocialMediaPanel lang="en" hasAccess={false} />);
      expect(
        screen.getByText("Social Media Available on Enterprise Plan"),
      ).toBeInTheDocument();
    });
  });
});
