import logging
from median.models import Compteur
from median.database import mysql_db
from .base import MedianLibException
from peewee import DoesNotExist
from datetime import datetime


logger = logging.getLogger('median.utils')


def compute_gtin_checksum(gtin: str, fullcode: bool = False) -> str:
    """
    Compute the GTIN barcode checksum

    :param gtin: GTIN to compute the checksum, must have 12 characters
    :param fullcode: decide if we return the full gtin or juste the checksum
    :returns: checksum only by default or full GTIN if fullcode=True
    """
    if not gtin:
        logger.warning("GTIN cannot be null!")
        raise MedianLibException("GTIN cannot be null!")

    if len(gtin) != 12:
        logger.warning("GTIN must have 12 characters!")
        raise MedianLibException("GTIN must have 12 characters!")

    checksum_char = str((10 - sum((3, 1)[i % 2] * int(n) for i, n in enumerate(reversed(gtin)))) % 10)
    logger.debug("Checksum for %s is %s" % (gtin, checksum_char))
    return fullcode and (gtin + checksum_char) or checksum_char


def get_counter(counter_name: str = '', increment: int = 1, force_create: bool = False) -> int:
    """
    Retrieve the valeur of the counter and return it
    and increment for the next call

    :param count_name: name of the counter to retrieve the value
    :param increment: increment value for the next call, 1 by default
    :param force_create: if counter not exists, we create it if value is True
    :returns: current counter value
    """
    with mysql_db.atomic():
        try:
            cpt = (
                Compteur.select()
                .where(Compteur.cle == counter_name)
                .for_update()
                .get()
            )
            result = cpt.val
            cpt.val = cpt.val + increment
            cpt.save()
        except DoesNotExist:
            if force_create:
                cpt = Compteur()
                cpt.cle = counter_name
                cpt.val = 2
                cpt.save()
                return 1
            else:
                raise MedianLibException("Counter %s does not exists!")
    return result


def padding_address(address) -> str:
    """Reformat address to be compliant with database storage"""
    tmp_adr = []
    if isinstance(address, str):
        address = address.split('.')
    for a in address:
        if str(a).strip().find('%') == -1:
            tmp_adr.append(str(a).strip().rjust(3))
        else:
            tmp_adr.append(str(a).strip())
    return '.'.join(tmp_adr)


def date_add_month(d, x):
    """Add some month to the current date"""
    dom = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    n_month = (((d.month - 1) + x) % 12) + 1
    newyear = d.year + (((d.month - 1) + x) // 12)
    if d.day > dom[n_month-1]:
        n_day = dom[n_month-1]
    else:
        n_day = d.day
    return datetime(newyear, n_month, n_day)
