import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import type React from "react";
import { MemoryRouter, Route, Routes } from "react-router-dom";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { createI18nMock } from "../../test/i18nMock";
import { TenantAdminsAndOwnersTab } from "../tenants/routes/TenantAdminsAndOwnersTab";
import TenantUserGroupsTab from "../user-groups/routes/TenantUserGroupsTab";

const exportUsersCSVMock = vi.hoisted(() =>
  vi.fn(async () => ({
    blob: new Blob(["email,name\nmember@example.com,Member User\n"], {
      type: "text/csv",
    }),
    filename: "users_export_20260609.csv",
  })),
);
const bulkUpdateUsersMock = vi.hoisted(() => vi.fn(async () => ({ results: [] })));

const tenants = [
  {
    id: "tenant-root",
    type: "COMPANY_GROUP",
    name: "한맥 가족",
    slug: "hanmac-family",
    description: "",
    status: "active",
    memberCount: 0,
    createdAt: "2026-05-01T00:00:00Z",
    updatedAt: "2026-05-01T00:00:00Z",
  },
  {
    id: "tenant-company",
    type: "COMPANY",
    parentId: "tenant-root",
    name: "GPDTDC",
    slug: "gpdtdc",
    description: "",
    status: "active",
    memberCount: 2,
    createdAt: "2026-05-01T00:00:00Z",
    updatedAt: "2026-05-01T00:00:00Z",
  },
  {
    id: "tenant-leaf",
    type: "ORGANIZATION",
    parentId: "tenant-company",
    name: "기술연구팀",
    slug: "gpdtdc-rnd",
    description: "",
    status: "active",
    memberCount: 1,
    createdAt: "2026-05-01T00:00:00Z",
    updatedAt: "2026-05-01T00:00:00Z",
  },
];

const users = [
  {
    id: "user-owner",
    name: "Owner User",
    email: "owner@example.com",
    role: "tenant_admin",
    status: "active",
  },
  {
    id: "user-admin",
    name: "Admin User",
    email: "admin@example.com",
    role: "tenant_admin",
    status: "active",
  },
  {
    id: "user-member",
    name: "Member User",
    email: "member@example.com",
    role: "user",
    status: "active",
    tenantSlug: "gpdtdc-rnd",
    tenant: tenants[2],
  },
];

vi.mock("../../lib/i18n", () => createI18nMock());

vi.mock("react-oidc-context", () => ({
  useAuth: () => ({
    user: {
      profile: {
        sub: "admin-1",
      },
    },
  }),
}));

vi.mock("../../lib/adminApi", () => ({
  fetchTenantOwners: vi.fn(async () => [users[0]]),
  fetchTenantAdmins: vi.fn(async () => [users[1]]),
  addTenantOwner: vi.fn(async () => undefined),
  addTenantAdmin: vi.fn(async () => undefined),
  removeTenantOwner: vi.fn(async () => undefined),
  removeTenantAdmin: vi.fn(async () => undefined),
  fetchUsers: vi.fn(async () => ({
    items: users,
    total: users.length,
  })),
  fetchAllTenants: vi.fn(async () => ({
    items: tenants,
    total: tenants.length,
  })),
  updateTenant: vi.fn(async () => tenants[2]),
  updateUser: vi.fn(async () => users[2]),
  bulkUpdateUsers: bulkUpdateUsersMock,
  exportTenantsCSV: vi.fn(async () => ({
    blob: new Blob(["name,slug"]),
    filename: "tenants.csv",
  })),
  exportUsersCSV: exportUsersCSVMock,
}));

function renderWithProviders(ui: React.ReactElement, entry: string) {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: { retry: false },
      mutations: { retry: false },
    },
  });

  return render(
    <QueryClientProvider client={queryClient}>
      <MemoryRouter initialEntries={[entry]}>{ui}</MemoryRouter>
    </QueryClientProvider>,
  );
}

describe("admin tenant tab coverage smoke", () => {
  beforeEach(() => {
    vi.clearAllMocks();
    vi.spyOn(window, "confirm").mockReturnValue(true);
    vi.spyOn(window.URL, "createObjectURL").mockReturnValue(
      "blob:tenant-users-export",
    );
    vi.spyOn(window.URL, "revokeObjectURL").mockImplementation(() => {});
  });

  it("renders tenant owners and admins lists", async () => {
    renderWithProviders(
      <Routes>
        <Route
          path="/tenants/:tenantId/permissions"
          element={<TenantAdminsAndOwnersTab />}
        />
      </Routes>,
      "/tenants/tenant-company/permissions",
    );

    expect(await screen.findByText("Owner User")).toBeInTheDocument();
    expect(screen.getByText("Admin User")).toBeInTheDocument();
    expect(screen.getByText("owner@example.com")).toBeInTheDocument();
    expect(screen.getByText("admin@example.com")).toBeInTheDocument();
  });

  it("renders tenant hierarchy and selected organization members", async () => {
    renderWithProviders(
      <Routes>
        <Route
          path="/tenants/:tenantId/organization"
          element={<TenantUserGroupsTab />}
        />
      </Routes>,
      "/tenants/tenant-company/organization",
    );

    expect((await screen.findAllByText("GPDTDC")).length).toBeGreaterThan(0);
    expect(screen.getAllByText("기술연구팀").length).toBeGreaterThan(0);
    expect(await screen.findByText("Member User")).toBeInTheDocument();
  });

  it("exports selected organization users by tenant slug", async () => {
    renderWithProviders(
      <Routes>
        <Route
          path="/tenants/:tenantId/organization"
          element={<TenantUserGroupsTab />}
        />
      </Routes>,
      "/tenants/tenant-company/organization",
    );

    expect(await screen.findByText("Member User")).toBeInTheDocument();

    fireEvent.click(screen.getByTestId("tenant-current-users-export-btn"));

    await waitFor(() => {
      expect(exportUsersCSVMock).toHaveBeenCalledWith("", "gpdtdc", false);
    });
  });

  it("queues searched users and bulk adds them to the selected organization", async () => {
    renderWithProviders(
      <Routes>
        <Route
          path="/tenants/:tenantId/organization"
          element={<TenantUserGroupsTab />}
        />
      </Routes>,
      "/tenants/tenant-company/organization",
    );

    expect(await screen.findByText("Member User")).toBeInTheDocument();

    fireEvent.click(screen.getByRole("button", { name: /멤버 추가/ }));
    fireEvent.change(screen.getByTestId("tenant-org-member-search-input"), {
      target: { value: "user" },
    });
    fireEvent.click(screen.getByTestId("tenant-org-member-search-btn"));

    fireEvent.click(
      await screen.findByTestId("tenant-org-member-search-result-user-owner"),
    );
    fireEvent.click(
      await screen.findByTestId("tenant-org-member-search-result-user-admin"),
    );

    expect(screen.getByTestId("tenant-org-member-add-queue")).toHaveTextContent(
      "Owner User",
    );
    expect(screen.getByTestId("tenant-org-member-add-queue")).toHaveTextContent(
      "Admin User",
    );

    fireEvent.click(screen.getByTestId("tenant-org-member-add-submit-btn"));

    await waitFor(() => {
      expect(bulkUpdateUsersMock).toHaveBeenCalledWith({
        userIds: ["user-owner", "user-admin"],
        tenantSlug: "gpdtdc",
        isAddTenant: true,
      });
    });
  });
});
