from peewee import AutoField, CharField, IntegerField, BooleanField, FloatField, DateTimeField
from peewee import SQL
from ..base import BaseModel
from ..constant import EcoType


class Magasin(BaseModel):
    pk = AutoField(column_name="x_pk", primary_key=True)
    last_reap = DateTimeField(
        column_name='x_last_reap', null=True, constraints=[SQL("DEFAULT '0000-00-00 00:00:00'")])
    mag = CharField(
        column_name='x_mag', unique=True, null=True, max_length=3, constraints=[SQL("DEFAULT ''")])
    type_mag = CharField(
        column_name='x_type_mag', null=True, max_length=15, constraints=[SQL("DEFAULT ''")])
    dim_2 = IntegerField(
        column_name="x_dim_2", null=True, constraints=[SQL("DEFAULT 0")], default=0
    )
    dim_3 = IntegerField(
        column_name="x_dim_3", null=True, constraints=[SQL("DEFAULT 0")], default=0
    )
    dim_4 = IntegerField(
        column_name="x_dim_4", null=True, constraints=[SQL("DEFAULT 0")], default=0
    )
    dim_5 = IntegerField(
        column_name="x_dim_5", null=True, constraints=[SQL("DEFAULT 0")], default=0
    )
    lib_2 = CharField(
        column_name='x_lib_2', null=True, max_length=20, constraints=[SQL("DEFAULT ''")], default='')
    lib_3 = CharField(
        column_name='x_lib_3', null=True, max_length=20, constraints=[SQL("DEFAULT ''")], default='')
    lib_4 = CharField(
        column_name='x_lib_4', null=True, max_length=20, constraints=[SQL("DEFAULT ''")], default='')
    lib_5 = CharField(
        column_name='x_lib_5', null=True, max_length=20, constraints=[SQL("DEFAULT ''")], default='')
    nb_dim = IntegerField(
        column_name="x_nb_dim", null=True, constraints=[SQL("DEFAULT 0")]
    )
    bmp = CharField(
        column_name='x_bmp', null=True, max_length=100)
    compo_x = IntegerField(
        column_name='x_compo_x', null=True, constraints=[SQL("DEFAULT 0")], default=0)
    compo_y = IntegerField(
        column_name='x_compo_y', null=True, constraints=[SQL("DEFAULT 0")], default=0)
    emp_res = BooleanField(
        column_name='x_emp_res', null=True, constraints=[SQL("DEFAULT 0")], default=0)
    statique = BooleanField(
        column_name='x_statique', null=True, constraints=[SQL("DEFAULT 0")], default=0)
    pds_max = IntegerField(
        column_name='x_pds_max', null=True, constraints=[SQL("DEFAULT 0")], default=0)
    dim_pds = IntegerField(
        column_name='x_dim_pds', null=True, constraints=[SQL("DEFAULT 0")], default=0)
    multiref = BooleanField(
        column_name='x_multiref', null=True, constraints=[SQL("DEFAULT 0")], default=0)
    parcours = CharField(
        column_name='x_parcours', null=True, max_length=1)
    palettier = BooleanField(
        column_name='x_palettier', null=True, constraints=[SQL("DEFAULT 0")], default=0)
    armoire = CharField(
        column_name='x_armoire', null=True, max_length=15)
    dest = CharField(
        column_name='x_dest', max_length=30, constraints=[SQL("DEFAULT ''")], default='')
    tampon = BooleanField(
        column_name='x_tampon', constraints=[SQL("DEFAULT 0")], default=0)
    adr_tampon = CharField(
        column_name='x_adr_tampon', null=True, max_length=19)
    coef_aut = IntegerField(
        column_name='x_coef_aut', constraints=[SQL("DEFAULT 1")], default=1)
    eco_type = CharField(column_name="x_eco_type", constraints=[SQL("DEFAULT ''")], default='')
    id_zone = CharField(
        column_name='x_id_zone', max_length=35, constraints=[SQL("DEFAULT ''")], default='')
    id_robot = CharField(
        column_name='x_id_robot', null=True, max_length=35, constraints=[SQL("DEFAULT ''")], default='')
    split_liste = BooleanField(
        column_name='x_split_liste', null=True, constraints=[SQL("DEFAULT 0")])
    libelle = CharField(
        column_name='x_libelle', max_length=35, constraints=[SQL("DEFAULT ''")], default='')
    type_machine = CharField(
        column_name="x_type_machine", max_length=20, constraints=[SQL("DEFAULT ''")], default='')
    groupe = CharField(
        column_name='x_groupe', null=True, max_length=3, default='')
    last_reap = DateTimeField(
        column_name='x_last_reap', null=True, constraints=[SQL("DEFAULT '0000-00-00 00:00:00'")])
    option_machine = BooleanField(
        column_name='x_option_machine', null=True, constraints=[SQL("DEFAULT 0")], default=0)
    compteur_coupe = BooleanField(
        column_name='x_compteur_coupe', null=True, constraints=[SQL("DEFAULT 0")], default=0)
    avatar = CharField(
        column_name='x_avatar', default='', max_length=50)
    groupe = CharField(
        column_name='x_groupe', max_length=3, constraints=[SQL("DEFAULT ''")], default='')
    type_dpm = CharField(
        column_name='x_type_dpm',  max_length=1,
        constraints=[SQL("DEFAULT ''")], default="")
    lettre = CharField(
        column_name='x_lettre', max_length=1, constraints=[SQL("DEFAULT '-'")], default='-')

    class Meta:
        table_name = "f_mag"
        indexes = (
            (('x_mag',), True)
        )

    def save(self, force_insert=False, only=None):
        """Enforce control on each information passed"""

        if self.eco_type not in [e.value for e in EcoType]:
            raise ValueError('Bad eco type!')
        if self.type_mag is None:
            raise ValueError('Type mag is required')
        return super().save(force_insert, only)


