import { describe, it, expect, beforeEach, vi } from "vitest";
import { render, waitFor } from "@testing-library/react";
import React from "react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { CmsProvider } from "@/lib/providers/cms-provider";
import { setCmsCache, resolveGlobal, type CmsField } from "@/lib/hooks/use-translation";
import { useAuthStore } from "@/lib/store/auth-store";

// vi.mock factory must not reference outer variables — use inline object
vi.mock("@/lib/api/client", () => ({
  publicApi: {
    cmsBulk: vi.fn().mockResolvedValue({
      data: {
        TOAST: [
          {
            id: 1, section: "TOAST", groupKey: "auth", fieldKey: "login_success",
            titleHi: "", titleEn: "", valueHi: "लॉगिन सफल", valueEn: "Login successful",
            fieldType: "text", sortOrder: 1,
          },
        ],
        COMMON: [
          {
            id: 2, section: "COMMON", groupKey: "buttons", fieldKey: "save",
            titleHi: "", titleEn: "", valueHi: "सहेजें", valueEn: "Save",
            fieldType: "text", sortOrder: 1,
          },
        ],
      },
    }),
  },
}));

function createWrapper() {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false } },
  });
  return function Wrapper({ children }: { children: React.ReactNode }) {
    return (
      <QueryClientProvider client={queryClient}>
        {children}
      </QueryClientProvider>
    );
  };
}

describe("CmsProvider", () => {
  beforeEach(() => {
    useAuthStore.setState({ language: "en" });
    // Reset global cache
    setCmsCache({}, "en");
    vi.clearAllMocks();
  });

  it("renders children", () => {
    const Wrapper = createWrapper();
    const { getByText } = render(
      <Wrapper>
        <CmsProvider>
          <div>Hello</div>
        </CmsProvider>
      </Wrapper>
    );
    expect(getByText("Hello")).toBeTruthy();
  });

  it("populates global cache after data loads", async () => {
    const Wrapper = createWrapper();
    render(
      <Wrapper>
        <CmsProvider>
          <div>Test</div>
        </CmsProvider>
      </Wrapper>
    );

    // Wait for the query to resolve and useEffect to run
    await waitFor(() => {
      const result = resolveGlobal("TOAST", "auth", "login_success", "fallback");
      expect(result).toBe("Login successful");
    });
  });

  it("resolves COMMON section from global cache", async () => {
    const Wrapper = createWrapper();
    render(
      <Wrapper>
        <CmsProvider>
          <div>Test</div>
        </CmsProvider>
      </Wrapper>
    );

    await waitFor(() => {
      const result = resolveGlobal("COMMON", "buttons", "save", "fallback");
      expect(result).toBe("Save");
    });
  });

  it("respects language setting for Hindi", async () => {
    useAuthStore.setState({ language: "hi" });
    const Wrapper = createWrapper();
    render(
      <Wrapper>
        <CmsProvider>
          <div>Test</div>
        </CmsProvider>
      </Wrapper>
    );

    await waitFor(() => {
      const result = resolveGlobal("TOAST", "auth", "login_success", "fallback");
      expect(result).toBe("लॉगिन सफल");
    });
  });

  it("returns fallback for missing keys", async () => {
    const Wrapper = createWrapper();
    render(
      <Wrapper>
        <CmsProvider>
          <div>Test</div>
        </CmsProvider>
      </Wrapper>
    );

    await waitFor(() => {
      const result = resolveGlobal("TOAST", "auth", "login_success", "fallback");
      expect(result).toBe("Login successful");
    });

    // This key doesn't exist in CMS or static JSON
    const missing = resolveGlobal("UNKNOWN", "x", "y", "my fallback");
    expect(missing).toBe("my fallback");
  });
});
