/**
 * Tests for useSocialData hook — disconnectAccount
 *
 * Verifies the disconnect function calls DELETE with CSRF,
 * removes the account from local state on success,
 * and sets error on failure.
 */

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

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

// Mock global fetch for the GET endpoints
const mockFetch = jest.fn();
global.fetch = mockFetch;

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

import { renderHook, act } from "@testing-library/react";
import { useSocialData } from "@/app/[lang]/dashboard/components/social-media/useSocialData";

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

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

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

describe("useSocialData — disconnectAccount", () => {
  beforeEach(() => {
    jest.clearAllMocks();
    // Default: all GETs return empty data
    mockFetch.mockResolvedValue(makeResponse({ data: [] }));
    // Default: POST sync returns ok
    mockFetchWithCSRF.mockResolvedValue(makeResponse({ success: true }));
  });

  it("calls fetchWithCSRF with DELETE method", async () => {
    mockFetchWithCSRF.mockResolvedValue(
      makeResponse({ success: true, message: "Account disconnected" }),
    );

    // Seed accounts via the initial fetch
    mockFetch.mockImplementation((url: string) => {
      if (url === "/api/social/accounts") {
        return Promise.resolve(
          makeResponse({
            data: [{ id: "acc-1", platform: "FACEBOOK", accountName: "Page" }],
          }),
        );
      }
      return Promise.resolve(makeResponse({ data: [] }));
    });

    const { result } = renderHook(() => useSocialData());

    // Wait for initial loads
    await act(async () => {
      await new Promise((r) => setTimeout(r, 50));
    });

    expect(result.current.accounts).toHaveLength(1);

    // Reset to track only disconnect call
    mockFetchWithCSRF.mockClear();
    mockFetchWithCSRF.mockResolvedValueOnce(
      makeResponse({ success: true, message: "Account disconnected" }),
    );

    await act(async () => {
      await result.current.disconnectAccount("acc-1");
    });

    expect(mockFetchWithCSRF).toHaveBeenCalledWith(
      "/api/social/accounts/acc-1",
      { method: "DELETE" },
    );
  });

  it("removes account from state on successful disconnect", async () => {
    mockFetch.mockImplementation((url: string) => {
      if (url === "/api/social/accounts") {
        return Promise.resolve(
          makeResponse({
            data: [
              { id: "acc-1", platform: "FACEBOOK", accountName: "Page 1" },
              { id: "acc-2", platform: "INSTAGRAM", accountName: "Page 2" },
            ],
          }),
        );
      }
      return Promise.resolve(makeResponse({ data: [] }));
    });

    const { result } = renderHook(() => useSocialData());
    await act(async () => {
      await new Promise((r) => setTimeout(r, 50));
    });

    expect(result.current.accounts).toHaveLength(2);

    mockFetchWithCSRF.mockClear();
    mockFetchWithCSRF.mockResolvedValueOnce(makeResponse({ success: true }));

    await act(async () => {
      await result.current.disconnectAccount("acc-1");
    });

    expect(result.current.accounts).toHaveLength(1);
    expect(result.current.accounts[0].id).toBe("acc-2");
  });

  it("sets error on failed disconnect", async () => {
    mockFetch.mockImplementation((url: string) => {
      if (url === "/api/social/accounts") {
        return Promise.resolve(
          makeResponse({
            data: [{ id: "acc-1", platform: "FACEBOOK", accountName: "Page" }],
          }),
        );
      }
      return Promise.resolve(makeResponse({ data: [] }));
    });

    const { result } = renderHook(() => useSocialData());
    await act(async () => {
      await new Promise((r) => setTimeout(r, 50));
    });

    mockFetchWithCSRF.mockClear();
    mockFetchWithCSRF.mockResolvedValueOnce(
      makeResponse({ success: false, error: "Not found" }, 404),
    );

    await act(async () => {
      await result.current.disconnectAccount("acc-1");
    });

    // Account should still be there (not removed on failure)
    expect(result.current.accounts).toHaveLength(1);
    expect(result.current.errors.disconnect).toBe("Not found");
  });

  it("sets generic error on network failure", async () => {
    mockFetch.mockImplementation((url: string) => {
      if (url === "/api/social/accounts") {
        return Promise.resolve(
          makeResponse({
            data: [{ id: "acc-1", platform: "FACEBOOK", accountName: "Page" }],
          }),
        );
      }
      return Promise.resolve(makeResponse({ data: [] }));
    });

    const { result } = renderHook(() => useSocialData());
    await act(async () => {
      await new Promise((r) => setTimeout(r, 50));
    });

    mockFetchWithCSRF.mockClear();
    mockFetchWithCSRF.mockRejectedValueOnce(new Error("Network error"));

    await act(async () => {
      await result.current.disconnectAccount("acc-1");
    });

    expect(result.current.errors.disconnect).toBe(
      "Failed to disconnect account",
    );
  });
});
