import os

from peewee import MySQLDatabase
from peewee import IntegerField

MYSQL_DB_HOST = os.environ.get('MEDIAN_DB_HOST', 'localhost')
MYSQL_DB_PORT = int(os.environ.get('MEDIAN_DB_PORT', 3306))
MYSQL_DB_NAME = os.environ.get('MEDIAN_DB_NAME', 'test')
MYSQL_DB_USER = os.environ.get('MEDIAN_DB_USER', 'test')
MYSQL_DB_PASS = os.environ.get('MEDIAN_DB_PASS', 'test')
MYSQL_DB_CHARSET = os.environ.get('MEDIAN_DB_CHARSET', 'utf8mb4')
MYSQL_DB_COLLATION = os.environ.get('MEDIAN_DB_COLLATION', 'utf8mb4_0900_ai_ci')

mysql_db = MySQLDatabase(
    MYSQL_DB_NAME, user=MYSQL_DB_USER, password=MYSQL_DB_PASS,
    host=MYSQL_DB_HOST, port=MYSQL_DB_PORT
)

MYSQL_DB_NAME_SUIVI_PROD = os.environ.get('MEDIAN_DB_NAME_SUIVI_PROD', 'suivi_production')

mysql_db_suivi_prod = MySQLDatabase(
    MYSQL_DB_NAME_SUIVI_PROD, user=MYSQL_DB_USER, password=MYSQL_DB_PASS,
    host=MYSQL_DB_HOST, port=MYSQL_DB_PORT
)


class TinyIntegerField(IntegerField):
    """Define a type for TinyINT (only on MySQL) """
    field_type = 'TINYINT'


def crypte(passwd):
    """
    Encrypts a password using a custom algorithm for the Median FoxPro system.
    The function processes the input password by converting it to lowercase and stripping leading whitespace.
    It then applies a character-wise transformation based on the position and the value of the previous character,
    producing an obfuscated string.
    Args:
        passwd (str): The plaintext password to encrypt.
    Returns:
        str: The encrypted password string.
    Note:
        This encryption is not cryptographically secure and is intended for compatibility with the Median FoxPro system.
        ¯\\_(ツ)_/¯
    """
    passwd_enc = ''
    passwd = passwd.lower().lstrip()

    n_car = 0
    n_last_car = 0

    if len(passwd) == 0:
        return passwd_enc

    for i in range(1, len(passwd) + 1):
        n_car = ord(passwd[i - 1:][0])

        if i == 1:
            n_car += 5
            n_last_car = n_car
        else:
            if i % 2 != 0:
                n_car += (n_last_car % 7)
            else:
                n_car -= (n_last_car % 7)

        passwd_enc += chr(n_car)
    return passwd_enc


def decripte(passwd):
    """
    Decrypts a given password string using a custom algorithm.
    The function processes the input string character by character, applying a transformation
    based on the ASCII value of each character and its position in the string. The first character
    is decremented by 5, while subsequent characters are incremented or decremented by the remainder
    of the previous character's ASCII value divided by 7, depending on whether their position is even or odd.
    Args:
        passwd (str): The encrypted password string to be decrypted.
    Returns:
        str: The decrypted password string. Returns an empty string if the input is empty or None.
    """
    passwd_dec = ''
    if not passwd:
        return passwd_dec
    passwd = passwd.lower().lstrip()

    n_car = 0
    n_last_car = 0

    if len(passwd) == 0:
        return passwd_dec

    for i in range(1, len(passwd) + 1):
        n_car = ord(passwd[i - 1:][0])

        if i == 1:
            n_last_car = n_car
            n_car = n_car - 5
        else:
            if i % 2 != 0:
                n_car = n_car - (n_last_car % 7)
            else:
                n_car = n_car + (n_last_car % 7)

        passwd_dec += chr(n_car)

    return passwd_dec