class Espace(BaseModel):
    pk = AutoField(
        column_name='x_pk', primary_key=True)
    poste = CharField(
        column_name='x_poste', null=True, max_length=20, constraints=[SQL("DEFAULT ''")], default='')
    mag = CharField(
        column_name='x_mag', null=True, max_length=3, constraints=[SQL("DEFAULT ''")], default='')
    alloc = BooleanField(
        column_name='x_alloc', null=True, constraints=[SQL("DEFAULT 0")])
    service = BooleanField(
        column_name='x_service', null=True, constraints=[SQL("DEFAULT 0")])
    gest = CharField(
        column_name='x_gest', null=True, max_length=20, constraints=[SQL("DEFAULT ''")], default='gest_trad')
    sub_gest = CharField(
        column_name='x_sub_gest', null=True, max_length=1, constraints=[SQL("DEFAULT ''")], default='a')
    pos_aff = IntegerField(
        column_name='x_pos_aff', null=True, constraints=[SQL("DEFAULT 0")])
    id_mag = CharField(
        column_name='x_id_mag', null=True, max_length=3, constraints=[SQL("DEFAULT ''")], default='')
    bouche = CharField(
        column_name='x_bouche', null=True, max_length=1, constraints=[SQL("DEFAULT ''")], default='')

    class Meta:
        table_name = 'f_espace'
        indexes = (
            (('x_poste', 'x_mag'), True),
            (('x_mag'), False)
        )

    # TODO: Check id poste or mag exists


