/*
Copyright 2023 Suguru Hirahara

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { test, expect } from "../../element-web-test";

const USER_NAME = "Bob";
const USER_NAME_NEW = "Alice";

test.describe("General user settings tab", () => {
    test.use({
        displayName: USER_NAME,
        config: {
            default_country_code: "US", // For checking the international country calling code
        },
        uut: async ({ app, user }, use) => {
            const locator = await app.settings.openUserSettings("General");
            await use(locator);
        },
    });

    test("should be rendered properly", async ({ uut, user }) => {
        await expect(uut).toMatchScreenshot("general.png");

        // Assert that the top heading is rendered
        await expect(uut.getByRole("heading", { name: "General" })).toBeVisible();

        const profile = uut.locator(".mx_UserProfileSettings_profile");
        await profile.scrollIntoViewIfNeeded();
        await expect(profile.getByRole("textbox", { name: "Display Name" })).toHaveValue(USER_NAME);

        // Assert that a userId is rendered
        expect(uut.getByLabel("Username")).toHaveText(user.userId);

        // Wait until spinners disappear
        await expect(uut.getByTestId("accountSection").locator(".mx_Spinner")).not.toBeVisible();
        await expect(uut.getByTestId("discoverySection").locator(".mx_Spinner")).not.toBeVisible();

        const accountSection = uut.getByTestId("accountSection");
        // Assert that input areas for changing a password exists
        const changePassword = accountSection.locator("form.mx_GeneralUserSettingsTab_section--account_changePassword");
        await changePassword.scrollIntoViewIfNeeded();
        await expect(changePassword.getByLabel("Current password")).toBeVisible();
        await expect(changePassword.getByLabel("New Password")).toBeVisible();
        await expect(changePassword.getByLabel("Confirm password")).toBeVisible();

        // Check email addresses area
        const emailAddresses = uut.getByTestId("mx_AccountEmailAddresses");
        await emailAddresses.scrollIntoViewIfNeeded();
        // Assert that an input area for a new email address is rendered
        await expect(emailAddresses.getByRole("textbox", { name: "Email Address" })).toBeVisible();
        // Assert the add button is visible
        await expect(emailAddresses.getByRole("button", { name: "Add" })).toBeVisible();

        // Check phone numbers area
        const phoneNumbers = uut.getByTestId("mx_AccountPhoneNumbers");
        await phoneNumbers.scrollIntoViewIfNeeded();
        // Assert that an input area for a new phone number is rendered
        await expect(phoneNumbers.getByRole("textbox", { name: "Phone Number" })).toBeVisible();
        // Assert that the add button is rendered
        await expect(phoneNumbers.getByRole("button", { name: "Add" })).toBeVisible();

        // Assert the account deactivation button is displayed
        const accountManagementSection = uut.getByTestId("account-management-section");
        await accountManagementSection.scrollIntoViewIfNeeded();
        await expect(accountManagementSection.getByRole("button", { name: "Deactivate Account" })).toHaveClass(
            /mx_AccessibleButton_kind_danger/,
        );
    });

    test("should respond to small screen sizes", async ({ page, uut }) => {
        await page.setViewportSize({ width: 700, height: 600 });
        await expect(uut).toMatchScreenshot("general-smallscreen.png");
    });

    test("should show tooltips on narrow screen", async ({ page, uut }) => {
        await page.setViewportSize({ width: 700, height: 600 });
        await page.getByRole("tab", { name: "General" }).hover();
        await expect(page.getByRole("tooltip")).toHaveText("General");
    });

    test("should support adding and removing a profile picture", async ({ uut, page }) => {
        const profileSettings = uut.locator(".mx_UserProfileSettings");
        // Upload a picture
        await profileSettings.getByAltText("Upload").setInputFiles("playwright/sample-files/riot.png");

        // Image should be visible
        await expect(profileSettings.locator(".mx_AvatarSetting_avatar img")).toBeVisible();

        // Open the menu & click remove
        await profileSettings.getByRole("button", { name: "Profile Picture" }).click();
        await page.getByRole("menuitem", { name: "Remove" }).click();

        // Assert that the image disappeared
        await expect(profileSettings.locator(".mx_AvatarSetting_avatar img")).not.toBeVisible();
    });

    test("should set a country calling code based on default_country_code", async ({ uut }) => {
        // Check phone numbers area
        const accountPhoneNumbers = uut.getByTestId("mx_AccountPhoneNumbers");
        await accountPhoneNumbers.scrollIntoViewIfNeeded();
        // Assert that an input area for a new phone number is rendered
        await expect(accountPhoneNumbers.getByRole("textbox", { name: "Phone Number" })).toBeVisible();

        // Check a new phone number dropdown menu
        const dropdown = accountPhoneNumbers.locator(".mx_PhoneNumbers_country");
        await dropdown.scrollIntoViewIfNeeded();
        // Assert that the country calling code of the United States is visible
        await expect(dropdown.getByText(/\+1/)).toBeVisible();

        // Click the button to display the dropdown menu
        await dropdown.getByRole("button", { name: "Country Dropdown" }).click();

        // Assert that the option for calling code of the United Kingdom is visible
        await expect(dropdown.getByRole("option", { name: /United Kingdom/ })).toBeVisible();

        // Click again to close the dropdown
        await dropdown.getByRole("button", { name: "Country Dropdown" }).click();

        // Assert that the default value is rendered again
        await expect(dropdown.getByText(/\+1/)).toBeVisible();

        await expect(accountPhoneNumbers.getByRole("button", { name: "Add" })).toBeVisible();
    });

    test("should support changing a display name", async ({ uut, page, app }) => {
        // Change the diaplay name to USER_NAME_NEW
        const displayNameInput = uut
            .locator(".mx_SettingsTab .mx_UserProfileSettings")
            .getByRole("textbox", { name: "Display Name" });
        await displayNameInput.fill(USER_NAME_NEW);
        await displayNameInput.press("Enter");

        await app.closeDialog();

        // Assert the avatar's initial characters are set
        await expect(page.locator(".mx_UserMenu .mx_BaseAvatar").getByText("A")).toBeVisible(); // Alice
        await expect(page.locator(".mx_RoomView_wrapper .mx_BaseAvatar").getByText("A")).toBeVisible(); // Alice
    });
});
