package com.atlassian.webdriver.bitbucket.page.admin;

import com.atlassian.pageobjects.elements.ElementBy;
import com.atlassian.pageobjects.elements.PageElement;
import com.atlassian.pageobjects.elements.query.Poller;
import com.atlassian.webdriver.bitbucket.element.UserDeleteDialog;
import com.atlassian.webdriver.bitbucket.page.BitbucketPage;
import com.atlassian.webdriver.bitbucket.util.ElementUtils;
import com.atlassian.webdriver.bitbucket.util.Locators;
import org.openqa.selenium.By;

import java.util.ArrayList;
import java.util.List;

import static org.hamcrest.Matchers.containsString;

/**
 * Represents the "User List" page.
 */
public class UserListPage extends BitbucketPage {

    @ElementBy(className = "create-user-link")
    private PageElement addUserButton;
    @ElementBy(id = "list-users")
    private PageElement userList;
    @ElementBy(className = "paged-table-filter-input")
    private PageElement filterTextbox;
    @ElementBy(cssSelector = ".aui-message-success")
    private PageElement successMessage;

    public String getUrl() {
        return "/admin/users";
    }

    public UserAddPage clickAdd() {
        addUserButton.click();
        return pageBinder.bind(UserAddPage.class);
    }

    public UserRow getUser(String name) {
        for (PageElement row : userList.findAll(Locators.tableRow())) {
            final UserRow userRow = new UserRow(row);
            if (name.equals(userRow.getName())) {
                return userRow;
            }
        }

        return null;
    }

    public List<UserRow> getUsers() {
        List<PageElement> tableRows = userList.findAll(Locators.tableRow());
        List<UserRow> users = new ArrayList<UserRow>(tableRows.size());
        for (PageElement row : tableRows) {
            users.add(new UserRow(row));
        }

        return users;
    }

    public String getDeleteSuccessMessage() {
        return Poller.waitUntil(successMessage.timed().getText(), containsString("delete")).trim();
    }

    public UserListPage setFilter(final String filter) {
        ElementUtils.waitUntilUpdated(userList, new Runnable() {
            @Override
            public void run() {
                filterTextbox.clear().type(filter);
            }
        });
        return pageBinder.bind(UserListPage.class);
    }

    public class UserRow {
        private final PageElement row;

        public UserRow(PageElement row) {
            this.row = row;
        }

        public String getName() {
            return getColumnText("username");
        }

        public String getFullname() {
            return getColumnText("fullname");
        }

        public String getEmail() {
            return getColumnText("email");
        }

        private String getColumnText(String section) {
            final PageElement column = getColumn(section);
            return column.isPresent() ? column.getText() : null;
        }

        private PageElement getColumn(String section) {
            return row.find(By.cssSelector("td[headers='" + section + "']"));
        }

        public UserEditPage clickView() {
            getColumn("fullname").find(By.tagName("a")).click();
            return pageBinder.bind(UserEditPage.class);
        }

        public UserDeleteDialog clickDelete() {
            ElementUtils.displayAllDeleteButtons(javascriptExecutor);

            PageElement deleteUser = getColumn("actions").find(By.className("delete-user"));
            ElementUtils.scrollIntoViewIfNeeded(deleteUser);
            deleteUser.click();

            UserDeleteDialog dialog = body.find(By.id(UserDeleteDialog.ID), UserDeleteDialog.class);
            Poller.waitUntilTrue(dialog.timed().isVisible());

            return dialog;
        }
    }
}