class Adresse(BaseModel):
    pk = AutoField(column_name="x_pk", primary_key=True)
    adresse = CharField(
        column_name="x_adr", max_length=19,
        null=True, constraints=[SQL("DEFAULT ''")]
    )
    etat = CharField(
        column_name="x_etat", max_length=1,
        null=True, constraints=[SQL("DEFAULT ''")]
    )
    format = CharField(
        column_name="x_format", max_length=10,
        null=True, constraints=[SQL("DEFAULT ''")]
    )
    magasin = CharField(
        column_name="x_mag", max_length=3,
        null=True, constraints=[SQL("DEFAULT ''")]
    )
    contenant = CharField(
        column_name="x_contenant", max_length=20,
        constraints=[SQL("DEFAULT ''")]
    )
    bloque = IntegerField(column_name="x_bloque", constraints=[SQL("DEFAULT 0")])
    stupefiant = BooleanField(
        column_name="x_stup", null=True, constraints=[SQL("DEFAULT 0")]
    )
    quantite_posage = IntegerField(
        column_name="x_qte_posage", null=True, constraints=[SQL("DEFAULT 0")]
    )
    nouvelle_quantite_posage = IntegerField(
        column_name="x_nouv_qte_posage", null=True, constraints=[SQL("DEFAULT 0")]
    )
    emplacement = CharField(
        column_name="x_emplacement", max_length=20,
        null=True, constraints=[SQL("DEFAULT ''")]
    )
    nouvel_emplacement = CharField(
        column_name="x_nouv_emplacement", max_length=20,
        null=True, constraints=[SQL("DEFAULT ''")]
    )
    classe = CharField(
        column_name="x_classe", max_length=1,
        null=True, constraints=[SQL("DEFAULT ''")]
    )
    dim_x = IntegerField(
        column_name="x_dim_x", null=True, constraints=[SQL("DEFAULT 0")]
    )
    dim_y = IntegerField(
        column_name="x_dim_y", null=True, constraints=[SQL("DEFAULT 0")]
    )
    princ = BooleanField(
        column_name="x_princ", null=True, constraints=[SQL("DEFAULT 0")]
    )
    adr_topo = CharField(
        column_name="x_adr_topo", null=True, constraints=[SQL("DEFAULT ''")]
    )
    serial = CharField(
        column_name="x_serial", max_length=20,
        constraints=[SQL("DEFAULT ''")]
    )
    nb_div = IntegerField(
        column_name="x_nb_div", null=True, constraints=[SQL("DEFAULT 0")]
    )
    service = BooleanField(
        column_name="x_service", null=True, constraints=[SQL("DEFAULT 0")]
    )
    bloque_reappro = BooleanField(
        column_name="x_bloque_reappro", constraints=[SQL("DEFAULT 0")]
    )
    bloque_message = CharField(
        column_name="x_bloque_msg", max_length=100,
        constraints=[SQL("DEFAULT ''")], default=''
    )

    def save(self, force_insert=False, only=None):
        """Enforce control on each information passed"""
        if not self.magasin:
            self.magasin = self.adresse[:3]
        if not self.etat:
            self.etat = "L"
        return super().save(force_insert, only)

    class Meta:
        table_name = "f_adr"
        indexes = (
            (('x_adr',), True),
            (('x_mag',), False)
        )


class Reform(BaseModel):
    pk = AutoField(column_name="x_pk", primary_key=True)
    reference = CharField(
        column_name="x_ref", max_length=35)
    format = CharField(
        column_name="x_format", max_length=10)
    capacity = FloatField(
        column_name='x_capa', constraints=[SQL("DEFAULT 0")], default=0)
    nb_div = IntegerField(
        column_name="x_nb_div", constraints=[SQL("DEFAULT 0")], default=0)
    ordre = IntegerField(
        column_name="x_ordre", constraints=[SQL("DEFAULT 0")], default=0)

    class Meta:
        table_name = "f_reform"
        indexes = (
            (('x_ref', 'x_format', 'x_nb_div'), True),
            (('x_format',), False),
            (('x_ref',), False),
        )


class Compteur(BaseModel):
    pk = AutoField(
        column_name='x_pk', primary_key=True)
    cle = CharField(
        column_name='x_cle', constraints=[SQL("DEFAULT ''")])
    val = IntegerField(
        column_name='x_val', constraints=[SQL("DEFAULT 0")])

    def next_value(self):
        return 0

    class Meta:
        table_name = 'f_compteur'
        indexes = (
            (('x_cle',), True)
        )


