/*
 * Copyright 2025 New Vector Ltd.
 *
 * SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
 * Please see LICENSE files in the repository root for full details.
 */

import React from "react";
import { render, screen, waitFor } from "jest-matrix-react";
import userEvent from "@testing-library/user-event";
import { mocked } from "jest-mock";

import type { MatrixClient } from "matrix-js-sdk/src/matrix";
import { createTestClient, withClientContextRenderOptions } from "../../../../../test-utils";
import { DeleteKeyStoragePanel } from "../../../../../../src/components/views/settings/encryption/DeleteKeyStoragePanel";
import { useKeyStoragePanelViewModel } from "../../../../../../src/components/viewmodels/settings/encryption/KeyStoragePanelViewModel";

jest.mock("../../../../../../src/components/viewmodels/settings/encryption/KeyStoragePanelViewModel", () => ({
    useKeyStoragePanelViewModel: jest.fn().mockReturnValue({
        setEnabled: jest.fn(),
        isEnabled: true,
        loading: false,
        busy: false,
    }),
}));

describe("<DeleteKeyStoragePanel />", () => {
    let matrixClient: MatrixClient;

    beforeEach(() => {
        matrixClient = createTestClient();
    });

    it("should match snapshot", async () => {
        const { asFragment } = render(
            <DeleteKeyStoragePanel onFinish={() => {}} />,
            withClientContextRenderOptions(matrixClient),
        );
        expect(asFragment()).toMatchSnapshot();
    });

    it("should call onFinished when cancel pressed", async () => {
        const user = userEvent.setup();

        const onFinish = jest.fn();
        render(<DeleteKeyStoragePanel onFinish={onFinish} />, withClientContextRenderOptions(matrixClient));

        await user.click(screen.getByRole("button", { name: "Cancel" }));
        expect(onFinish).toHaveBeenCalled();
    });

    it("should call disable key storage when confirm pressed", async () => {
        const setEnabled = jest.fn();

        mocked(useKeyStoragePanelViewModel).mockReturnValue({
            setEnabled,
            isEnabled: true,
            loading: false,
            busy: false,
        });

        const user = userEvent.setup();

        const onFinish = jest.fn();
        render(<DeleteKeyStoragePanel onFinish={onFinish} />, withClientContextRenderOptions(matrixClient));

        await user.click(screen.getByRole("button", { name: "Delete key storage" }));

        expect(setEnabled).toHaveBeenCalledWith(false);
    });

    it("should wait with button disabled while setEnabled runs", async () => {
        let setEnabledResolve: () => void;
        const setEnabledPromise = new Promise<void>((r) => {
            setEnabledResolve = r;
        });

        mocked(useKeyStoragePanelViewModel).mockReturnValue({
            setEnabled: jest.fn().mockReturnValue(setEnabledPromise),
            isEnabled: true,
            loading: false,
            busy: false,
        });

        const user = userEvent.setup();

        const onFinish = jest.fn();
        render(<DeleteKeyStoragePanel onFinish={onFinish} />, withClientContextRenderOptions(matrixClient));

        await user.click(screen.getByRole("button", { name: "Delete key storage" }));

        expect(onFinish).not.toHaveBeenCalled();
        expect(screen.getByRole("button", { name: "Delete key storage" })).toHaveAttribute("aria-disabled", "true");
        setEnabledResolve!();
        await waitFor(() => expect(onFinish).toHaveBeenCalled());
    });
});
