from selenium import webdriver
from selenium.webdriver.firefox.options import Options as FirefoxOptions
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException, ElementNotInteractableException
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import mariadb

from enum import Enum
import time

magnus = "http://192.168.2.56/mbilling/"

login = {
    'user': 'root',
    'password': 'NgtAtONgeRaFtsbu',
}

db_login = {
    "user": "scripts",
    "password": "scripts",
    "host": "192.168.2.84",
    "port": 3306,
    "database": "mbilling"
}


class DuplicateNumberError(Exception):
    pass


class MagnusBillingError(Exception):
    pass


class UserNotFoundError(Exception):
    pass


class Tarifa(Enum):
    ESTANDAR = 'Tarifa Estándar'
    EMPRESA = 'Tarifa Empresas'
    PLANA1000 = 'Bono PTV'
    PLANA2000 = 'Bono PTV'


def authenticate(driver: webdriver.Firefox):
    driver.get(magnus)
    WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
        (By.XPATH, '//*[@id="textfield-1013-inputEl"]'))).send_keys(login['user'])
    driver.find_element(
        By.XPATH, '//*[@id="textfield-1014-inputEl"]').send_keys(login['password'], Keys.ENTER)

    try:
        WebDriverWait(driver, 5).until(EC.element_to_be_clickable(
            (By.XPATH, ' //*[@id="tool-1031-toolEl"]'))).click()
    except TimeoutException:
        pass


def new_user(driver: webdriver.Firefox, telefono: str, titular: str, password: str = None,  tarifa: Tarifa = Tarifa.ESTANDAR):
    # Acceso a Panel
    WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
        (By.XPATH, '//*[@id="treeview-1176-record-10"]'))).click()
    WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
        (By.XPATH, '//*[@id="button-1270"]'))).click()

    # Usuario y Comntraseña
    username = WebDriverWait(driver, 3).until(
        EC.element_to_be_clickable((By.XPATH, '//input[@name="username"]')))
    username.clear()
    username.send_keys(telefono)

    if password:
        password_field = driver.find_element(
            By.XPATH, '//input[@name="password"]')
        password_field.clear()
        password_field.send_keys(password)

    # Cambio de Panel
    driver.find_element(
        By.XPATH, '//*[@id="groupusercombo-1293-trigger-picker"]').click()
    driver.find_element(
        By.XPATH, '//ul[@data-ref="listEl"]/li[text()="Cliente"]').click()

    # Tarifa
    driver.find_element(By.XPATH, '//*[@id="button-1297"]').click()
    tarifa = WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
        (By.XPATH, f'/html/body/div/div/div/div/div/div/div/div/table/tbody/tr/td/div[text()="{tarifa.value}"]'))
    )

    ActionChains(driver).double_click(tarifa).perform()

    # Datos Personales
    driver.find_element(
        By.XPATH, '  //span[text()="Información personal"]').click()
    WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
        (By.XPATH, '//input[@name="lastname"]'))).send_keys(titular)
    WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
        (By.XPATH, '//input[@name="firstname"]'))).send_keys(titular)

    # Guardar Datos
    driver.find_element(By.XPATH, '//span[text()="Salvar"]').click()
    try:
        driver.find_element(By.XPATH, '//span[text()="Cancelar"]').click()
    except ElementNotInteractableException:
        pass

    # Comprobar Mensaje de Error
    try:
        error = WebDriverWait(driver, 2).until(EC.element_to_be_clickable(
            (By.XPATH, '//table[@class="alert-error"]//p[@style="font-size: 13px;"]')))
        raise DuplicateNumberError(error.text)
    except TimeoutException:
        pass


def balance_recharge(driver: webdriver.Firefox, phone: str, recharge: float = 10.00, tax_include: bool = False):
    """Recarga la Cantidad de Saldo 

    """

    try:
        WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
            (By.XPATH, '//span[contains(text(), "Recargas")]')
        )).click()
    except TimeoutException:
        WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
            (By.XPATH, '//div[contains(text(), "Financiero")]')
        )).click()
        return balance_recharge(driver, phone, recharge, tax_include)

    WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
        (By.XPATH, '//span[contains(text(), "Nuevo")]')
    )).click()

    WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
        (By.XPATH, '//span[contains(text(), "Buscar")]')
    )).click()

    search = WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
        (By.XPATH,
         '//div[@role="dialog"]//input[@placeholder="Buscar username"]')
    ))

    ActionChains(driver).click(search).send_keys(
        phone).send_keys(Keys.ENTER).perform()

    WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
        (By.XPATH,
         '//div[@role="dialog"]//div[@class="x-grid-cell-inner "]')
    )).click()


def create_sip_account(driver: webdriver.Firefox, username: str,  phone: str, pbx_address: str = None):
    """Genera las cuentas SIP del Usuario

    """

    try:
        WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
            (By.XPATH, '//span[contains(text(), "Cuentas SIP")]')
        )).click()
    except TimeoutException:
        WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
            (By.XPATH, '//div[contains(text(), "Clientes")]')
        )).click()
        return balance_recharge(driver, phone, pbx_address)

    WebDriverWait(driver, 3).until(EC.element_to_be_clickable(
        (By.XPATH, '//input[@placeholder="Buscar name"]')
    )).send_keys(phone, Keys.ENTER)

    try:

        WebDriverWait(driver, 1).until(EC.element_to_be_clickable(
            (By.XPATH, f'//div[text() = "{phone}"]')
        )).click()

    except TimeoutException:

        WebDriverWait(driver, 1).until(EC.element_to_be_clickable(
            (By.XPATH, f'//span[text() = "Nuevo"]')
        )).click()

    # Selección de Usuario
    driver.find_element(By.XPATH, '//span[text()="Buscar"]').click()
    driver.find_element(
        By.XPATH, '//div[@role="dialog"]//input[@placeholder="Buscar username"]').send_keys(
            username, Keys.ENTER
    )
    try:
        user = WebDriverWait(driver, 1).until(EC.element_to_be_clickable(
            (By.XPATH, f'//div[@role="dialog"]//tr[@class="  x-grid-row"]')
        ))
        ActionChains(driver).move_to_element(user).double_click().perform()

    except TimeoutException:
        raise UserNotFoundError()

    # SIP User


    # Caller ID
    caller_id = driver.find_element(By.XPATH, '//input[@name="callerid"]')
    if len(caller_id.text) == 0:
        caller_id.send_keys(phone, Keys.ENTER)

    # Secret
    secret = driver.find_element(By.XPATH, '//input[@name="callerid"]')
    if len(secret.text) == 0:
        secret.send_keys(username, Keys.ENTER)

    



def user_exists(telefono: str) -> dict:
    with mariadb.connect(**db_login) as cnx:
        with cnx.cursor() as cursor:
            cursor.execute(
                'SELECT * FROM mbilling.pkg_sip WHERE name=?;',
                (telefono,)
            )

            exists = cursor.fetchone() is not None

    return exists


if __name__ == '__main__':
    options = FirefoxOptions()
    # options.add_argument("--headless")
    driver = webdriver.Firefox(options=options)
    authenticate(driver)
    create_sip_account(driver, '856135158', '856135158')