class MagasinService(BaseModel):
    pk = AutoField(
        column_name='x_pk', primary_key=True)
    mag = CharField(
        column_name='x_mag', max_length=3, null=True,
        constraints=[SQL("DEFAULT ''")])
    dest = CharField(
        column_name='x_dest', max_length=30, null=True,
        constraints=[SQL("DEFAULT ''")])

    class Meta:
        table_name = 'f_mag_dest'
        indexes = (
            (('x_mag', 'x_dest'), True),
        )


class MagasinGroupe(BaseModel):
    pk = AutoField(
        column_name='x_pk', primary_key=True)
    code = CharField(
        column_name='x_code', null=True, max_length=3)
    nom = CharField(
        column_name='x_nom', null=True, max_length=35)

    def save(self, force_insert=False, only=None):
        if not self.code:
            raise ValueError('Code is required')
        if not self.nom:
            raise ValueError('Nom is required')
        if len(self.code) > 3:
            raise ValueError('Code must be exactly 3 characters long')
        if len(self.nom) > 35:
            raise ValueError('Nom must be at most 35 characters long')
        return super().save(force_insert, only)

    class Meta:
        table_name = 'f_mag_groupe'
        indexes = (
            (('x_code',), True),
        )


class Zone(BaseModel):
    pk = AutoField(
        column_name='x_pk', primary_key=True)
    zone = CharField(
        column_name='x_zone', max_length=20, null=True,
        constraints=[SQL("DEFAULT ''")])
    appro = IntegerField(
        column_name='x_appro', constraints=[SQL("DEFAULT 0")])

    class Meta:
        table_name = 'f_zone'
        indexes = (
            (('x_zone'), True),
        )


class ZoneMag(BaseModel):
    pk = AutoField(
        column_name='x_pk', primary_key=True)
    zone = CharField(
        column_name='x_zone', max_length=20, null=True,
        constraints=[SQL("DEFAULT ''")])
    mag = CharField(
        column_name='x_mag', max_length=3, null=True,
        constraints=[SQL("DEFAULT ''")])

    class Meta:
        table_name = 'f_zonemag'
        indexes = (
            (('x_zone', 'x_mag'), True),
        )


class EquipmentUnitStock(BaseModel):
    pk = AutoField(column_name='x_pk', primary_key=True, index=True)
    equipment_pk = IntegerField(column_name='x_equipment_pk', null=True, default=None, index=True)
    total_line = IntegerField(column_name='x_total_line', constraints=[SQL("DEFAULT 0")], default=0)
    total_colonne = IntegerField(column_name='x_total_colonne', constraints=[SQL("DEFAULT 0")], default=0)
    order = IntegerField(column_name='x_order', constraints=[SQL("DEFAULT 0")], default=0)

    class Meta:
        table_name = 'f_equipment_unitstock'


class EquipmentLines(BaseModel):
    pk = AutoField(column_name='x_pk', primary_key=True, index=True)
    unit_stock_pk = IntegerField(column_name='x_unit_stock_pk', null=True, default=None, index=True)
    start_line = IntegerField(column_name='x_start_line', constraints=[SQL("DEFAULT 0")], default=0)
    end_line = IntegerField(column_name='x_end_line', constraints=[SQL("DEFAULT 0")], default=0)

    class Meta:
        table_name = 'f_equipment_lines'


class EquipmentColumns(BaseModel):
    pk = AutoField(column_name='x_pk', primary_key=True, index=True)
    line_pk = IntegerField(column_name='x_line_pk', null=True, default=None, index=True)
    start_column = IntegerField(column_name='x_start_column', constraints=[SQL("DEFAULT 0")], default=0)
    end_Column = IntegerField(column_name='x_end_Column', constraints=[SQL("DEFAULT 0")], default=0)
    container_type = CharField(column_name='x_container_type', max_length=20, constraints=[SQL("DEFAULT ''")])

    class Meta:
        table_name = 'f_equipment_columns'
