package com.intland.codebeamer.functionaltest.page;

import com.codeborne.selenide.ElementsCollection;
import com.codeborne.selenide.SelenideElement;
import org.openqa.selenium.By;

import java.security.InvalidParameterException;
import java.util.List;

import static com.codeborne.selenide.Selenide.$;
import static com.codeborne.selenide.Selenide.$$;
import static com.codeborne.selenide.Selenide.page;

/**
 * Copyright by Intland Software
 * <p>
 * All rights reserved.
 * <p>
 * This software is the confidential and proprietary information
 * of Intland Software. ("Confidential Information"). You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with Intland.
 */
public class LicenseGeneratorPage {

    private final String PASSWORD = "newCorners";

    public static class License {

        private Product product;
        private List<AdditionalOption> additionalOptions;
        private int usersWithNamedLicense;
        private int usersWithFloatingLicense;

        public License(Product product, List<AdditionalOption> additionalOptions, int usersWithNamedLicense, int usersWithFloatingLicense) {
            this.product = product;
            this.additionalOptions = additionalOptions;
            this.usersWithNamedLicense = usersWithNamedLicense;
            this.usersWithFloatingLicense = usersWithFloatingLicense;
        }

        public Product getProduct() {
            return product;
        }

        public void setProduct(Product product) {
            this.product = product;
        }

        public List<AdditionalOption> getAdditionalOptions() {
            return additionalOptions;
        }

        public void setAdditionalOptions(List<AdditionalOption> additionalOptions) {
            this.additionalOptions = additionalOptions;
        }

        public int getUsersWithNamedLicense() {
            return usersWithNamedLicense;
        }

        public void setUsersWithNamedLicense(int usersWithNamedLicense) {
            this.usersWithNamedLicense = usersWithNamedLicense;
        }

        public int getUsersWithFloatingLicense() {
            return usersWithFloatingLicense;
        }

        public void setUsersWithFloatingLicense(int usersWithFloatingLicense) {
            this.usersWithFloatingLicense = usersWithFloatingLicense;
        }
    }

    //TODO add all options to the list
    public enum AdditionalOption {
        ESCALATION("Escalation"),
        TEST_SERVER("Test Server"),
        SERVICE_DESK("Service Desk"),
        DOCUMENT_APPROVAL("Document Approval (deprecated)"),
        DOCUMENT_REVIEW("Document Review (deprecated)");

        private final String text;

        AdditionalOption(String s) {
            text = s;
        }
    }

    public enum Product {
        AGILE("Agile"),
        APPLICATION_LIFECYLE_MANAGEMENT("Application Lifecyle Management"),
        DEVELOPMENT_MANAGEMENT("Development Management (former CM)"),
        COLLABORATION_PLATFORM("Collaboration Platform"),
        DOCUMENT_REVIEWER("Document Reviewer - only View, Comment abilities"),
        QA_TEST_MANAGEMENT("QA/Test Management"),
        REQUIREMENTS_MANAGEMENT("Requirements Management"),
        SERVICE_DESK("Service Desk");


        private final String text;


        Product(String s) {
            text = s;

        }

        public boolean equalsName(String otherSelector) {
            return (otherSelector == null) ? false : text.equals(otherSelector);
        }

        public String toString() {
            return this.text;
        }
    }

    public enum Release {
        R8_1("8.1 - ... "),
        R8_0_1_8_0_2("8.0.1 - 8.0.2");

        private final String text;

        Release(String s) {
            text = s;
        }

        public boolean equalsName(String otherSelector) {
            return (otherSelector == null) ? false : text.equals(otherSelector);
        }

        public String toString() {
            return this.text;
        }
    }

    public void fillHostId(String hostId) {
        SelenideElement input = $(By.xpath(".//input[@name='hostId']"));
        input.clear();
        input.sendKeys(hostId);
    }

    public void selectProduct(Product product, int index) {
        $(By.xpath("(.//td[@id='productLicenses']//select)[" + index + "]")).selectOption(product.text);
    }

    public void tickAdditionalOptions(List<AdditionalOption> additionalOptions, int index) {
        for (AdditionalOption additionalOption : additionalOptions) {
            $(By.xpath(".//td[@id='productLicenses']//tbody//tr[2]/td[1+" + index + "]//label[normalize-space()='" + additionalOption.text + "']")).setSelected(true);
        }
    }

    public void fillUsersWithNamedLicense(int number, int index) {
        $(By.xpath(".//td[@id='productLicenses']//tbody//tr[3]//td[1+" + index + "]/input")).setValue(String.valueOf(number));
    }

    public void fillUsersWithFloatingLicense(int number, int index) {
        $(By.xpath(".//td[@id='productLicenses']//tbody//tr[4]//td[1+" + index + "]/input")).setValue(String.valueOf(number));
    }

    public void selectProducts(List<Product> products) {
        if (products.size() > 6) throw new InvalidParameterException("Maximum 6 products are allowed");
        ElementsCollection selects = $$(By.xpath(".//td[@id='productLicenses']//select"));
        for (int i = 0; i < products.size(); ++i) {
            selects.get(i).selectOption(products.get(i).text);
        }
    }


    public void fillUsersWithFloatingLicense(List<Integer> numbers) {
        if (numbers.size() > 6) throw new InvalidParameterException("Maximum 6 numbers are allowed");
        ElementsCollection inputs = $$(By.xpath(".//td[@id='productLicenses']//tr[4]//input"));
        for (int i = 0; i < numbers.size(); ++i) {
            inputs.get(i).sendKeys(numbers.get(i).toString());
        }
    }

    public void fillPassword() {
        $(By.xpath(".//input[@name='password']")).sendKeys(PASSWORD);
    }


    public GeneratedLicensePage clickOnSave() {
        $(By.xpath(".//input[@value='Save']")).click();
        //TODO check if there is no error
        return page(GeneratedLicensePage.class);
    }

    public String generateLicense(String hostId, List<License> licenses) {
        fillHostId(hostId);
        for (int i = 0; i < licenses.size(); ++i){
            selectProduct(licenses.get(i).getProduct(), i+1);
            tickAdditionalOptions(licenses.get(i).getAdditionalOptions(), i+1 );
            fillUsersWithNamedLicense(licenses.get(i).getUsersWithNamedLicense(), i+1);
            fillUsersWithFloatingLicense(licenses.get(i).getUsersWithFloatingLicense(), i+1);
        }
        fillPassword();
        GeneratedLicensePage generatedLicensePage = clickOnSave();
        return generatedLicensePage.getLicenseInBinaryFormat();
    }

}
