import { fireEvent, screen, waitFor } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { renderWithProviders } from "../utils/testHelpers";
import SettingsPage from "./settings";

const mockUpdateProfile = vi.fn();
const mockUploadAvatar = vi.fn();
const mockRemoveAvatar = vi.fn();
const mockUpdateIntroduction = vi.fn();
const mockSetDraftIntroduction = vi.fn();

vi.mock("../hooks/profile", () => ({
  useUpdateProfile: () => ({
    mutate: mockUpdateProfile,
    isPending: false,
  }),
  useUploadAvatar: () => ({
    mutate: mockUploadAvatar,
  }),
  useRemoveAvatar: () => ({
    mutateAsync: mockRemoveAvatar,
    isPending: false,
  }),
}));

vi.mock("../hooks/intros", () => ({
  useIntroduction: () => ({
    introduction: { intro_email: "Test introduction" },
    updateIntroduction: mockUpdateIntroduction,
    setDraftIntroduction: mockSetDraftIntroduction,
    isPending: false,
  }),
}));

vi.mock("@xtablo/shared", async () => {
  const actual = await vi.importActual("@xtablo/shared");
  return {
    ...actual,
    toast: {
      add: vi.fn(),
    },
  };
});

describe.skip("SettingsPage", () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it("renders without crashing", () => {
    const { container } = renderWithProviders(<SettingsPage />);
    expect(container).toBeInTheDocument();
  });

  it("renders all settings sections", () => {
    const { container } = renderWithProviders(<SettingsPage />);
    // Component renders with all sections
    expect(container).toBeInTheDocument();
  });

  it("displays user information in form fields", () => {
    renderWithProviders(<SettingsPage />);

    const firstNameInput = screen.getByLabelText(
      /settings:personalInfo.firstName/i
    ) as HTMLInputElement;
    const lastNameInput = screen.getByLabelText(
      /settings:personalInfo.lastName/i
    ) as HTMLInputElement;
    const emailInput = screen.getByLabelText(/settings:personalInfo.email/i) as HTMLInputElement;

    expect(firstNameInput.value).toBe("John");
    expect(lastNameInput.value).toBe("Doe");
    expect(emailInput.value).toBe("john@example.com");
  });

  it("email input is disabled", () => {
    renderWithProviders(<SettingsPage />);

    const emailInput = screen.getByLabelText(/settings:personalInfo.email/i);
    expect(emailInput).toBeDisabled();
  });

  it("updates first name on change", () => {
    renderWithProviders(<SettingsPage />);

    const firstNameInput = screen.getByLabelText(
      /settings:personalInfo.firstName/i
    ) as HTMLInputElement;
    fireEvent.change(firstNameInput, { target: { value: "Jane" } });

    expect(firstNameInput.value).toBe("Jane");
  });

  it("updates last name on change", () => {
    renderWithProviders(<SettingsPage />);

    const lastNameInput = screen.getByLabelText(
      /settings:personalInfo.lastName/i
    ) as HTMLInputElement;
    fireEvent.change(lastNameInput, { target: { value: "Smith" } });

    expect(lastNameInput.value).toBe("Smith");
  });

  it("calls updateProfile with new values when save button is clicked", async () => {
    renderWithProviders(<SettingsPage />);

    const firstNameInput = screen.getByLabelText(/settings:personalInfo.firstName/i);
    const lastNameInput = screen.getByLabelText(/settings:personalInfo.lastName/i);

    fireEvent.change(firstNameInput, { target: { value: "Jane" } });
    fireEvent.change(lastNameInput, { target: { value: "Smith" } });

    const saveButton = screen.getByRole("button", { name: /settings:personalInfo.save/i });
    fireEvent.click(saveButton);

    await waitFor(() => {
      expect(mockUpdateProfile).toHaveBeenCalledWith({
        firstName: "Jane",
        lastName: "Smith",
      });
    });
  });

  it("displays introduction text", () => {
    renderWithProviders(<SettingsPage />);

    const introTextarea = screen.getByLabelText(
      /settings:introduction.title/i
    ) as HTMLTextAreaElement;
    expect(introTextarea.value).toBe("Test introduction");
  });

  it("updates introduction text on change", () => {
    renderWithProviders(<SettingsPage />);

    const introTextarea = screen.getByLabelText(/settings:introduction.title/i);
    fireEvent.change(introTextarea, { target: { value: "New introduction" } });

    expect(mockSetDraftIntroduction).toHaveBeenCalled();
  });

  it("calls updateIntroduction when save button is clicked", async () => {
    renderWithProviders(<SettingsPage />);

    const saveButtons = screen.getAllByRole("button", { name: /common:buttons.save/i });
    const introSaveButton = saveButtons[saveButtons.length - 1]; // Last save button is for introduction

    fireEvent.click(introSaveButton);

    await waitFor(() => {
      expect(mockUpdateIntroduction).toHaveBeenCalledWith({
        intro_email: "Test introduction",
      });
    });
  });

  it("renders avatar with user initials fallback", () => {
    const { container } = renderWithProviders(<SettingsPage />);
    // Component renders with avatar section
    expect(container).toBeInTheDocument();
  });

  it("has file input for avatar upload", () => {
    renderWithProviders(<SettingsPage />);

    const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
    expect(fileInput).toBeInTheDocument();
    expect(fileInput).toHaveAttribute("accept", "image/*");
  });

  it("shows choose file button", () => {
    renderWithProviders(<SettingsPage />);

    expect(screen.getByRole("button", { name: /settings:avatar.chooseFile/i })).toBeInTheDocument();
  });

  it("validates file size on avatar upload", async () => {
    const { toast } = await import("@xtablo/shared");
    renderWithProviders(<SettingsPage />);

    const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;

    // Create a large file (> 5MB)
    const largeFile = new File(["x".repeat(6 * 1024 * 1024)], "large.jpg", { type: "image/jpeg" });

    Object.defineProperty(fileInput, "files", {
      value: [largeFile],
      writable: false,
    });

    fireEvent.change(fileInput);

    await waitFor(() => {
      expect(toast.add).toHaveBeenCalledWith(
        expect.objectContaining({
          title: "settings:toasts.error",
          description: "settings:toasts.fileTooLarge",
          type: "error",
        })
      );
    });
  });

  it("validates file type on avatar upload", async () => {
    const { toast } = await import("@xtablo/shared");
    renderWithProviders(<SettingsPage />);

    const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;

    // Create a non-image file
    const textFile = new File(["test"], "test.txt", { type: "text/plain" });

    Object.defineProperty(fileInput, "files", {
      value: [textFile],
      writable: false,
    });

    fireEvent.change(fileInput);

    await waitFor(() => {
      expect(toast.add).toHaveBeenCalledWith(
        expect.objectContaining({
          title: "settings:toasts.error",
          description: "settings:toasts.invalidImage",
          type: "error",
        })
      );
    });
  });

  it("shows delete avatar button when avatar exists", () => {
    renderWithProviders(<SettingsPage />);

    expect(screen.getByRole("button", { name: /settings:avatar.delete/i })).toBeInTheDocument();
  });

  it("opens confirmation dialog when delete button is clicked", () => {
    renderWithProviders(<SettingsPage />);

    const deleteButton = screen.getByRole("button", { name: /settings:avatar.delete/i });
    fireEvent.click(deleteButton);

    expect(screen.getByText(/settings:avatar.deleteTitle/i)).toBeInTheDocument();
    expect(screen.getByText(/settings:avatar.deleteDescription/i)).toBeInTheDocument();
  });

  it("calls removeAvatar when deletion is confirmed", async () => {
    renderWithProviders(<SettingsPage />);

    const deleteButton = screen.getByRole("button", { name: /settings:avatar.delete/i });
    fireEvent.click(deleteButton);

    // Find and click confirm button in dialog
    const confirmButtons = screen.getAllByRole("button", { name: /settings:avatar.delete/i });
    const confirmButton = confirmButtons[confirmButtons.length - 1]; // Last one is in the dialog
    fireEvent.click(confirmButton);

    await waitFor(() => {
      expect(mockRemoveAvatar).toHaveBeenCalled();
    });
  });

  it("renders language selector", () => {
    renderWithProviders(<SettingsPage />);

    // LanguageSelector is a separate component, just verify it's rendered
    expect(screen.getByText(/settings:title/i)).toBeInTheDocument();
  });
});
